You are viewing a plain text version of this content. The canonical link for it is here.
Posted to bcel-user@jakarta.apache.org by Razvanica <mo...@yahoo.fr> on 2009/05/25 19:50:17 UTC
ArrayIndexOutOfBoundsException in generic.PUTFIELD
Hello all,
Here's my problem. I am trying to make some network simulations using a tool
called JiST/SWANS. This simulator has been written for Java 1.4 and, for my
simulations, I would like to use some 1.5 features, like genericity.
So what I am trying to do is to compile the original code with the "source
-1.5" tag instead of the "source -1.4" tag. The problem is that the
simulator uses bcel to rewrite the bytecode so that JVM could be used for
simulations. The bcel library in the release doesn't work with the "source
-1.5" tag so I replace it with bcel-5.2. I made 2 minor modifications to the
original code :
- I have added an implementation of getClassPath in a class that implements
org.apache.bcel.util.Repository. This class just returns null, just like in
org.apache.bcel.util.ClassLoaderRepository
- In a class using org.apache.bcel.Repository.lookupClass() I am now
throwing java.lang.ClassNotFoundException
These 2 modifications shouldn't change anything as far as I understand the
application. And when I compile the new code with the "-source 1.4" tag, it
doesn,t change anything. Everything compiles and works just fine. However,
when I compile the new code with the "-source 1.5" tag the compilation goes
smoothly, but, at runtime, the rewriter throws an
ArrayIndexOutOfBoundsException.
This happens every time org.apache.bcel.generic.PUTFIELD.accept is called:
java.lang.ArrayIndexOutOfBoundsException: -1
at java.util.ArrayList.remove(ArrayList.java:390)
at
org.apache.bcel.verifier.structurals.OperandStack.pop(OperandStack.java:135)
at
org.apache.bcel.verifier.structurals.ExecutionVisitor.visitPUTFIELD(ExecutionVisitor.java:1048)
at org.apache.bcel.generic.PUTFIELD.accept(PUTFIELD.java:78)
Does anybody have any idea what happens and if there's something I could do
to fix this?
Thank you.
--
View this message in context: http://www.nabble.com/ArrayIndexOutOfBoundsException-in-generic.PUTFIELD-tp23710707p23710707.html
Sent from the BCEL - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-user-help@jakarta.apache.org
Re: ArrayIndexOutOfBoundsException in generic.PUTFIELD
Posted by Arrin Daley <ar...@anu.edu.au>.
Hi Razvan
If you use the BCEL APIs you can see what effect each bytecode will have on the stack (it's amongst the first lines explaining each bytecode), the stack is initially empty and the arguments are in the ALOAD_0, ILOAD1 etc slots.
Anyway I've gone through and produced an idea of what the stack does for each method below, there appears to be a couple of problems the LDC_W doesn't seem right LDC_W is typically for loading wide constants such as double and long from the constantPool, second we end up with the result of an ALOAD_0 still on the stack at the end of the execution of the method which shouldn't happen either. Neither of these really explain how you are getting a StackUnderflow problem as these are both putting too much on the stack. Anyway they are worth fixing, and perhaps it creates trouble further down the line?
Bye Arrin
Code:
0: aload_0
obj,
1: getstatic #19; //Field jist/runtime/JistAPI.THIS:Ljist/runtime/JistAPI$Entity;
obj, obj
4: ldc_w #20; //class jist/swans/app/AppInterface$UdpApp
obj, obj, w1, w2,
7: invokestatic #21; //Method jist/runtime/JistAPI.proxy:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
1st problem here the last thing put on the stack was the result of the LDC_W(a wide type constant, like a long or a double) but the invokestatic is expecting 2 objects.
Perhaps it's supposed to be an LDC? I'll continue as though it is... obj, obj, Class
obj, obj, obj
10: checkcast #20; //class jist/swans/app/AppInterface$UdpApp
obj, obj, obj
13: invokeinterface #22, 1; //InterfaceMethod jist/swans/app/AppInterface$UdpApp.getUdpEntity:()Ljist/swans/trans/TransInterface$TransUdpInterface;
obj, obj, obj
18: putfield #23; //Field udpEntity:Ljist/swans/trans/TransInterface;
obj
21: aload_0
obj, obj
22: new #1; //class java/net/InetSocketAddress
obj, obj, new
25: dup
obj, obj, new, new
26: aload_0
obj, obj, new, new, obj
27: getfield #12; //Field laddr:Ljava/net/InetAddress;
obj, obj, new, new, obj
30: aload_0
obj, obj, new, new, obj, obj
31: getfield #10; //Field lport:I
obj, obj, new, new, obj, I
34: invokespecial #8; //Method java/net/InetSocketAddress."<init>":(Ljava/net/InetAddress;I)V
obj, obj, new
37: invokevirtual #24; //Method bind:(Ljava/net/SocketAddress;)V
obj
40: return
There shouldn't be anything left on the stack at this point.
Code:
0: aload_0
obj,
1: getstatic #24; //Field jist/runtime/JistAPI.THIS:Ljist/runtime/JistAPI$Entity;
obj, obj
4: getstatic #25; //Field class$jist$swans$app$AppInterface$UdpApp:Ljava/lang/Class;
obj, obj, obj
7: ifnonnull 22
obj, obj
10: ldc #26; //String jist.swans.app.AppInterface$UdpApp
obj, obj, String
12: invokestatic #27; //Method class$:(Ljava/lang/String;)Ljava/lang/Class;
obj, obj, Class
15: dup
obj, obj, Class, Class
16: putstatic #25; //Field class$jist$swans$app$AppInterface$UdpApp:Ljava/lang/Class;
obj, obj, Class
19: goto 25
22: getstatic #25; //Field class$jist$swans$app$AppInterface$UdpApp:Ljava/lang/Class;
obj, obj, class
25: invokestatic #28; //Method jist/runtime/JistAPI.proxy:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
obj, obj,
28: checkcast #29; //class jist/swans/app/AppInterface$UdpApp
obj, obj,
31: invokeinterface #30, 1; //InterfaceMethod jist/swans/app/AppInterface$UdpApp.getUdpEntity:()Ljist/swans/trans/TransInterface$TransUdpInterface;
obj, obj
36: putfield #31; //Field udpEntity:Ljist/swans/trans/TransInterface;
.
39: aload_0
obj
40: new #6; //class java/net/InetSocketAddress
obj, new
43: dup
obj, new, new
44: aload_0
obj, new, new, obj
45: getfield #17; //Field laddr:Ljava/net/InetAddress;
obj, new, new, obj
48: aload_0
obj, new, new, obj, obj
49: getfield #15; //Field lport:I
obj, new, new, obj, I
52: invokespecial #13; //Method java/net/InetSocketAddress."<init>":(Ljava/net/InetAddress;I)V
obj, new
55: invokevirtual #32; //Method bind:(Ljava/net/SocketAddress;)V
.
58: return
Razvanica wrote:
> Hello Arrin,
>
> Thank you for your response. I found the method that fails and it's true
> that the bytecode resulting after compiling with the "-source 1.4" flag and
> the one that result when I compile with the "-source 1.5" are very
> different. Unfortunately for me, I don't have the skills required to judge
> what exactly triggers the exception I was talking about (I understand I try
> to pop from an empty stack but I haven't yet figured what exactly should be
> on that stack). I will post here the 2 bytecodes, hoping you or someone else
> would be able to detect the problem.
>
> The bytecode that works (generated with "-source 1.4") is:
> public void _jistPostInit();
> Code:
> 0: aload_0
> 1: getstatic #24; //Field
> jist/runtime/JistAPI.THIS:Ljist/runtime/JistAPI$Entity;
> 4: getstatic #25; //Field
> class$jist$swans$app$AppInterface$UdpApp:Ljava/lang/Class;
> 7: ifnonnull 22
> 10: ldc #26; //String jist.swans.app.AppInterface$UdpApp
> 12: invokestatic #27; //Method
> class$:(Ljava/lang/String;)Ljava/lang/Class;
> 15: dup
> 16: putstatic #25; //Field
> class$jist$swans$app$AppInterface$UdpApp:Ljava/lang/Class;
> 19: goto 25
> 22: getstatic #25; //Field
> class$jist$swans$app$AppInterface$UdpApp:Ljava/lang/Class;
> 25: invokestatic #28; //Method
> jist/runtime/JistAPI.proxy:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
> 28: checkcast #29; //class jist/swans/app/AppInterface$UdpApp
> 31: invokeinterface #30, 1; //InterfaceMethod
> jist/swans/app/AppInterface$UdpApp.getUdpEntity:()Ljist/swans/trans/TransInterface$TransUdpInterface;
> 36: putfield #31; //Field udpEntity:Ljist/swans/trans/TransInterface;
> 39: aload_0
> 40: new #6; //class java/net/InetSocketAddress
> 43: dup
> 44: aload_0
> 45: getfield #17; //Field laddr:Ljava/net/InetAddress;
> 48: aload_0
> 49: getfield #15; //Field lport:I
> 52: invokespecial #13; //Method
> java/net/InetSocketAddress."<init>":(Ljava/net/InetAddress;I)V
> 55: invokevirtual #32; //Method bind:(Ljava/net/SocketAddress;)V
> 58: return
>
> The one that fails, generated with "-source 1.5" is:
> public void _jistPostInit();
> Code:
> 0: aload_0
> 1: getstatic #19; //Field
> jist/runtime/JistAPI.THIS:Ljist/runtime/JistAPI$Entity;
> 4: ldc_w #20; //class jist/swans/app/AppInterface$UdpApp
> 7: invokestatic #21; //Method
> jist/runtime/JistAPI.proxy:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
> 10: checkcast #20; //class jist/swans/app/AppInterface$UdpApp
> 13: invokeinterface #22, 1; //InterfaceMethod
> jist/swans/app/AppInterface$UdpApp.getUdpEntity:()Ljist/swans/trans/TransInterface$TransUdpInterface;
> 18: putfield #23; //Field udpEntity:Ljist/swans/trans/TransInterface;
> 21: aload_0
> 22: new #1; //class java/net/InetSocketAddress
> 25: dup
> 26: aload_0
> 27: getfield #12; //Field laddr:Ljava/net/InetAddress;
> 30: aload_0
> 31: getfield #10; //Field lport:I
> 34: invokespecial #8; //Method
> java/net/InetSocketAddress."<init>":(Ljava/net/InetAddress;I)V
> 37: invokevirtual #24; //Method bind:(Ljava/net/SocketAddress;)V
> 40: return
>
> The exception appears when the putfield operation is rewritten.
>
> Thank you once again for your answer,
>
> Razvan.
>
>
>
>
> Arrin Daley wrote:
>
>> Hi
>>
>> My experience is that the error you are getting is it because some
>> method code has an invalid stack, in this case you are removing too many
>> items from the stack, the verifier is picking this up and reporting the
>> error. I'm not sure but perhaps some code doesn't call
>> MethodGen.setMaxStack() after transforming, although I doubt it, because
>> if the code were otherwise correct it should have complained of a stack
>> overflow.
>>
>> The problem has to be with the method it is verifying at the time so if
>> you can print out which method the verifier is working on and it's
>> bytecodes you could go through it and find the problem. The bytecode
>> pre-transformation by BCEL should be correct so the problem lies with
>> the transformations your code performs.
>>
>> I'm don't know why this should be a problem with 1.5 and not 1.4.
>>
>> Hope it helps
>>
>> Bye Arrin
>>
>> Razvanica wrote:
>>
>>> Hello all,
>>>
>>> Here's my problem. I am trying to make some network simulations using a
>>> tool
>>> called JiST/SWANS. This simulator has been written for Java 1.4 and, for
>>> my
>>> simulations, I would like to use some 1.5 features, like genericity.
>>>
>>> So what I am trying to do is to compile the original code with the
>>> "source
>>> -1.5" tag instead of the "source -1.4" tag. The problem is that the
>>> simulator uses bcel to rewrite the bytecode so that JVM could be used for
>>> simulations. The bcel library in the release doesn't work with the
>>> "source
>>> -1.5" tag so I replace it with bcel-5.2. I made 2 minor modifications to
>>> the
>>> original code :
>>> - I have added an implementation of getClassPath in a class that
>>> implements
>>> org.apache.bcel.util.Repository. This class just returns null, just like
>>> in
>>> org.apache.bcel.util.ClassLoaderRepository
>>> - In a class using org.apache.bcel.Repository.lookupClass() I am now
>>> throwing java.lang.ClassNotFoundException
>>>
>>> These 2 modifications shouldn't change anything as far as I understand
>>> the
>>> application. And when I compile the new code with the "-source 1.4" tag,
>>> it
>>> doesn,t change anything. Everything compiles and works just fine.
>>> However,
>>> when I compile the new code with the "-source 1.5" tag the compilation
>>> goes
>>> smoothly, but, at runtime, the rewriter throws an
>>> ArrayIndexOutOfBoundsException.
>>>
>>>
>>> This happens every time org.apache.bcel.generic.PUTFIELD.accept is
>>> called:
>>> java.lang.ArrayIndexOutOfBoundsException: -1
>>> at java.util.ArrayList.remove(ArrayList.java:390)
>>> at
>>> org.apache.bcel.verifier.structurals.OperandStack.pop(OperandStack.java:135)
>>> at
>>> org.apache.bcel.verifier.structurals.ExecutionVisitor.visitPUTFIELD(ExecutionVisitor.java:1048)
>>> at org.apache.bcel.generic.PUTFIELD.accept(PUTFIELD.java:78)
>>>
>>> Does anybody have any idea what happens and if there's something I could
>>> do
>>> to fix this?
>>>
>>> Thank you.
>>>
>>>
>> ---------------------------------------------------------------------
>> 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
Re: ArrayIndexOutOfBoundsException in generic.PUTFIELD
Posted by Razvanica <mo...@yahoo.fr>.
Hello Arrin,
Thank you for your response. I found the method that fails and it's true
that the bytecode resulting after compiling with the "-source 1.4" flag and
the one that result when I compile with the "-source 1.5" are very
different. Unfortunately for me, I don't have the skills required to judge
what exactly triggers the exception I was talking about (I understand I try
to pop from an empty stack but I haven't yet figured what exactly should be
on that stack). I will post here the 2 bytecodes, hoping you or someone else
would be able to detect the problem.
The bytecode that works (generated with "-source 1.4") is:
public void _jistPostInit();
Code:
0: aload_0
1: getstatic #24; //Field
jist/runtime/JistAPI.THIS:Ljist/runtime/JistAPI$Entity;
4: getstatic #25; //Field
class$jist$swans$app$AppInterface$UdpApp:Ljava/lang/Class;
7: ifnonnull 22
10: ldc #26; //String jist.swans.app.AppInterface$UdpApp
12: invokestatic #27; //Method
class$:(Ljava/lang/String;)Ljava/lang/Class;
15: dup
16: putstatic #25; //Field
class$jist$swans$app$AppInterface$UdpApp:Ljava/lang/Class;
19: goto 25
22: getstatic #25; //Field
class$jist$swans$app$AppInterface$UdpApp:Ljava/lang/Class;
25: invokestatic #28; //Method
jist/runtime/JistAPI.proxy:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
28: checkcast #29; //class jist/swans/app/AppInterface$UdpApp
31: invokeinterface #30, 1; //InterfaceMethod
jist/swans/app/AppInterface$UdpApp.getUdpEntity:()Ljist/swans/trans/TransInterface$TransUdpInterface;
36: putfield #31; //Field udpEntity:Ljist/swans/trans/TransInterface;
39: aload_0
40: new #6; //class java/net/InetSocketAddress
43: dup
44: aload_0
45: getfield #17; //Field laddr:Ljava/net/InetAddress;
48: aload_0
49: getfield #15; //Field lport:I
52: invokespecial #13; //Method
java/net/InetSocketAddress."<init>":(Ljava/net/InetAddress;I)V
55: invokevirtual #32; //Method bind:(Ljava/net/SocketAddress;)V
58: return
The one that fails, generated with "-source 1.5" is:
public void _jistPostInit();
Code:
0: aload_0
1: getstatic #19; //Field
jist/runtime/JistAPI.THIS:Ljist/runtime/JistAPI$Entity;
4: ldc_w #20; //class jist/swans/app/AppInterface$UdpApp
7: invokestatic #21; //Method
jist/runtime/JistAPI.proxy:(Ljava/lang/Object;Ljava/lang/Class;)Ljava/lang/Object;
10: checkcast #20; //class jist/swans/app/AppInterface$UdpApp
13: invokeinterface #22, 1; //InterfaceMethod
jist/swans/app/AppInterface$UdpApp.getUdpEntity:()Ljist/swans/trans/TransInterface$TransUdpInterface;
18: putfield #23; //Field udpEntity:Ljist/swans/trans/TransInterface;
21: aload_0
22: new #1; //class java/net/InetSocketAddress
25: dup
26: aload_0
27: getfield #12; //Field laddr:Ljava/net/InetAddress;
30: aload_0
31: getfield #10; //Field lport:I
34: invokespecial #8; //Method
java/net/InetSocketAddress."<init>":(Ljava/net/InetAddress;I)V
37: invokevirtual #24; //Method bind:(Ljava/net/SocketAddress;)V
40: return
The exception appears when the putfield operation is rewritten.
Thank you once again for your answer,
Razvan.
Arrin Daley wrote:
>
> Hi
>
> My experience is that the error you are getting is it because some
> method code has an invalid stack, in this case you are removing too many
> items from the stack, the verifier is picking this up and reporting the
> error. I'm not sure but perhaps some code doesn't call
> MethodGen.setMaxStack() after transforming, although I doubt it, because
> if the code were otherwise correct it should have complained of a stack
> overflow.
>
> The problem has to be with the method it is verifying at the time so if
> you can print out which method the verifier is working on and it's
> bytecodes you could go through it and find the problem. The bytecode
> pre-transformation by BCEL should be correct so the problem lies with
> the transformations your code performs.
>
> I'm don't know why this should be a problem with 1.5 and not 1.4.
>
> Hope it helps
>
> Bye Arrin
>
> Razvanica wrote:
>> Hello all,
>>
>> Here's my problem. I am trying to make some network simulations using a
>> tool
>> called JiST/SWANS. This simulator has been written for Java 1.4 and, for
>> my
>> simulations, I would like to use some 1.5 features, like genericity.
>>
>> So what I am trying to do is to compile the original code with the
>> "source
>> -1.5" tag instead of the "source -1.4" tag. The problem is that the
>> simulator uses bcel to rewrite the bytecode so that JVM could be used for
>> simulations. The bcel library in the release doesn't work with the
>> "source
>> -1.5" tag so I replace it with bcel-5.2. I made 2 minor modifications to
>> the
>> original code :
>> - I have added an implementation of getClassPath in a class that
>> implements
>> org.apache.bcel.util.Repository. This class just returns null, just like
>> in
>> org.apache.bcel.util.ClassLoaderRepository
>> - In a class using org.apache.bcel.Repository.lookupClass() I am now
>> throwing java.lang.ClassNotFoundException
>>
>> These 2 modifications shouldn't change anything as far as I understand
>> the
>> application. And when I compile the new code with the "-source 1.4" tag,
>> it
>> doesn,t change anything. Everything compiles and works just fine.
>> However,
>> when I compile the new code with the "-source 1.5" tag the compilation
>> goes
>> smoothly, but, at runtime, the rewriter throws an
>> ArrayIndexOutOfBoundsException.
>>
>>
>> This happens every time org.apache.bcel.generic.PUTFIELD.accept is
>> called:
>> java.lang.ArrayIndexOutOfBoundsException: -1
>> at java.util.ArrayList.remove(ArrayList.java:390)
>> at
>> org.apache.bcel.verifier.structurals.OperandStack.pop(OperandStack.java:135)
>> at
>> org.apache.bcel.verifier.structurals.ExecutionVisitor.visitPUTFIELD(ExecutionVisitor.java:1048)
>> at org.apache.bcel.generic.PUTFIELD.accept(PUTFIELD.java:78)
>>
>> Does anybody have any idea what happens and if there's something I could
>> do
>> to fix this?
>>
>> Thank you.
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>
>
>
--
View this message in context: http://www.nabble.com/ArrayIndexOutOfBoundsException-in-generic.PUTFIELD-tp23710707p23722920.html
Sent from the BCEL - User mailing list archive at Nabble.com.
---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-user-help@jakarta.apache.org
Re: ArrayIndexOutOfBoundsException in generic.PUTFIELD
Posted by Arrin Daley <ar...@anu.edu.au>.
Hi
My experience is that the error you are getting is it because some
method code has an invalid stack, in this case you are removing too many
items from the stack, the verifier is picking this up and reporting the
error. I'm not sure but perhaps some code doesn't call
MethodGen.setMaxStack() after transforming, although I doubt it, because
if the code were otherwise correct it should have complained of a stack
overflow.
The problem has to be with the method it is verifying at the time so if
you can print out which method the verifier is working on and it's
bytecodes you could go through it and find the problem. The bytecode
pre-transformation by BCEL should be correct so the problem lies with
the transformations your code performs.
I'm don't know why this should be a problem with 1.5 and not 1.4.
Hope it helps
Bye Arrin
Razvanica wrote:
> Hello all,
>
> Here's my problem. I am trying to make some network simulations using a tool
> called JiST/SWANS. This simulator has been written for Java 1.4 and, for my
> simulations, I would like to use some 1.5 features, like genericity.
>
> So what I am trying to do is to compile the original code with the "source
> -1.5" tag instead of the "source -1.4" tag. The problem is that the
> simulator uses bcel to rewrite the bytecode so that JVM could be used for
> simulations. The bcel library in the release doesn't work with the "source
> -1.5" tag so I replace it with bcel-5.2. I made 2 minor modifications to the
> original code :
> - I have added an implementation of getClassPath in a class that implements
> org.apache.bcel.util.Repository. This class just returns null, just like in
> org.apache.bcel.util.ClassLoaderRepository
> - In a class using org.apache.bcel.Repository.lookupClass() I am now
> throwing java.lang.ClassNotFoundException
>
> These 2 modifications shouldn't change anything as far as I understand the
> application. And when I compile the new code with the "-source 1.4" tag, it
> doesn,t change anything. Everything compiles and works just fine. However,
> when I compile the new code with the "-source 1.5" tag the compilation goes
> smoothly, but, at runtime, the rewriter throws an
> ArrayIndexOutOfBoundsException.
>
>
> This happens every time org.apache.bcel.generic.PUTFIELD.accept is called:
> java.lang.ArrayIndexOutOfBoundsException: -1
> at java.util.ArrayList.remove(ArrayList.java:390)
> at
> org.apache.bcel.verifier.structurals.OperandStack.pop(OperandStack.java:135)
> at
> org.apache.bcel.verifier.structurals.ExecutionVisitor.visitPUTFIELD(ExecutionVisitor.java:1048)
> at org.apache.bcel.generic.PUTFIELD.accept(PUTFIELD.java:78)
>
> Does anybody have any idea what happens and if there's something I could do
> to fix this?
>
> Thank you.
>
---------------------------------------------------------------------
To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: bcel-user-help@jakarta.apache.org