Re: Problems with Try/Catch Blocks (yay! thanks!)
Vincent Marquez <[email protected]>
| Newsgroups | gmane.comp.jakarta.bcel.user |
|---|---|
| Message-ID | <[email protected]> |
Andrew,
Thank you very much for your patience. Your link and explanation were
exactly what I needed to finally get what I was doing wrong and fix the
problem. The classfile section of the VMSpec really helped me
understand what happens when objects are created. Again, thanks for
your help.
--vince
Andrew Huntwork wrote:
> 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: [email protected]
>>> For additional commands, e-mail: [email protected]
>>>
>>>
>>>
>>
>>
>> ---------------------------------------------------------------------
>> 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]
>
>
>