Re: Problems with Try/Catch Blocks

Vincent Marquez <[email protected]>
Newsgroups gmane.comp.jakarta.bcel.user
Message-ID <[email protected]>
Andrew, I changed the 'insert/delete' to a replace, and it didn't seem 
to help the 'inconsistant stack height' problem.  Heres my new method i 
used, and I've included before and after bytecode.  If another format 
would be more helpful, just let me know.  Thanks for taking a look at my 
problem.   Hopefully i'm just missing something and not doing something 
that shouldn't be done. 

--Vince

============= BEFORE ===============================
 method name = public void <init>()
    aload_0
    invokespecial java/lang/Object/<init>()V
    return
 method name = public static java.util.ArrayList getArrList()
    new java/util/ArrayList
    dup
    invokespecial java/util/ArrayList/<init>()V
    areturn
 method name = public static void main(String[] arg0)
    getstatic java.lang.System.out Ljava/io/PrintStream;
    ldc "test"
    invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
    new java/util/ArrayList
    dup
    invokespecial java/util/ArrayList/<init>()V
    astore_1
    goto -> 20
    astore_1
    getstatic java.lang.System.out Ljava/io/PrintStream;
    ldc "test test test"
    invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
    return
=======================================================

===============  AFTER ==================================
 method name = public void <init>()
    aload_0
    invokespecial java/lang/Object/<init>()V
    return
 method name = public static java.util.ArrayList getArrList()
    new java/util/ArrayList
    dup
     invokestatic java/util/ArrayList/getArrList()Ljava/util/ArrayList; 
LoadClassType = java.util.ArrayList
    areturn
 method name = public static void main(String[] arg0)
    getstatic java.lang.System.out Ljava/io/PrintStream;
    ldc "test"
    invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
    new java/util/ArrayList
    dup
     invokestatic java/util/ArrayList/getArrList()Ljava/util/ArrayList; 
LoadClassType = java.util.ArrayList
    astore_1
    goto -> 20
    astore_1
    getstatic java.lang.System.out Ljava/io/PrintStream;
    ldc "test test test"
    invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
    return
====================================================================

=================  Method used to alter the class 
==============================


    protected void replaceConstructor( ClassGen cg, String 
original_class, String new_class, String static_method_name ) {
     
        boolean refresh = false;
        ConstantPoolGen cp_gen = cg.getConstantPool();
        ConstantPool cp        = cp_gen.getConstantPool();
        InstructionFactory factory = new InstructionFactory( cg , cp_gen );
        Method [] methods = cg.getMethods();
        for ( int x=0; x<methods.length; x++ ) {
            refresh = false;
            MethodGen method_gen = new MethodGen( methods[x], 
cg.getJavaClass().getClassName(), cp_gen );
            Iterator i = method_gen.getInstructionList().iterator();
           
            while ( i.hasNext() ) {
                InstructionHandle handle = ( InstructionHandle )i.next();

                if ( handle.getInstruction() instanceof INVOKESPECIAL && 
( ( INVOKESPECIAL )handle.getInstruction() ).getClassName( cp_gen 
).equals( original_class ) && ( ( INVOKESPECIAL )handle.getInstruction() 
).getMethodName( cp_gen ).equals( "<init>" ) ) {
                    try {
                        INVOKESPECIAL invk = ( INVOKESPECIAL 
)handle.getInstruction();
           
                        handle.setInstruction( factory.createInvoke(
                                    new_class,
                                    static_method_name,
                                    new ObjectType( original_class ),
                                    invk.getArgumentTypes( cp_gen ),
                                    Constants.INVOKESTATIC ) );

                        refresh = true;
                    //} catch ( 
org.apache.bcel.generic.TargetLostException e ) {
                    } catch ( Exception e ) {
                         Log.write( "ERROR", e.toString() );
                    }
                }

            }
            if ( refresh ) {
                method_gen.stripAttributes( false );
                method_gen.setMaxStack();
                method_gen.setMaxLocals();
                         cg.replaceMethod( methods[x], 
method_gen.getMethod() );
            }
          }
    }

=====================================================================================













Andrew Huntwork wrote:

> Posting disassembly for a simple test before and after modification 
> would be very helpful.  There are a couple obvious problems with the 
> method you've presented:  it doesn't replace the NEW instruction that 
> matches the invokespecial; and it ignores the TargetLostException that 
> will certainly occur in some code.  The second problem is easily 
> solvable by using InstructionHandle.setInstruction instead of 
> InstructionList.insert/delete.  The first is probably an artifact of 
> not seeing all your code.
>
> Vincent Marquez wrote:
>
>>
>> My problem is, while i'm modifying a method, if the method i'm 
>> modifying has a try/catch block, I get a "inconsistant stack height" 
>> error.   It seems this only occurs if the Try/Catch block is directly 
>> around the part i'm modifying.  Currently, i'm replacing a 
>> constructor from once class type to another.  It works perfectly 
>> except when there are Try/Catch blocks.  For example, if I have
>>
>> 1:    public static void main( String [] args ) {
>> 2:        System.out.println( "test" );
>> 3:        System.out.println( "anotherr test");
>> 4:        Shape shape = new Shape();
>> 5:        System.out.println( "final test" );
>> 6:     }
>>
>> There isn't a problem if the try/catch is around line 2 and 3.  Only 
>> if it encapsulates line 4, or anything after,  will there be the 
>> error.   For legal reasons i'm unable to show all my actual code so I 
>> contrived a very similar example of our insturmenation method that is 
>> below.   If i'm doing anything wrong/stupid let me know.  If you see 
>> other problems with my code, feel free to let me know also, i'm 
>> always looking for ways to improve.  Thanks for any help/suggestions 
>> and MUCH thanks to whoever can solve my problem.
>>
>> --vince
>>
>> protected void replaceConstructor( ClassGen cg, String 
>> original_class, String new_class ) {
>>
>>        boolean refresh = false;
>>        ConstantPoolGen cp_gen = cg.getConstantPool();
>>        ConstantPool cp        = cp_gen.getConstantPool();
>>        InstructionFactory factory = new InstructionFactory( cg , 
>> cp_gen );
>>
>>        Method [] methods = cg.getMethods();
>>        for ( int x=0; x<methods.length; x++ ) {
>>            refresh = false;
>>            MethodGen method_gen = new MethodGen( methods[x], 
>> cg.getJavaClass().getClassName(), cp_gen );
>>            Iterator i = method_gen.getInstructionList().iterator();
>>                    while ( i.hasNext() ) {
>>                InstructionHandle handle = ( InstructionHandle )i.next();
>>
>>                if ( handle.getInstruction() instanceof INVOKESPECIAL 
>> && ( ( INVOKESPECIAL )handle.getInstruction() ).getClassName( cp_gen 
>> ).equals( original_class ) && ( ( INVOKESPECIAL 
>> )handle.getInstruction() ).getMethodName( cp_gen ).equals( "<init>" ) 
>> ) {
>>                    try {
>>                        INVOKESPECIAL invk = ( INVOKESPECIAL 
>> )handle.getInstruction();
>>                                      
>> method_gen.getInstructionList().insert( invk, factory.createInvoke(
>>                                    new_class,
>>                                    "name",
>>                                    new ObjectType( original_class ),
>>                                    invk.getArgumentTypes( cp_gen ),
>>                                    Constants.INVOKESTATIC) );
>>
>>                        // Delete the old method
>>                        method_gen.getInstructionList().delete( invk );
>>                        refresh = true;
>>                    } catch ( 
>> org.apache.bcel.generic.TargetLostException e ) {
>>                        Log.write( "Error", + e.toString() );
>>                    }
>>                }
>>            }
>>            if ( refresh ) {
>>                  method_gen.stripAttributes( false );
>>                method_gen.setMaxStack();
>>                method_gen.setMaxLocals();
>>               cg.replaceMethod( methods[x], method_gen.getMethod() );
>>            }
>>           }
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [email protected]
>> For additional commands, e-mail: [email protected]
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.