jakarta-bcel-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andrew Huntwork <...@huntwork.net>
Subject Re: Problems with Try/Catch Blocks
Date Mon, 28 Feb 2005 16:32:01 GMT
because you _didn't_ do it with bcel.  You seem to think that changing

invokespecial ArrayList.<init>
to
invokestatic ArrayList.getArrList
is the same as changing
new ArrayList()
to
ArrayList.getArrList

It's not.
new ArrayList()
compiles to
new ArrayList
dup
invokespecial ArrayList.<init>

(as shown here: 
http://java.sun.com/docs/books/vmspec/2nd-edition/html/ClassFile.doc.html#9839
)

ArrayList.getArrList()
compiles to
invokestatic ArrayList.getArrList

So you can't expect to replace 1 instruction from the first sequence 
with the second sequence and expect things to be ok.  replace the whole 
sequence, or at least pop the extra ArrayLists off the stack.

Vincent Marquez wrote:
> Well, i've been playing with this a little in my spare time and there is 
> still a problem.  This may be due to my lack of experience in regards to 
> Java's exception handling, but I don't understand why the code would 
> compile and run when I manually change the ArrayList() constructor to a 
> static method returning a new ArrayList, but not when I do it with 
> BCEL.  For reference, here is the original code I wrote by hand for the 
> test case:
> 
> -------------------------------------------------------------------------------------------------

> 
>    public static java.util.ArrayList getArrList();
>     Code:
>       0:   new     #2; //class java/util/ArrayList
>       3:   dup
>       4:   invokespecial   #3; //Method java/util/ArrayList."<init>":()V
>       7:   areturn
>      public static void main(java.lang.String[]);
>      Code:
>       0:   getstatic       #4; //Field 
> java/lang/System.out:Ljava/io/PrintStream;
>       3:   ldc     #5; //String test
>       5:   invokevirtual   #6; //Method 
> java/io/PrintStream.println:(Ljava/lang/String;)V
>       8:   new     #2; //class java/util/ArrayList
>       11:  dup
>       12:  invokespecial   #3; //Method java/util/ArrayList."<init>":()V
>       15:  astore_1
>       16:  goto    20
>       19:  astore_1
>       20:  return
>      Exception table:
>       from   to  target type
>         8    16    19   Class java/lang/Exception
> ---------------------------------------------------------------------------------- 
> 
> and the actual java that was compiled to whats up above:
>    public static void main( String [] args ) {
>        System.out.println( "test" );
>        try {
>            ArrayList arr = new ArrayList( );
>        } catch ( Exception e ) {
>        }
>    }
> ----------------------------------------------------------------------------------- 
> 
> 
> Next, I ran it through my BCEL program that modifies it.  The output is 
> exactly the same except for 13, which is now
> 13:  invokestatic    #41; //Method 
> java/util/ArrayList.getArrList:(I)Ljava/util/ArrayList;
> Here is the output again from the "after BCEL modification"
> 
> -------------------------------------------------------------------------------------

> 
>    public static void main(java.lang.String[]);
>      Code:
>       0:   getstatic       #4; //Field 
> java/lang/System.out:Ljava/io/PrintStream;
>       3:   ldc     #5; //String test
>       5:   invokevirtual   #6; //Method 
> java/io/PrintStream.println:(Ljava/lang/String;)V
>       8:   new     #2; //class java/util/ArrayList
>       11:  dup
>       12:  invokestatic    #37; //Method 
> java/util/ArrayList.getArrList:()Ljava/util/ArrayList;
>       15:  astore_1
>       16:  goto    20
>       19:  astore_1
>       20:  return
>      Exception table:
>       from   to  target type
>         8    16    19   Class java/lang/Exception
> ------------------------------------------------------------------------------------------------

> 
> 
> 
> I'm confused because I don't see how changing that one line would cause 
> the class to not be verified correctly.  I'm also stumped because when I 
> change my code manually to the following, compile, and run, it works fine.
>    try {
>       ArrayList arr = getArrList();
>    } catch ( Exception e ) {
>    }
> 
> 
> Is this a problem with BCEL or a problem with my lack of Exception 
> knowledge?  I'm leaning towards the later, but I'm quite stumped.  If 
> anyone has any clues or ideas on how I could solve this problem, I'd 
> appreciate it very much.   Thank you for your time.
> 
> --vince
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 
> Andrew Huntwork wrote:
> 
>> Vincent Marquez wrote:
>>
>>> 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
>>
>>
>>
>> is this right?
>> try {
>>
>>>    astore_1
>>>    getstatic java.lang.System.out Ljava/io/PrintStream;
>>>    ldc "test test test"
>>>    invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V
>>
>>
>> } catch(...
>>
>> is this offset 20?
>>
>>>    return
>>> =======================================================
>>
>>
>>
>> if i'm right then your problem is...
>>
>>>
>>> ===============  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
>>
>>
>>
>> this dup ^.  It leaves an extra object on the stack that will be there 
>> when you get to 20 via the goto -> 20 below but not if you get there 
>> via the exception catch block.  the stack in an exception handler is 
>> always just the exception object.  everything on the stack at the 
>> instruction that threw the exception gets tossed.
>>
>>>     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
>>> ====================================================================
>>
>>
>>
>> ---------------------------------------------------------------------
>> 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