You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by ko...@apache.org on 2005/10/19 08:18:46 UTC

svn commit: r326409 - in /jakarta/commons/sandbox/javaflow/trunk/src: java/org/apache/commons/javaflow/bytecode/ test/org/apache/commons/javaflow/

Author: kohsuke
Date: Tue Oct 18 23:18:37 2005
New Revision: 326409

URL: http://svn.apache.org/viewcvs?rev=326409&view=rev
Log:
modified the test harness and fixed some bugs so that all the unit tests will pass

Added:
    jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/TestClassLoader.java
Modified:
    jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/BytecodeClassLoader.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/StackRecorder.java
    jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/AbstractTestCase.java
    jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTestCase.java

Modified: 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=326409&r1=326408&r2=326409&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/BytecodeClassLoader.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/BytecodeClassLoader.java Tue Oct 18 23:18:37 2005
@@ -32,7 +32,7 @@
         
         System.out.println("loading class " + name);
         
-        final Class clazz = defineClass(name, bytecode, 0, bytecode.length);
+        final Class clazz = defineClass(null, 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=326409&r1=326408&r2=326409&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 Tue Oct 18 23:18:37 2005
@@ -181,7 +181,7 @@
         log.debug("push double " + d + " " + getStats());
 
         if (dTop == dstack.length) {
-            double[] hlp = new double[dstack.length*2];
+            double[] hlp = new double[Math.max(8,dstack.length*2)];
             System.arraycopy(dstack, 0, hlp, 0, dstack.length);
             dstack = hlp;
         }
@@ -192,7 +192,7 @@
         log.debug("push float " + f + " " + getStats());
         
         if (fTop == fstack.length) {
-            float[] hlp = new float[fstack.length*2];
+            float[] hlp = new float[Math.max(8,fstack.length*2)];
             System.arraycopy(fstack, 0, hlp, 0, fstack.length);
             fstack = hlp;
         }
@@ -203,7 +203,7 @@
         log.debug("push int " + i + " " + getStats());
 
         if (iTop == istack.length) {
-            int[] hlp = new int[istack.length*2];
+            int[] hlp = new int[Math.max(8,istack.length*2)];
             System.arraycopy(istack, 0, hlp, 0, istack.length);
             istack = hlp;
         }
@@ -214,7 +214,7 @@
         log.debug("push long " + l + " " + getStats());
         
         if (lTop == lstack.length) {
-            long[] hlp = new long[lstack.length*2];
+            long[] hlp = new long[Math.max(8,lstack.length*2)];
             System.arraycopy(lstack, 0, hlp, 0, lstack.length);
             lstack = hlp;
         }
@@ -230,7 +230,7 @@
         }
         
         if (oTop == ostack.length) {
-            Object[] hlp = new Object[ostack.length*2];
+            Object[] hlp = new Object[Math.max(8,ostack.length*2)];
             System.arraycopy(ostack, 0, hlp, 0, ostack.length);
             ostack = hlp;
         }
@@ -247,7 +247,7 @@
         }
         
         if (rTop == rstack.length) {
-            Object[] hlp = new Object[rstack.length*2];
+            Object[] hlp = new Object[Math.max(8,rstack.length*2)];
             System.arraycopy(rstack, 0, hlp, 0, rstack.length);
             rstack = hlp;
         }

Modified: jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/StackRecorder.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/StackRecorder.java?rev=326409&r1=326408&r2=326409&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/StackRecorder.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/java/org/apache/commons/javaflow/bytecode/StackRecorder.java Tue Oct 18 23:18:37 2005
@@ -95,15 +95,16 @@
             runnable.run();
 
             if (capturing) {
-                // the top of the reference stack is always the same as 'runnable'.
-                // since we won't use this (instead we use 'runnable') for restoring
-                // the stack frame, we need to throw it away now, or else the restoration won't work.
-                if(isEmpty() || popReference()!=runnable) {
+                if(isEmpty()) {
                     // if we were really capturing the stack, at least we should have
                     // one object in the reference stack. Otherwise, it usually means
                     // that the application wasn't instrumented correctly.
                     throw new IllegalStateException("stack corruption. Is "+runnable.getClass()+" instrumented for javaflow?");
                 }
+                // top of the reference stack is the object that we'll call into
+                // when resuming this continuation. we have a separate Runnable
+                // for this, so throw it away
+                popReference();
                 return this;
             } else {
                 return null;    // nothing more to continue

Modified: jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/AbstractTestCase.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/AbstractTestCase.java?rev=326409&r1=326408&r2=326409&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/AbstractTestCase.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/AbstractTestCase.java Tue Oct 18 23:18:37 2005
@@ -1,33 +1,53 @@
 package org.apache.commons.javaflow;
 
+import junit.framework.TestCase;
+
 import java.io.IOException;
-import java.io.InputStream;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
-import junit.framework.TestCase;
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.javaflow.bytecode.BytecodeClassLoader;
-import org.apache.commons.javaflow.bytecode.transformation.ResourceTransformer;
-import org.apache.commons.javaflow.bytecode.transformation.bcel.BcelClassTransformer;
 
 
 public abstract class AbstractTestCase extends TestCase {
-    
+
+    /**
+     * {@link ClassLoader} that loads instrumented classes.
+     * <p/>
+     * instrumented {@link Runnable}s often need to call into
+     * other classes that in turn also need to be instrumented,
+     * we do need a class loader around that can load them.
+     */
+    private ClassLoader instrumentedLoader;
+
+    private ClassLoader oldContextClassLoader;
+
     public Runnable createRunnable(final Class pClazz)  throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SecurityException, IllegalArgumentException, NoSuchMethodException, InvocationTargetException {
         return createRunnable(pClazz, new Class[] {}, new Object[] {});
     }
     
     public Runnable createRunnable(final Class pClazz, final Class[] pParameterTypes, final Object[] pParameters) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
-        final BytecodeClassLoader clazzloader = new BytecodeClassLoader();
-        final String clazzName = pClazz.getName().replace('.', '/') + ".class";
-        final InputStream is = pClazz.getClassLoader().getResourceAsStream(clazzName);
-        final byte[] clazzBytes = IOUtils.toByteArray(is);
-        final ResourceTransformer t = new BcelClassTransformer();
-        final byte[] newClazzBytes = t.transform(clazzBytes);
-        final Class clazz = clazzloader.loadClass(newClazzBytes);
+        final Class clazz = instrumentedLoader.loadClass(pClazz.getName());
         final Constructor constructor = clazz.getConstructor(pParameterTypes);
         final Object o = constructor.newInstance(pParameters);
         return (Runnable) o;
+    }
+
+    /**
+     * Set up the context class loader to the instrumented one
+     * so that the serialization engines will use it.
+     */
+    protected void setUp() throws Exception {
+        oldContextClassLoader = Thread.currentThread().getContextClassLoader();
+        Thread.currentThread().setContextClassLoader(instrumentedLoader);
+
+        instrumentedLoader = new TestClassLoader(getClass().getClassLoader(), "org.apache.commons.javaflow.runnables.");
+
+        super.setUp();
+    }
+
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        Thread.currentThread().setContextClassLoader(oldContextClassLoader);
+        instrumentedLoader = null;
     }
 
 }

Modified: jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTestCase.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTestCase.java?rev=326409&r1=326408&r2=326409&view=diff
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTestCase.java (original)
+++ jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/SerializationTestCase.java Tue Oct 18 23:18:37 2005
@@ -1,18 +1,18 @@
 package org.apache.commons.javaflow;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
 import junitx.util.PrivateAccessor;
-import org.apache.commons.javaflow.Continuation;
 import org.apache.commons.javaflow.runnables.Invoker;
 import org.apache.commons.javaflow.runnables.Simple;
 import org.apache.commons.javaflow.runnables.SimpleSerializable;
 import org.apache.commons.javaflow.utils.ReflectionUtils;
 import org.apache.tools.ant.util.FileUtils;
-import com.thoughtworks.xstream.XStream;
-import com.thoughtworks.xstream.io.xml.DomDriver;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
 
 
 public final class SerializationTestCase extends AbstractTestCase {

Added: jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/TestClassLoader.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/TestClassLoader.java?rev=326409&view=auto
==============================================================================
--- jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/TestClassLoader.java (added)
+++ jakarta/commons/sandbox/javaflow/trunk/src/test/org/apache/commons/javaflow/TestClassLoader.java Tue Oct 18 23:18:37 2005
@@ -0,0 +1,71 @@
+package org.apache.commons.javaflow;
+
+import org.apache.commons.javaflow.bytecode.transformation.ResourceTransformer;
+import org.apache.commons.javaflow.bytecode.transformation.bcel.BcelClassTransformer;
+import org.apache.commons.io.IOUtils;
+
+import java.io.InputStream;
+import java.io.IOException;
+
+/**
+ * @author Kohsuke Kawaguchi
+ */
+public class TestClassLoader extends ClassLoader {
+    private ResourceTransformer transformer = new BcelClassTransformer();
+
+    private final String prefix;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param parent
+     *      parent class loader. Can be null, in which case it delegates
+     *      to the application class loader.
+     * @param prefix
+     *      prefix of the classes that will be instrumented by this class loader.
+     *      for example, if this parameter is "org.acme.foo.", then classes like
+     *      "org.acme.foo.Abc" or "org.acme.foo.bar.Zot" will be instrumented,
+     *      but not "org.acme.Joe" or "org.acme.foobar.Zot".
+     */
+    public TestClassLoader(ClassLoader parent, String prefix) {
+        super(parent);
+        this.prefix = prefix;
+        if(prefix==null)
+            throw new IllegalArgumentException();
+    }
+
+    private boolean shouldBeRewritten(String s) {
+        return s.startsWith(prefix);
+    }
+
+    protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+
+        Class c = findLoadedClass(name);
+
+        if(c==null && shouldBeRewritten(name)) {
+            InputStream is = super.getResourceAsStream(name.replace('.', '/') + ".class");
+            if(is!=null) {
+                try {
+                    byte[] buf = IOUtils.toByteArray(is);
+                    buf = transformer.transform(buf);
+                    c = defineClass(name, buf, 0, buf.length);
+                } catch (IOException e) {
+                    throw new ClassNotFoundException("failed to read the class file", e);
+                }
+            }
+        }
+
+        if(c==null) {
+            // delegate
+            final ClassLoader parent = getParent();
+            if (parent != null)
+                c = parent.loadClass(name);
+            else
+                throw new ClassNotFoundException(name);
+        }
+
+        if (resolve)
+            resolveClass(c);
+        return c;
+    }
+}



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