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 { - + + /** + * [EMAIL PROTECTED] ClassLoader} that loads instrumented classes. + * <p/> + * instrumented [EMAIL PROTECTED] 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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]