Hi,
the program works fine for me (I slightly modified it to work
without JUnit). I dump the code to a file to see what's
generated and for the testCatch it looks like
public int runTest(int x)
Code(max_stack = 2, max_locals = 2, code_length = 11)
0: aconst_null
1: iconst_0
2: invokevirtual test.Catch.runTest (I)I (10)
5: pop
6: iconst_1
7: ireturn
8: pop
9: iconst_1
10: ireturn
Exception handler(s) =
From To Handler Type
0 8 8 java.lang.NullPointerException(22)
BTW: I enhanced the code to use clazz.addEmptyConstructor(), but
that shouldn't make a difference.
When I run the program the output is
java CodeExceptionGenTest
true
NullPointerException thrown as expected
java.lang.NullPointerException
at test.NoCatch.runTest(test/NoCatch.java)
at CodeExceptionGenTest.testNoCatch(CodeExceptionGenTest.java:170)
at CodeExceptionGenTest.main(CodeExceptionGenTest.java:145)
Cheers
Markus
public interface TInterface {
public int runTest( int x );
}
import org.apache.bcel.Constants;
import org.apache.bcel.generic.*;
import org.apache.bcel.classfile.*;
import java.security.SecureClassLoader;
public class CodeExceptionGenTest {
public CodeExceptionGenTest( String name ) {
}
private static class MockClassLoader
extends SecureClassLoader
{
private CodeExceptionGenTest test = null;
public MockClassLoader( CodeExceptionGenTest test ) {
super( TInterface.class.getClassLoader() );
this.test = test;
}
protected Class findClass( String className )
throws ClassNotFoundException
{
ClassGen clazz = null;
if (className.equals( "test.NoCatch" )) {
clazz = test.makeNoCatch();
}
if (className.equals( "test.Catch" )) {
clazz = test.makeCatch();
}
if (clazz == null) {
return super.findClass( className );
}
JavaClass jClass = clazz.getJavaClass();
try {
jClass.dump(jClass.getClassName() + ".class");
} catch(Exception ex) { }
byte bytecode[] = jClass.getBytes();
Class RC = defineClass( className,
bytecode, 0,
bytecode.length );
return RC;
}
}
public ClassGen makeNoCatch()
{
ClassGen clazz = new ClassGen("test.NoCatch",
"java.lang.Object",
"test/NoCatch.java",
Constants.ACC_PUBLIC,
new String[]
{ "TInterface" } );
/*MethodGen constructor =
makeConstructor( clazz );
*/
InstructionList instructions = new InstructionList();
InstructionFactory factory = new InstructionFactory( clazz );
instructions.append( factory.ACONST_NULL );
instructions.append( factory.ICONST_0 );
instructions.append( factory.createInvoke( "test.NoCatch",
"runTest",
Type.INT,
new Type[] { Type.INT },
Constants.INVOKEVIRTUAL));
instructions.append( factory.POP );
instructions.append( factory.ICONST_1 );
instructions.append( factory.IRETURN );
MethodGen runTest =
new MethodGen( Constants.ACC_PUBLIC,
Type.INT,
new Type[] { Type.INT },
new String[] { "x" },
"runTest", "test.NoCatch",
instructions, clazz.getConstantPool() );
runTest.setMaxStack();
clazz.addMethod( runTest.getMethod() );
clazz.addEmptyConstructor(Constants.ACC_PUBLIC);
return clazz;
}
public ClassGen makeCatch()
{
ClassGen clazz = new ClassGen("test.Catch",
"java.lang.Object",
"test/Catch.java",
Constants.ACC_PUBLIC,
new String[]
{ "TInterface" } );
InstructionList instructions = new InstructionList();
InstructionFactory factory = new InstructionFactory( clazz );
instructions.append( factory.ACONST_NULL );
instructions.append( factory.ICONST_0 );
instructions.append( factory.createInvoke( "test.Catch",
"runTest",
Type.INT,
new Type[] { Type.INT },
Constants.INVOKEVIRTUAL));
instructions.append( factory.POP );
instructions.append( factory.ICONST_1 );
instructions.append( factory.IRETURN );
InstructionHandle beginTry = instructions.getStart();
InstructionHandle endTry = instructions.getEnd();
InstructionHandle catchHandle =
instructions.append( factory.POP );
instructions.append( factory.ICONST_1 );
instructions.append( factory.IRETURN );
MethodGen runTest =
new MethodGen( Constants.ACC_PUBLIC,
Type.INT,
new Type[] { Type.INT },
new String[] { "x" },
"runTest", "test.Catch",
instructions, clazz.getConstantPool() );
ObjectType npe = new ObjectType( "java.lang.NullPointerException" );
runTest.addExceptionHandler( beginTry, endTry, catchHandle, npe );
runTest.setMaxStack();
clazz.addEmptyConstructor(Constants.ACC_PUBLIC);
clazz.addMethod( runTest.getMethod() );
return clazz;
}
public static void main(String[] args)
throws Throwable
{
testCatch();
testNoCatch();
}
public static void testCatch() throws Throwable {
CodeExceptionGenTest test = new CodeExceptionGenTest("foo");
MockClassLoader loader = new MockClassLoader(test);
Class clazz = loader.loadClass("test.Catch");
TInterface object =
(TInterface) clazz.newInstance();
System.out.println(object.runTest( 3 ) == 1);
}
public static void testNoCatch()
throws Throwable
{
CodeExceptionGenTest test = new CodeExceptionGenTest("foo");
MockClassLoader loader = new MockClassLoader(test);
Class clazz = loader.loadClass("test.NoCatch");
TInterface object =
(TInterface) clazz.newInstance();
try {
object.runTest( 5 );
System.out.println("Expected NullPointerException to be thrown.");
} catch (NullPointerException npe) {
System.out.println("NullPointerException thrown as expected");
npe.printStackTrace();
}
}
}
--
To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>