Ok, here's a start, anyway.
Some notes:
* The simplelog setup wasn't working at all for me for anything less than info, so I added log4j into the project.xml. Works fine now. Not sure if you were having a similar problem? junit is also added to project.xml.
* There are some references to /home/tcurdt in .classpath. I didn't touch them. Does this even belong in svn?
* I added a ContinuationException class that can be thrown to clients using this code instead of stuff like java.lang.reflect.InvocationTargetException that is dependent on the underlying bytecode toolkit.
* Added some serialVersionUID fields to Serializable classes.
* The test case causes an exception to be thrown and tests for it, so be aware of that when you see the stacktrace in the output.
* In the TODO file, you mention something about removing the Continuable and ContinuationCapable marker interfaces. Can you please elaborate on the reasons behind that?
Just starting off small for now - more soon.
phil.
Torsten Curdt wrote:
Any objections to receiving test cases using junit?
Phil, of course not! :)
...actually it was my plan using junit for that.
cheers -- Torsten
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
-- Whirlycott Philip Jacob [EMAIL PROTECTED] http://www.whirlycott.com/phil/
Index: C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/.classpath
===================================================================
--- C:/Documents and Settings/pjacob/My Documents/workspace/javaflow/.classpath
(revision 149125)
+++ C:/Documents and Settings/pjacob/My Documents/workspace/javaflow/.classpath
(working copy)
@@ -8,5 +8,7 @@
<classpathentry kind="var"
path="MAVEN_REPO/commons-logging/jars/commons-logging-api-1.0.4.jar"/>
<classpathentry kind="var"
path="MAVEN_REPO/commons-logging/jars/commons-logging-1.0.4.jar"/>
<classpathentry kind="var" path="MAVEN_REPO/ant/jars/ant-1.5.3-1.jar"/>
+ <classpathentry kind="var"
path="MAVEN_REPO/junit/jars/junit-3.8.1.jar"/>
+ <classpathentry kind="var"
path="MAVEN_REPO/log4j/jars/log4j-1.2.8.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>
Index: C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/project.xml
===================================================================
--- C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/project.xml (revision 149125)
+++ C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/project.xml (working copy)
@@ -68,6 +68,18 @@
<artifactId>ant</artifactId>
<version>1.5.3-1</version>
</dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>3.8.1</version>
+ </dependency>
+
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>1.2.8</version>
+ </dependency>
</dependencies>
</project>
Index: C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/src/test/org/apache/commons/javaflow/ContinuationClassLoaderTestCase.java
===================================================================
--- C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/src/test/org/apache/commons/javaflow/ContinuationClassLoaderTestCase.java
(revision 149125)
+++ C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/src/test/org/apache/commons/javaflow/ContinuationClassLoaderTestCase.java
(working copy)
@@ -18,6 +18,8 @@
import java.lang.reflect.Method;
import java.util.Map;
+import junit.framework.TestCase;
+
import org.apache.commons.javaflow.utils.ReflectionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -27,40 +29,70 @@
* @author tcurdt
*
*/
-public final class ContinuationClassLoaderTestCase {
+public final class ContinuationClassLoaderTestCase extends TestCase {
+ /**
+ * Logger.
+ */
private final static Log log =
LogFactory.getLog(ContinuationClassLoaderTestCase.class);
- private void testCalculator() throws Exception {
+ public void testCalculator() throws Exception {
+ log.debug("Doing testCalculator()");
+
+ final String calculatorTestClass =
"org.apache.commons.javaflow.testcode.Calculator";
+
final ClassLoader cl = new
ContinuationClassLoader(getClass().getClassLoader());
- final Class clazz =
cl.loadClass("org.apache.commons.javaflow.testcode.Calculator");
+ final Class clazz = cl.loadClass(calculatorTestClass);
+ assertNotNull(clazz);
- final Map m = ReflectionUtils.discoverMethods(clazz);
+ //This map contains methods indexed by their names (Strings).
+ final Map methods = ReflectionUtils.discoverMethods(clazz);
+ assertNotNull(methods);
+
+ //We must at least see the methods inherited from java.lang.Object.
+ assertTrue(methods.size() > 0);
+
final Object instance = clazz.newInstance();
+ assertNotNull(instance);
+
+ final ContinuationContext parentContext = new ContinuationContext();
+ parentContext.setMethod((Method)methods.get("main"));
+ parentContext.setInstance(instance);
Continuation c = null;
- ContinuationContext context = null;
+ log.debug("Continuation 1");
+ c = Continuation.continueWith(c, parentContext);
- context = new ContinuationContext();
- context.setMethod((Method)m.get("main"));
- context.setInstance(instance);
+ final ContinuationContext childContext = new ContinuationContext();
+ childContext.setMethod((Method)methods.get("main"));
+ childContext.setInstance(instance);
- log.debug("continuation 1");
- c = Continuation.continueWith(c, context);
-
+ log.debug("Continuation 2");
+ c = Continuation.continueWith(c, childContext);
- context = new ContinuationContext();
- context.setMethod((Method)m.get("main"));
- context.setInstance(instance);
+ //We should see an exception being thrown here since we are trying to
re-use a Continuation.
+ boolean exceptionThrown = false;
+ try {
+ log.debug("Trying to redo a continuation - this should fail.");
+ c = Continuation.continueWith(c, childContext);
+ } catch (final ContinuationException e) {
+ log.debug("Expected exception caught");
+ exceptionThrown = true;
+ }
+
+ assertTrue(exceptionThrown);
- log.debug("continuation 2");
- c = Continuation.continueWith(c, context);
-
}
- public static void main(String[] args) throws Exception {
- ContinuationClassLoaderTestCase t = new
ContinuationClassLoaderTestCase();
+
+ /**
+ * The junit tests are preferred over running this main() method.
+ * @param args
+ * @throws Exception
+ */
+ public static void main(final String[] args) throws Exception {
+ final ContinuationClassLoaderTestCase t = new
ContinuationClassLoaderTestCase();
t.testCalculator();
}
}
Index: C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/src/test/org/apache/commons/javaflow/testcode/Calculator.java
===================================================================
--- C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/src/test/org/apache/commons/javaflow/testcode/Calculator.java
(revision 149125)
+++ C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/src/test/org/apache/commons/javaflow/testcode/Calculator.java
(working copy)
@@ -19,6 +19,8 @@
import org.apache.commons.javaflow.Continuable;
import org.apache.commons.javaflow.Continuation;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* @author tcurdt
@@ -26,13 +28,20 @@
*/
public final class Calculator implements Continuable, Serializable {
+ private static final long serialVersionUID = 134424444444L;
+
+ /**
+ * Logger.
+ */
+ private static final Log log = LogFactory.getLog(Calculator.class);
+
public void main() {
- System.out.println("Calculator1");
+ log.debug("Calculator1");
Continuation.suspend();
- System.out.println("Calculator2");
+ log.debug("Calculator2");
}
}
Index: C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/src/java/org/apache/commons/javaflow/Continuation.java
===================================================================
--- C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/src/java/org/apache/commons/javaflow/Continuation.java
(revision 149125)
+++ C:/Documents and Settings/pjacob/My
Documents/workspace/javaflow/src/java/org/apache/commons/javaflow/Continuation.java
(working copy)
@@ -25,29 +25,34 @@
import org.apache.commons.logging.LogFactory;
/**
- * Continations object to store the current execution. The continuation
- * object can only used once.
- *
- * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels</a>
- * @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt</a>
- * @version CVS $Id: Continuation.java,v 1.1 2005/01/23 03:55:21 tcurdt Exp $
+ * Continations object to store the current execution. The continuation object
+ * can only used once.
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Stephan Michels </a>
+ * @author <a href="mailto:[EMAIL PROTECTED]">Torsten Curdt </a>
+ * @version CVS $Id$
*/
public class Continuation implements Serializable {
+
+ private static final long serialVersionUID = 234599993L;
+ /**
+ * Logger.
+ */
private final static Log log = LogFactory.getLog(Continuation.class);
-
private final Stack stack;
private final static transient Map continuationsMap = new HashMap();
private boolean restoring = false;
+
private boolean capturing = false;
/**
- * Create a new continuation, which continue a previous continuation.
+ * Create a new continuation that continues a previous continuation.
*/
- private Continuation( final Continuation parent ) {
+ private Continuation(final Continuation parent) {
if (parent != null) {
stack = new Stack(parent.stack);
} else {
@@ -56,33 +61,27 @@
}
/**
- * Return the stack, which is used to store the frame information.
- private Stack getStack() {
- return stack;
- }
+ * Return the stack, which is used to store the frame information. private
+ * Stack getStack() { return stack; }
*/
-
// REVISIT
private Object context;
+
public Object getContext() {
return context;
}
-
- public static Continuation continueWith(
- final Continuation parent,
- final ContinuationContext context
- ) {
+ public static Continuation continueWith(final Continuation parent, final
ContinuationContext context) throws ContinuationException {
+
// setup context outside
-
+
final Continuation newContinuation = new Continuation(parent);
-
+
if (parent != null) {
log.debug("resuming continuation " + parent);
newContinuation.restoring = true;
- }
- else {
+ } else {
log.debug("starting new flow");
// create continuable instance
}
@@ -90,18 +89,19 @@
newContinuation.registerThread();
newContinuation.context = context;
-
+
final Object instance = context.getInstance();
final Method method = context.getMethod();
try {
method.invoke(instance, new Object[0]);
- }
- catch(Exception e) {
- log.error("could not execute " + instance + " " + method, e);
- }
- finally {
+
+ } catch (final Exception e) {
+ final String msg = "Did you try to reuse a Continuation? " +
instance + " " + method;
+ log.error(msg, e);
+ throw new ContinuationException(msg);
+ } finally {
if (newContinuation.capturing) {
newContinuation.stack.popReference();
}
@@ -110,41 +110,37 @@
newContinuation.deregisterThread();
}
-
+
return newContinuation;
}
-
+
/**
* Stop the running continuation.
*/
public static void suspend() {
-
- log.debug("suspend()");
+ log.debug("suspend()");
- Continuation continuation = Continuation.currentContinuation();
+ final Continuation continuation = Continuation.currentContinuation();
if (continuation == null)
- throw new IllegalStateException("no continuation is running");
+ throw new IllegalStateException("No continuation is running");
- if (continuation.restoring) {
- continuation.capturing = false;
- } else {
- continuation.capturing = true;
- }
-
+ //If we're restoring, set capturing to true.
+ continuation.setCapturing( (continuation.isRestoring() ? false : true)
);
continuation.restoring = false;
}
/**
- * True, if the continuation restores the previous stack trace to the
- * last invocation of suspend().
+ * True, if the continuation restores the previous stack trace to the last
+ * invocation of suspend().
*/
public boolean isRestoring() {
return restoring;
}
/**
- * True, is the continuation freeze the strack trace, and stops the
continuation.
+ * True, is the continuation freeze the strack trace, and stops the
+ * continuation.
*/
public boolean isCapturing() {
return capturing;
@@ -153,7 +149,7 @@
public Stack getStack() {
return stack;
}
-
+
/**
* Bind the continuation to running thread.
*/
@@ -173,13 +169,19 @@
}
/**
- * Return the continuation, which is associated to the
- * current thread.
+ * Return the continuation, which is associated to the current thread.
*/
public static Continuation currentContinuation() {
synchronized (continuationsMap) {
- Thread t = Thread.currentThread();
- return (Continuation) continuationsMap.get(t);
+ return (Continuation) continuationsMap.get(Thread.currentThread());
}
}
-}
+
+ public void setCapturing(boolean capturing) {
+ this.capturing = capturing;
+ }
+
+ public void setRestoring(boolean restoring) {
+ this.restoring = restoring;
+ }
+}
\ No newline at end of file--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
