You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by tc...@apache.org on 2005/07/04 11:01:48 UTC

svn commit: r209036 - in /jakarta/commons/sandbox/javaflow/trunk: ./ lib/ src/java/org/apache/commons/javaflow/ src/java/org/apache/commons/javaflow/bytecode/ src/java/org/apache/commons/javaflow/bytecode/asm/ src/test/org/apache/commons/javaflow/testc...

Author: tcurdt
Date: Mon Jul  4 02:01:47 2005
New Revision: 209036

URL: http://svn.apache.org/viewcvs?rev=209036&view=rev
Log:
first steps of an ASM based implementation

Added:
    jakarta/commons/sandbox/javaflow/trunk/lib/asm-20050703.234510.jar   (with props)
    jakarta/commons/sandbox/javaflow/trunk/lib/asm-analysis-20050703.234510.jar   (with props)
    jakarta/commons/sandbox/javaflow/trunk/lib/asm-attrs-20050703.234510.jar   (with props)
    jakarta/commons/sandbox/javaflow/trunk/lib/asm-common-20050703.234510.jar   (with props)
    jakarta/commons/sandbox/javaflow/trunk/lib/asm-tree-20050703.234510.jar   (with props)
    jakarta/commons/sandbox/javaflow/trunk/lib/asm-util-20050703.234510.jar   (with props)
    jakarta/commons/sandbox/javaflow/trunk/lib/asm-xml-20050703.234510.jar   (with props)
    jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/BytecodeClassLoader.java
    jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Test.java
Modified:
    jakarta/commons/sandbox/javaflow/trunk/project.properties
    jakarta/commons/sandbox/javaflow/trunk/project.xml
    jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java
    jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/Stack.java
    jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/asm/AsmClassTransformer.java

Added: jakarta/commons/sandbox/javaflow/trunk/lib/asm-20050703.234510.jar
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/lib/asm-20050703.234510.jar?rev=209036&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jakarta/commons/sandbox/javaflow/trunk/lib/asm-20050703.234510.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jakarta/commons/sandbox/javaflow/trunk/lib/asm-analysis-20050703.234510.jar
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/lib/asm-analysis-20050703.234510.jar?rev=209036&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jakarta/commons/sandbox/javaflow/trunk/lib/asm-analysis-20050703.234510.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jakarta/commons/sandbox/javaflow/trunk/lib/asm-attrs-20050703.234510.jar
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/lib/asm-attrs-20050703.234510.jar?rev=209036&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jakarta/commons/sandbox/javaflow/trunk/lib/asm-attrs-20050703.234510.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jakarta/commons/sandbox/javaflow/trunk/lib/asm-common-20050703.234510.jar
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/lib/asm-common-20050703.234510.jar?rev=209036&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jakarta/commons/sandbox/javaflow/trunk/lib/asm-common-20050703.234510.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jakarta/commons/sandbox/javaflow/trunk/lib/asm-tree-20050703.234510.jar
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/lib/asm-tree-20050703.234510.jar?rev=209036&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jakarta/commons/sandbox/javaflow/trunk/lib/asm-tree-20050703.234510.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jakarta/commons/sandbox/javaflow/trunk/lib/asm-util-20050703.234510.jar
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/lib/asm-util-20050703.234510.jar?rev=209036&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jakarta/commons/sandbox/javaflow/trunk/lib/asm-util-20050703.234510.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: jakarta/commons/sandbox/javaflow/trunk/lib/asm-xml-20050703.234510.jar
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/lib/asm-xml-20050703.234510.jar?rev=209036&view=auto
==============================================================================
Binary file - no diff available.

Propchange: jakarta/commons/sandbox/javaflow/trunk/lib/asm-xml-20050703.234510.jar
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: jakarta/commons/sandbox/javaflow/trunk/project.properties
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/project.properties?rev=209036&r1=209035&r2=209036&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/project.properties (original)
+++ jakarta/commons/sandbox/javaflow/trunk/project.properties Mon Jul  4 02:01:47 2005
@@ -34,8 +34,12 @@
 # ------------------------------------------------------------------------
 # Jars set explicity by path.
 # ------------------------------------------------------------------------
-maven.jar.commons-jci = ${basedir}/lib/commons-jci-r159148.jar
-maven.jar.bcel = ${basedir}/lib/jakarta-bcel-20040329.jar
+maven.jar.commons-jci = lib/commons-jci-r159148.jar
+maven.jar.bcel = lib/jakarta-bcel-20040329.jar
 maven.jar.commons-io = lib/commons-io-20050621.133116.jar
-maven.jar.asm = lib/asm-2.0.jar
-maven.jar.asm-tree = lib/asm-tree-2.0.jar
+maven.jar.asm = lib/asm-20050703.234510.jar
+maven.jar.asm-tree = lib/asm-tree-20050703.234510.jar
+maven.jar.asm-analysis = lib/asm-analysis-20050703.234510.jar
+maven.jar.asm-common = lib/asm-common-20050703.234510.jar
+maven.jar.asm-util = lib/asm-util-20050703.234510.jar
+

Modified: jakarta/commons/sandbox/javaflow/trunk/project.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/project.xml?rev=209036&r1=209035&r2=209036&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/project.xml (original)
+++ jakarta/commons/sandbox/javaflow/trunk/project.xml Mon Jul  4 02:01:47 2005
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project>
   <!--
-  <extend>../commons-build/sandbox-project.xml</extend>
   -->
+  <extend>../commons-build/sandbox-project.xml</extend>
   <pomVersion>1</pomVersion>
   <artifactId>commons-javaflow</artifactId>
   <name>Commons Javaflow</name>
@@ -88,13 +88,36 @@
     <dependency>
       <groupId>asm</groupId>
       <artifactId>asm</artifactId>
-      <version>2.0</version>
+      <jar>${basedir}/lib/asm-20050703.234510.jar</jar>
+      <version>SNAPSHOT</version>
       <type>jar</type>
     </dependency>
     <dependency>
       <groupId>asm</groupId>
       <artifactId>asm-tree</artifactId>
-      <version>2.0</version>
+      <jar>${basedir}/lib/asm-tree-20050703.234510.jar</jar>
+      <version>SNAPSHOT</version>
+      <type>jar</type>
+    </dependency>
+    <dependency>
+      <groupId>asm</groupId>
+      <artifactId>asm-analysis</artifactId>
+      <jar>${basedir}/lib/asm-analysis-20050703.234510.jar</jar>
+      <version>SNAPSHOT</version>
+      <type>jar</type>
+    </dependency>
+    <dependency>
+      <groupId>asm</groupId>
+      <artifactId>asm-common</artifactId>
+      <jar>${basedir}/lib/asm-common-20050703.234510.jar</jar>
+      <version>SNAPSHOT</version>
+      <type>jar</type>
+    </dependency>
+    <dependency>
+      <groupId>asm</groupId>
+      <artifactId>asm-util</artifactId>
+      <jar>${basedir}/lib/asm-util-20050703.234510.jar</jar>
+      <version>SNAPSHOT</version>
       <type>jar</type>
     </dependency>
   </dependencies>

Modified: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java?rev=209036&r1=209035&r2=209036&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/Continuation.java Mon Jul  4 02:01:47 2005
@@ -141,7 +141,9 @@
             log.error("could not execute " + continuation, e);       
         } finally {
             if (continuation.capturing) {
-                continuation.stack.popReference();
+                if (continuation.stack.hasReference()) {
+                    continuation.stack.popReference();
+                }
             }
 
             continuation.context = null;
@@ -160,9 +162,10 @@
 
         final Continuation continuation = Continuation.currentContinuation();
 
-        if (continuation == null)
+        if (continuation == null) {
             throw new IllegalStateException("no continuation is running");
-
+        }
+        
         continuation.capturing = !continuation.restoring;
         
         continuation.restoring = false;

Added: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/BytecodeClassLoader.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/BytecodeClassLoader.java?rev=209036&view=auto
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/BytecodeClassLoader.java (added)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/BytecodeClassLoader.java Mon Jul  4 02:01:47 2005
@@ -0,0 +1,39 @@
+package org.apache.commons.javaflow.bytecode;
+
+import org.objectweb.asm.ClassAdapter;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.commons.EmptyVisitor;
+
+
+public final class BytecodeClassLoader extends ClassLoader {
+
+    class NameClassAdapter extends ClassAdapter {
+        private String className;
+
+        public NameClassAdapter() {
+            super(new EmptyVisitor());
+        }
+        
+        public void visit( int version, int access, String name, String signature, String superName, String[] interfaces ) {
+            className = name;
+        }
+        
+        public String getName() {
+            return className;
+        }
+    }
+    
+    public Class loadClass( final byte[] bytecode ) {
+        final NameClassAdapter nameClassAdapter = new NameClassAdapter();
+        
+        new ClassReader(bytecode).accept(nameClassAdapter, false);
+        
+        final String name = nameClassAdapter.getName().replace('/', '.');
+        
+        System.out.println("loading class " + name);
+        
+        final Class clazz = defineClass(name, bytecode, 0, bytecode.length);
+        
+        return clazz;
+    }
+}

Modified: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/Stack.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/Stack.java?rev=209036&r1=209035&r2=209036&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/Stack.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/Stack.java Mon Jul  4 02:01:47 2005
@@ -71,6 +71,10 @@
         rTop = parent.rTop;
     }
 
+    public boolean hasDouble() {
+        return dTop > 0;
+    }
+    
     public double popDouble() {
         if (dTop==0) {
             throw new EmptyStackException("pop double");
@@ -81,6 +85,10 @@
         return d;
     }
 
+    public boolean hasFloat() {
+        return fTop > 0;
+    }
+
     public float popFloat() {
         if (fTop==0) {
             throw new EmptyStackException("pop float");
@@ -91,6 +99,10 @@
         return f;
     }
 
+    public boolean hasInt() {
+        return iTop > 0;
+    }
+
     public int popInt() {
         if (iTop==0) {
             throw new EmptyStackException("pop int");
@@ -101,6 +113,10 @@
         return i;
     }
 
+    public boolean hasLong() {
+        return lTop > 0;
+    }
+
     public long popLong() {
         if (lTop==0) {
             throw new EmptyStackException("pop long");
@@ -111,6 +127,10 @@
         return l;
     }
 
+    public boolean hasObject() {
+        return oTop > 0;
+    }
+
     public Object popObject() {
         if (oTop==0) {
             throw new EmptyStackException("pop object");
@@ -124,6 +144,10 @@
         log.debug("pop object "+ clazz + "/" + clazzLoader + " [" + o + "] " + toString());
         
         return o;
+    }
+
+    public boolean hasReference() {
+        return rTop > 0;
     }
 
     public Object popReference() {

Modified: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/asm/AsmClassTransformer.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/asm/AsmClassTransformer.java?rev=209036&r1=209035&r2=209036&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/asm/AsmClassTransformer.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/asm/AsmClassTransformer.java Mon Jul  4 02:01:47 2005
@@ -15,35 +15,230 @@
  */
 package org.apache.commons.javaflow.bytecode.asm;
 
+import java.util.ArrayList;
+import java.util.Collection;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.javaflow.bytecode.BytecodeClassLoader;
 import org.apache.commons.javaflow.bytecode.ClassTransformer;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
+import org.objectweb.asm.ClassAdapter;
 import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
 import org.objectweb.asm.ClassWriter;
-import org.objectweb.asm.tree.ClassNode;
-
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodAdapter;
+import org.objectweb.asm.MethodVisitor;
+import org.objectweb.asm.Opcodes;
+import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.analysis.Analyzer;
+import org.objectweb.asm.tree.analysis.BasicVerifier;
+import org.objectweb.asm.tree.analysis.Frame;
 
 /**
  * @author tcurdt
- *  
  */
 public final class AsmClassTransformer implements ClassTransformer {
 
     private final static Log log = LogFactory.getLog(AsmClassTransformer.class);
 
-    public byte[] transform(final byte[] original) {
+    class MyClassAdapter extends ClassAdapter {
 
-        final ClassReader cr = new ClassReader(original);
-        final ClassNode cn = new ClassNode();
-        
-        cr.accept(cn, true);
+        private String className;
+
+        public MyClassAdapter(ClassVisitor cv) {
+            super(cv);
+        }
+
+
+        public void visit( int version, int access, String name, String signature, String superName, String[] interfaces ) {
+            cv.visit(version, access, name, signature, superName, interfaces);
+            className = name;
+        }
+
+
+        public MethodVisitor visitMethod( int access, String name, String desc, String signature, String[] exceptions ) {
+            // return a MethodNode so that the visited method will be stored as
+            // a tree
+            // (instead of being transformed on the fly and passed directly to
+            // the next visitor in the chain)
+ 
+            if (inScope(className, name) && "main".equals(name)) {
+            return new MethodNode(access, name, desc, signature, exceptions) {
+
+                private Collection labels = new ArrayList();
+                
+                public void visitMethodInsn( int opcode, String owner, String name, String desc ) {
+
+                    if (needsFrameGuard(opcode, owner, name, desc) && inScope(owner, name)) {
+                        System.out.println("creating label for " + owner + "." + name);
+
+                        final Label label = new Label();
+                        super.visitLabel(label);
+                        labels.add(label);
+                    }
+
+                    super.visitMethodInsn(opcode, owner, name, desc);
+                }
+
+                public void visitEnd() {
+                    // once the MethodNode is complete, compute the frames
+                    final Frame[] frames;
+                    if (instructions.size() > 0) {
+                        Analyzer a = new Analyzer(new BasicVerifier());
+                        try {
+                            a.analyze(className, this);
+                        } catch (Exception ignored) {
+                        }
+                        frames = a.getFrames();
+                    } else {
+                        frames = new Frame[0];
+                    }
+                    System.out.println(labels.size() + " labels for method " + name);
+                    System.out.println(frames.length + " frame states for method " + name);
+                    // now make the next visitor in the chain (i.e. cv) visit
+                    // this method
+                    accept(new ClassAdapter(cv) {
+
+                        public MethodVisitor visitMethod( int access, String name, String desc, String signature, String[] exceptions ) {
+                            // insert an adapter to transform the method based
+                            // on the computed frames
+                            
+                            final Label[] la = new Label[labels.size()];
+                            labels.toArray(la);
+                            
+                            return new MyMethodAdapter(
+                                    cv.visitMethod(access, name, desc, signature, exceptions),
+                                    frames,
+                                    la,
+                                    name
+                                    );
+                        }
+                    });
+                }
+            };
+            } else {
+                return super.visitMethod(access, name, desc, signature, exceptions);
+            }
+       }
+    }
+
+    class MyMethodAdapter extends MethodAdapter {
+
+        private final Frame[] frames;
+        private final Label[] labels;
+        private final String name;
+        private int currentInsn; // position in the *original* code
+
+
+        public MyMethodAdapter(MethodVisitor mv, Frame[] frames, Label[] labels, String name) {
+            super(mv);
+            this.frames = frames;
+            this.name = name;
+            this.labels = labels;
+        }
+
+        public void visitCode() {
+            mv.visitCode();
+
+            mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+            mv.visitLdcInsn("entering " + name);
+            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
+
+            //mv.visitTableSwitchInsn(0, labels.length-1 , null, labels);
+            //mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "", "", "");
+        }
+
+        public void visitInsn( int opcode ) {
+
+            if (opcode == Opcodes.RETURN) {
+                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+                mv.visitLdcInsn("returning from " + name);
+                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
+            }
+            
+            mv.visitInsn(opcode);
+            ++currentInsn;
+        }
+
+
+        public void visitMethodInsn( int opcode, String owner, String name, String desc ) {
+            if (needsFrameGuard(opcode, owner, name, desc) && inScope(owner, name)) {
+
+                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+                mv.visitLdcInsn("before " + name);
+                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
+
+                mv.visitMethodInsn(opcode, owner, name, desc);
+
+                mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
+                mv.visitLdcInsn("after " + name);
+                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
+                
+            } else {
+                mv.visitMethodInsn(opcode, owner, name, desc);
+            }
+            // insert your code here if necessary,
+            // you can use frames[currentInsn] to know frame types at this
+            // point
+            ++currentInsn;
+        }
+    }
+
+    private boolean inScope(String owner, String name) {
+        if (owner.startsWith("org/apache/commons/javaflow")) {
+            return true;
+        }
         
+        return false;        
+    }
+    private boolean needsFrameGuard( int opcode, String owner, String name, String desc ) {
+        if (opcode == Opcodes.INVOKEINTERFACE ||
+            opcode == Opcodes.INVOKESPECIAL ||
+            opcode == Opcodes.INVOKESTATIC ||
+            opcode == Opcodes.INVOKEVIRTUAL ) {
+            return true;
+        }
+        return false;
+    }
+    
+    public byte[] transform( final byte[] original ) {
+        // new ClassReader(original).accept(new TraceClassVisitor(new
+        // ClassWriter(false), new PrintWriter(System.out)), false);
+        final ClassReader cr = new ClassReader(original);
         final ClassWriter cw = new ClassWriter(true, false);
-        cn.accept(cn);
-        
+        final ClassVisitor cv = new MyClassAdapter(cw);
+        cr.accept(cv, false);
         final byte[] transformed = cw.toByteArray();
         
-        return null;
+        //new ClassReader(transformed).accept(new TraceClassVisitor(new ClassWriter(false), new PrintWriter(System.out)), false);
+
+        return transformed;
     }
 
+
+    public static void main( String[] args ) throws Exception {
+        final byte[] original = IOUtils.toByteArray(ClassLoader.getSystemResourceAsStream("org/apache/commons/javaflow/testcode/Test.class"));
+        
+        System.out.println("original=" + original.length);
+        final byte[] transformed = new AsmClassTransformer().transform(original);
+        System.out.println("transformed=" + transformed.length);
+        
+        /*
+        System.out.println("running the original");
+        Class originalClass = new BytecodeClassLoader().loadClass(original);
+        Runnable orignalRunnable = (Runnable) originalClass.newInstance();
+        try {
+            orignalRunnable.run();
+        } catch(IllegalStateException e) {
+        }
+        System.out.println("original finished");
+        */
+        
+        System.out.println("running the transformed");
+        Class transformedClass = new BytecodeClassLoader().loadClass(transformed);
+        Runnable transformedRunnable = (Runnable) transformedClass.newInstance();
+        transformedRunnable.run();
+        System.out.println("transformed finished");
+    }
 }

Added: jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Test.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Test.java?rev=209036&view=auto
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Test.java (added)
+++ jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/testcode/Test.java Mon Jul  4 02:01:47 2005
@@ -0,0 +1,62 @@
+package org.apache.commons.javaflow.testcode;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+import junit.framework.TestCase;
+import org.apache.commons.javaflow.Continuation;
+import org.apache.commons.javaflow.ContinuationContext;
+import org.apache.commons.javaflow.MethodLookup;
+import org.apache.commons.javaflow.utils.ReflectionUtils;
+
+public class Test implements Runnable {
+
+    public final class MapMethodLookup implements MethodLookup {
+
+        private final Map methods;
+
+
+        public MapMethodLookup(Map methods) {
+            super();
+            this.methods = methods;
+        }
+
+
+        public Method getMethod(final String methodName) {
+            final Method method = (Method) methods.get(methodName);
+            if (method == null) {
+                throw new NullPointerException("method " + methodName + " could not be found");
+            }
+            return method;
+        }
+    }
+
+    private ContinuationContext createContinuationContext(final Class clazz) {
+
+        final Map methods = ReflectionUtils.discoverMethods(clazz);
+        TestCase.assertNotNull(methods);
+        TestCase.assertTrue(methods.size() > 0);
+        
+        final MethodLookup lookup = new MapMethodLookup(methods);
+        
+        final ContinuationContext context = new ContinuationContext();
+        context.setMethodLookup(lookup);
+        
+        return context;
+    }
+
+    public void run() {
+        System.out.println("running in " + this.getClass().getClassLoader().hashCode());
+        
+        final ContinuationContext context = createContinuationContext(this.getClass());
+        
+        final Continuation continuation = Continuation.startWith("main", context);
+        
+        System.out.println("finished in " + this.getClass().getClassLoader().hashCode());
+    }
+
+    public void main() {
+        
+        Continuation.suspend();
+
+    }
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org