backport concurrent
timeoutSeconds polish in conversation management system
This commit is contained in:
@@ -6,7 +6,6 @@
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/resources"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/spring-binding"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/edu.oswego.cs/concurrent/concurrent-1.3.4.jar" sourcepath="IVY_CACHE/edu.oswego.cs/concurrent/concurrent-sources-1.3.4.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/javax.el/el-api/el-api-1.0.jar" sourcepath="IVY_CACHE/javax.el/el-api/el-api-sources-1.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/javax.persistence/persistence-api/persistence-api-1.0.0.jar" sourcepath="IVY_CACHE/javax.persistence/persistence-api/persistence-api-sources-1.0.0.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/javax.portlet/portlet-api/portlet-api-1.0.jar" sourcepath="IVY_CACHE/javax.portlet/portlet-api/portlet-api-sources-1.0.jar"/>
|
||||
@@ -39,5 +38,6 @@
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.springframework/spring-webmvc/spring-webmvc-2.5.2.jar" sourcepath="IVY_CACHE/org.springframework/spring-webmvc/spring-webmvc-sources-2.5.2.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.springframework/spring-webmvc-portlet/spring-webmvc-portlet-2.5.2.jar" sourcepath="IVY_CACHE/org.springframework/spring-webmvc-portlet/spring-webmvc-portlet-sources-2.5.2.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/org.springframework.security/spring-security-core/spring-security-core-2.0.0.m2.jar" sourcepath="IVY_CACHE/org.springframework.security/spring-security-core/spring-security-core-sources-2.0.0.m2.jar"/>
|
||||
<classpathentry kind="var" path="IVY_CACHE/edu.emory.mathcs/backport-util-concurrent/backport-util-concurrent-3.0.0.jar"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
<dependency org="org.springframework" name="spring-tx" rev="2.5.2" conf="compile->default" />
|
||||
<dependency org="org.springframework.security" name="spring-security-core" rev="2.0.0.m2" conf="compile->default" />
|
||||
<dependency org="javax.persistence" name="persistence-api" rev="1.0.0" conf="compile->default" />
|
||||
<dependency org="edu.oswego.cs" name="concurrent" rev="1.3.4" conf="compile->default" />
|
||||
<dependency org="edu.emory.mathcs" name="backport-util-concurrent" rev="3.0.0" conf="compile->default" />
|
||||
|
||||
<!-- test time only dependencies -->
|
||||
<dependency org="org.hsqldb" name="hsqldb" rev="1.8.0.9" conf="test->default" />
|
||||
|
||||
@@ -57,8 +57,9 @@ public interface Conversation {
|
||||
|
||||
/**
|
||||
* Lock this conversation. May block until the lock is available, if someone else has acquired the lock.
|
||||
* @throws ConversationLockException if the lock could not be acquired
|
||||
*/
|
||||
public void lock();
|
||||
public void lock() throws ConversationLockException;
|
||||
|
||||
/**
|
||||
* Returns the conversation attribute with the specified name. You need to aquire the lock on this conversation
|
||||
|
||||
@@ -15,14 +15,12 @@
|
||||
*/
|
||||
package org.springframework.webflow.conversation;
|
||||
|
||||
import org.springframework.webflow.core.FlowException;
|
||||
|
||||
/**
|
||||
* The root of the conversation service exception hierarchy.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public class ConversationException extends FlowException {
|
||||
public abstract class ConversationException extends RuntimeException {
|
||||
|
||||
/**
|
||||
* Creates a conversation service exception.
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package org.springframework.webflow.conversation;
|
||||
|
||||
|
||||
/**
|
||||
* An exception occurred within the conversation locking system.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public abstract class ConversationLockException extends ConversationException {
|
||||
|
||||
/**
|
||||
* Creates a new lock exception.
|
||||
* @param msg the <code>Exception</code> message
|
||||
*/
|
||||
public ConversationLockException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new lock exception.
|
||||
* @param msg the <code>Exception</code> message
|
||||
* @param cause the root cause of this <code>Exception</code>
|
||||
*/
|
||||
public ConversationLockException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
package org.springframework.webflow.conversation.impl;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -44,7 +41,7 @@ class ContainedConversation implements Conversation, Serializable {
|
||||
|
||||
private ConversationId id;
|
||||
|
||||
private transient ConversationLock lock;
|
||||
private ConversationLock lock;
|
||||
|
||||
private Map attributes;
|
||||
|
||||
@@ -52,11 +49,12 @@ class ContainedConversation implements Conversation, Serializable {
|
||||
* Create a new contained conversation.
|
||||
* @param container the container containing the conversation
|
||||
* @param id the unique id assigned to the conversation
|
||||
* @param lock the conversation lock
|
||||
*/
|
||||
public ContainedConversation(ConversationContainer container, ConversationId id) {
|
||||
public ContainedConversation(ConversationContainer container, ConversationId id, ConversationLock lock) {
|
||||
this.container = container;
|
||||
this.id = id;
|
||||
this.lock = ConversationLockFactory.createLock();
|
||||
this.lock = lock;
|
||||
this.attributes = new HashMap();
|
||||
}
|
||||
|
||||
@@ -129,14 +127,4 @@ class ContainedConversation implements Conversation, Serializable {
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
// custom serialization
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException {
|
||||
out.defaultWriteObject();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
lock = ConversationLockFactory.createLock();
|
||||
}
|
||||
}
|
||||
@@ -82,11 +82,13 @@ class ConversationContainer implements Serializable {
|
||||
|
||||
/**
|
||||
* Create a new conversation based on given parameters and add it to the container.
|
||||
* @param parameters descriptive parameters
|
||||
* @param parameters descriptive conversation parameters
|
||||
* @param lockFactory the lock factory to use to create the conversation lock
|
||||
* @return the created conversation
|
||||
*/
|
||||
public synchronized Conversation createConversation(ConversationParameters parameters) {
|
||||
ContainedConversation conversation = new ContainedConversation(this, nextId());
|
||||
public synchronized Conversation createConversation(ConversationParameters parameters,
|
||||
ConversationLockFactory lockFactory) {
|
||||
ContainedConversation conversation = new ContainedConversation(this, nextId(), lockFactory.createLock());
|
||||
conversations.add(conversation);
|
||||
if (maxExceeded()) {
|
||||
// end oldest conversation
|
||||
|
||||
@@ -15,17 +15,22 @@
|
||||
*/
|
||||
package org.springframework.webflow.conversation.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.webflow.conversation.ConversationLockException;
|
||||
|
||||
/**
|
||||
* A normalized interface for conversation locks, used to obtain exclusive access to a conversation.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
public interface ConversationLock {
|
||||
public interface ConversationLock extends Serializable {
|
||||
|
||||
/**
|
||||
* Acquire the conversation lock.
|
||||
* @throws ConversationLockException if an exception is thrown attempting to acquire this lock
|
||||
*/
|
||||
public void lock();
|
||||
public void lock() throws ConversationLockException;
|
||||
|
||||
/**
|
||||
* Release the conversation lock.
|
||||
|
||||
@@ -25,34 +25,52 @@ import org.springframework.core.JdkVersion;
|
||||
* @author Keith Donald
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
public class ConversationLockFactory {
|
||||
class ConversationLockFactory {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(ConversationLockFactory.class);
|
||||
|
||||
private static boolean utilConcurrentPresent;
|
||||
private static boolean backportConcurrentPresent;
|
||||
|
||||
static {
|
||||
try {
|
||||
Class.forName("EDU.oswego.cs.dl.util.concurrent.ReentrantLock");
|
||||
utilConcurrentPresent = true;
|
||||
Class.forName("edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock");
|
||||
backportConcurrentPresent = true;
|
||||
} catch (ClassNotFoundException ex) {
|
||||
utilConcurrentPresent = false;
|
||||
backportConcurrentPresent = false;
|
||||
}
|
||||
}
|
||||
|
||||
private int timeoutSeconds = 30;
|
||||
|
||||
/**
|
||||
* When running on Java 1.5+, returns a jdk5 concurrent lock. When running on older JDKs with the 'util.concurrent'
|
||||
* package available, returns a util concurrent lock. In all other cases a "no-op" lock is returned.
|
||||
* Returns the period of time that can elapse before a lock attempt times out for locks created by this factory.
|
||||
*/
|
||||
public static ConversationLock createLock() {
|
||||
public int getTimeoutSeconds() {
|
||||
return timeoutSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the period of time that can elapse before a lock attempt times out for locks created by this factory.
|
||||
* @param timeoutSeconds the timeout period in seconds
|
||||
*/
|
||||
public void setTimeoutSeconds(int timeoutSeconds) {
|
||||
this.timeoutSeconds = timeoutSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* When running on Java 1.5+, returns a jdk5 concurrent lock. When running on older JDKs with the
|
||||
* 'backport-util-concurrent' package available, returns a backport concurrent lock. In all other cases a "no-op"
|
||||
* lock is returned.
|
||||
*/
|
||||
public ConversationLock createLock() {
|
||||
if (JdkVersion.getMajorJavaVersion() >= JdkVersion.JAVA_15) {
|
||||
return new JdkConcurrentConversationLock();
|
||||
} else if (utilConcurrentPresent) {
|
||||
return new UtilConcurrentConversationLock();
|
||||
return new JdkConcurrentConversationLock(timeoutSeconds);
|
||||
} else if (backportConcurrentPresent) {
|
||||
return new JdkBackportConcurrentConversationLock(timeoutSeconds);
|
||||
} else {
|
||||
logger.warn("Unable to enable conversation locking. Switch to Java 5 or above, "
|
||||
+ "or put the 'util.concurrent' package on the classpath "
|
||||
+ "to enable locking in your environment.");
|
||||
+ "or put the 'backport-util-concurrent' package on the classpath "
|
||||
+ "to enable locking in your Java 1.4 environment.");
|
||||
return NoOpConversationLock.INSTANCE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.webflow.conversation.impl;
|
||||
|
||||
import org.springframework.webflow.conversation.ConversationLockException;
|
||||
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.locks.Lock;
|
||||
import edu.emory.mathcs.backport.java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* A conversation lock that relies on backport-concurrent. For use on JDK 1.4
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
class JdkBackportConcurrentConversationLock implements ConversationLock {
|
||||
|
||||
private Lock lock = new ReentrantLock();
|
||||
|
||||
private int timeoutSeconds;
|
||||
|
||||
public JdkBackportConcurrentConversationLock(int timeoutSeconds) {
|
||||
this.timeoutSeconds = timeoutSeconds;
|
||||
}
|
||||
|
||||
public void lock() throws ConversationLockException {
|
||||
try {
|
||||
boolean acquired = lock.tryLock(timeoutSeconds, TimeUnit.SECONDS);
|
||||
if (!acquired) {
|
||||
throw new LockTimeoutException(timeoutSeconds);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new LockInterruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the lock.
|
||||
*/
|
||||
public void unlock() {
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
@@ -15,38 +15,36 @@
|
||||
*/
|
||||
package org.springframework.webflow.conversation.impl;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.springframework.webflow.conversation.ConversationLockException;
|
||||
|
||||
/**
|
||||
* A conversation lock that relies on a {@link ReentrantLock} within Java 5's <code>util.concurrent.locks</code>
|
||||
* package.
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
class JdkConcurrentConversationLock implements ConversationLock, Serializable {
|
||||
class JdkConcurrentConversationLock implements ConversationLock {
|
||||
|
||||
/**
|
||||
* The lock.
|
||||
*/
|
||||
private Lock lock = new ReentrantLock();
|
||||
|
||||
private int timeoutSeconds = 30;
|
||||
private int timeoutSeconds;
|
||||
|
||||
public void setTimeoutSeconds(int timeoutSeconds) {
|
||||
public JdkConcurrentConversationLock(int timeoutSeconds) {
|
||||
this.timeoutSeconds = timeoutSeconds;
|
||||
}
|
||||
|
||||
public void lock() {
|
||||
public void lock() throws ConversationLockException {
|
||||
try {
|
||||
boolean acquired = lock.tryLock(timeoutSeconds, TimeUnit.SECONDS);
|
||||
if (!acquired) {
|
||||
throw new LockException("Unable to acquire conversation lock after " + timeoutSeconds + " seconds");
|
||||
throw new LockTimeoutException(timeoutSeconds);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new IllegalStateException("Unable to acquire conversation lock - thread interrupted", e);
|
||||
throw new LockInterruptedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package org.springframework.webflow.conversation.impl;
|
||||
|
||||
import org.springframework.webflow.conversation.ConversationException;
|
||||
|
||||
public class LockException extends ConversationException {
|
||||
public LockException(String message) {
|
||||
super(message);
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
package org.springframework.webflow.conversation.impl;
|
||||
|
||||
import java.io.ObjectStreamException;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* A singleton lock that doesn't do anything. For use when conversations don't require or choose not to implement
|
||||
@@ -24,7 +23,7 @@ import java.io.Serializable;
|
||||
*
|
||||
* @author Keith Donald
|
||||
*/
|
||||
class NoOpConversationLock implements ConversationLock, Serializable {
|
||||
class NoOpConversationLock implements ConversationLock {
|
||||
|
||||
/**
|
||||
* The singleton instance.
|
||||
|
||||
@@ -53,18 +53,9 @@ public class SessionBindingConversationManager implements ConversationManager {
|
||||
private int maxConversations = 5;
|
||||
|
||||
/**
|
||||
* Returns the maximum number of allowed concurrent conversations. The default is 5.
|
||||
* The factory for creating conversation lock objects.
|
||||
*/
|
||||
public int getMaxConversations() {
|
||||
return maxConversations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of allowed concurrent conversations. Set to -1 for no limit. The default is 5.
|
||||
*/
|
||||
public void setMaxConversations(int maxConversations) {
|
||||
this.maxConversations = maxConversations;
|
||||
}
|
||||
private ConversationLockFactory conversationLockFactory = new ConversationLockFactory();
|
||||
|
||||
/**
|
||||
* Returns the key this conversation manager uses to store conversation data in the session.
|
||||
@@ -84,8 +75,41 @@ public class SessionBindingConversationManager implements ConversationManager {
|
||||
this.sessionKey = sessionKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the maximum number of allowed concurrent conversations. The default is 5.
|
||||
*/
|
||||
public int getMaxConversations() {
|
||||
return maxConversations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the maximum number of allowed concurrent conversations. Set to -1 for no limit. The default is 5.
|
||||
*/
|
||||
public void setMaxConversations(int maxConversations) {
|
||||
this.maxConversations = maxConversations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time period that can elapse before a timeout occurs on an attempt to acquire a conversation lock. The
|
||||
* default is 30 seconds.
|
||||
*/
|
||||
public int getLockTimeoutSeconds() {
|
||||
return conversationLockFactory.getTimeoutSeconds();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the time period that can elapse before a timeout occurs on an attempt to acquire a conversation lock. The
|
||||
* default is 30 seconds.
|
||||
* @param timeoutSeconds the timeout period in seconds
|
||||
*/
|
||||
public void setLockTimeoutSeconds(int timeoutSeconds) {
|
||||
conversationLockFactory.setTimeoutSeconds(timeoutSeconds);
|
||||
}
|
||||
|
||||
// implementing conversation manager
|
||||
|
||||
public Conversation beginConversation(ConversationParameters conversationParameters) throws ConversationException {
|
||||
return getConversationContainer().createConversation(conversationParameters);
|
||||
return getConversationContainer().createConversation(conversationParameters, conversationLockFactory);
|
||||
}
|
||||
|
||||
public Conversation getConversation(ConversationId id) throws ConversationException {
|
||||
@@ -96,7 +120,7 @@ public class SessionBindingConversationManager implements ConversationManager {
|
||||
try {
|
||||
return new SimpleConversationId(Integer.valueOf(encodedId));
|
||||
} catch (NumberFormatException e) {
|
||||
throw new ConversationException("Unable to parse string-encoded conversationId + '" + encodedId + "'", e);
|
||||
throw new BadlyFormattedConversationIdException(encodedId, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,8 +21,7 @@ import org.springframework.webflow.conversation.ConversationId;
|
||||
import org.springframework.webflow.conversation.ConversationManager;
|
||||
|
||||
/**
|
||||
* An id that uniquely identifies a conversation managed by a {@link ConversationManager}. This key consists of a
|
||||
* unique string that is typically a GUID.
|
||||
* An id that uniquely identifies a conversation managed by a {@link ConversationManager}.
|
||||
*
|
||||
* @author Ben Hale
|
||||
*/
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2004-2007 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.webflow.conversation.impl;
|
||||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
|
||||
import EDU.oswego.cs.dl.util.concurrent.ReentrantLock;
|
||||
|
||||
/**
|
||||
* A conversation lock that relies on a {@link ReentrantLock} within Doug Lea's <a
|
||||
* href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html">util.concurrent</a> package.
|
||||
* For use on JDK 1.3 and 1.4.
|
||||
*
|
||||
* @author Keith Donald
|
||||
* @author Rob Harrop
|
||||
*/
|
||||
class UtilConcurrentConversationLock implements ConversationLock {
|
||||
|
||||
/**
|
||||
* The {@link ReentrantLock} instance.
|
||||
*/
|
||||
private final ReentrantLock lock = new ReentrantLock();
|
||||
|
||||
private int timeoutMills;
|
||||
|
||||
public void setTimeoutSeconds(int timeoutSeconds) {
|
||||
this.timeoutMills = timeoutSeconds * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* Acquires the lock.
|
||||
* @throws SystemInterruptedException if the lock cannot be acquired due to interruption
|
||||
*/
|
||||
public void lock() {
|
||||
try {
|
||||
boolean acquired = lock.attempt(timeoutMills);
|
||||
if (!acquired) {
|
||||
throw new LockException("Unable to acquire conversation lock after " + timeoutMills / 1000 + " seconds");
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new SystemInterruptedException("Unable to acquire conversation lock - thread interrupted", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the lock.
|
||||
*/
|
||||
public void unlock() {
|
||||
lock.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>Exception</code> indicating that some {@link Thread} was {@link Thread#interrupt() interrupted} during
|
||||
* processing and as such processing was halted.
|
||||
* <p>
|
||||
* Only used to wrap the checked {@link InterruptedException java.lang.InterruptedException}.
|
||||
*/
|
||||
public static class SystemInterruptedException extends NestedRuntimeException {
|
||||
|
||||
/**
|
||||
* Creates a new <code>SystemInterruptedException</code>.
|
||||
* @param msg the <code>Exception</code> message
|
||||
*/
|
||||
public SystemInterruptedException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new <code>SystemInterruptedException</code>.
|
||||
* @param msg the <code>Exception</code> message
|
||||
* @param cause the root cause of this <code>Exception</code>
|
||||
*/
|
||||
public SystemInterruptedException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user