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]>

Reply via email to