jakarta-bcel-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Vincent Marquez <vmarq...@totemworks.com>
Subject Re: Problems with Try/Catch Blocks
Date Sun, 20 Feb 2005 22:46:59 GMT
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: bcel-user-unsubscribe@jakarta.apache.org
>> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-user-help@jakarta.apache.org


Mime
View raw message