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