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 Konstantin Scheglov <sc...@nlmk.ru> on 2003/06/11 16:17:47 UTC

Invalid constant pool reference: 28088. Constant pool size is: 1024

  I use following code to instrument one class.
  But when I instrument some classes and try to print debug
information, I receive following exception.

org.apache.bcel.classfile.ClassFormatException: Invalid constant pool reference: 28088. Constant pool size is: 1024
        at org.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:242)
        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:369)
        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:166)
        at org.apache.bcel.classfile.Code.toString(Code.java:326)
        at org.apache.bcel.classfile.Code.toString(Code.java:352)
        at java.lang.String.valueOf(String.java:2131)
        at java.io.PrintStream.print(PrintStream.java:462)
        at java.io.PrintStream.println(PrintStream.java:599)
        at ru.nlmk.eclipse.plugins.profiler.trace.Trace.instrumentClass(Trace.java:1190)
        at ru.nlmk.eclipse.plugins.profiler.trace.test.TestBCEL.main(TestBCEL.java:23)


 As you can see, I just copy code from one method to another (in real application
I change code a little). And when I try to load this class in real application
I receive exception like this from JVM:  "VerifyError: Illegal constant pool index".


        public static JavaClass instrumentClass(JavaClass clazz) throws Exception {
                ClassGen classGen = new ClassGen(clazz);
                ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
                classGen.setConstantPool(cp);
                //
                for (int i = 0; i < clazz.getMethods().length; i++) {
                        Method method = clazz.getMethods()[i];
                        if (method.isAbstract() || method.isNative())
                                continue;
                        if (method.getName().equals("finalize"))
                                continue;
                        MethodGen mg = new MethodGen(method, clazz.getClassName(), cp);
                        mg.setConstantPool(cp);
                        Method newMethod = mg.getMethod();
                        if (m_Debug) {
                                System.out.println(method.getCode());
                                System.out.println(newMethod.getCode());
                        }
                        classGen.replaceMethod(method, newMethod);
                }
                //
                JavaClass newClazz = classGen.getJavaClass();
                newClazz.setConstantPool(cp.getFinalConstantPool());
                return newClazz;
        }

  What I do wrong?
  I see such exception only on few classes (methods).
  I have example of such class.
        

-- 
Best regards,
 Konstantin                            mailto:scheglov_ke@nlmk.ru


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


Re[2]: Invalid constant pool reference: 28088. Constant pool size is: 1024

Posted by Konstantin Scheglov <sc...@nlmk.ru>.
Hello Stephen,

Wednesday, June 11, 2003, 7:13:39 PM, you wrote:

SK> Sorry, I forgot a think: try verifying with BCEL's verifier: extremly 
SK> useful utility. It have stand alone gui, but you can access its command 
SK> line interface: org.apache.bcel.verifier.Main.main("ru.tum.tum.ClassName");
  There is no such class in bcel.jar.
  There is org.apache.bcel.verifier.GraphicalVerifier, but when I try
to start it, it shows several classes, two green panels and hangs with
infinite "PLEASE WAIT" message on window caption. Is this normal?


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



-- 
Best regards,
 Konstantin                            mailto:scheglov_ke@nlmk.ru


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


Re: Invalid constant pool reference: 28088. Constant pool size is: 1024

Posted by Stephen Kolaroff <ch...@riflexo.com>.
Sorry, I forgot a think: try verifying with BCEL's verifier: extremly 
useful utility. It have stand alone gui, but you can access its command 
line interface: org.apache.bcel.verifier.Main.main("ru.tum.tum.ClassName");


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


Re[2]: Invalid constant pool reference: 28088. Constant pool size is: 1024

Posted by Konstantin Scheglov <sc...@nlmk.ru>.
Hello Stephen,

Thursday, June 12, 2003, 1:06:25 PM, you wrote:

  So... Can you change code in CVS to fix this?

SK> I found the problem (again:)), and posting this so anybody interested
SK> can read from one place.
SK> Last time I did not noticed the setSize() invokation from within 
SK> initFromFile.
SK> What happens:
SK> setSize() makes the proper length and changes the opcode (hmm, I am not 
SK> sure I want BCEL to change compiled code without my confirmation, but 
SK> who cares!). The next line in the initFromFile _restores_ the old opcode 
SK> (LDC_W), thus making opcode and length inconsistent. The problem shows 
SK> only when compiled code contains LDC_W with index less than MAX_BYTE 
SK> (when LDC suffice), and, therefore, shows up very rarely.

SK> Konstantin Scheglov wrote:

>>Hello Stephen,
>>
>>Thursday, June 12, 2003, 11:56:21 AM, you wrote:
>>
>>SK> Kosja, we are strange guys.
>>SK> Who checked the bug reports?
>>SK> Nobody...
>>SK> But should:
>>SK> http://nagoya.apache.org/bugzilla/show_bug.cgi?id=18323
>>  Ok, thanks. But to find this bug I should already to know, what to
>>search. :-)
>>
>>SK> (I investigated the code. Actually nobody invokes setSize(), when 
>>SK> reading from file; and NOONE sets proper length of LDC_W, when reading 
>>SK> from file (i think), and it stays 0 all the time. The fix you made in 
>>SK> dump() forces dumping with proper length  for the proper instruction).
>>  LDC_W.initFromFile calls LDC.setIndex, which call LDC.setSize()
>>  Well, may be my fix is not enough, it just dumps right bytes, but
>>length is still wrong.
>>  As I can see, there was version 1.2 of LDC_W with:
>>    opcode = org.apache.bcel.Constants.LDC_W;
>>    length = 3;
>>  but in 1.3 there was "bug fix" and length change was removed.
>>
>>SK> Strange, I have passed near a MB bytecode through BCEL, and had never 
>>SK> seen this bug in action.
>>  Yes, I and users of my tool also process many MB of code, but
>>as you can see, sometimes this happens. I have sample class (about 500
>>bytes length). Most probably this class also was automatically
>>generated, and generator is not smart enough to use LDC when index is
>>small, so it uses LDC_W and this causes problem. I think javac/jikes
>>use LDC where this is possible, so you just never see such cases.
>>
>>SK> About method copy:
>>SK> class Class1 {
>>SK> void method1() {
>>SK> // getstatic <System.out>
>>SK> // ldc #3 <String "Hello world">!!!!!
>>SK> // invokevirtual <PrintStream::println(String)>
>>SK> // return
>>SK> }
>>SK> }
>>
>>SK> if you want to copy method1 to _another_ class, you have to make sure 
>>SK> that ldc "Hello world" points somewhere in the new constantpool where 
>>SK> you have "Hello world". Complications are pouring in when you want the 
>>SK> copied method to reference methods of its containing class; or to 
>>SK> checkcast if a reference points to instance of the enclosing class.
>>  Thank you.
>>  I just replace methods in each class with a little changed methods,
>>so I think, that changing of constant pool is not required.
>>
>>SK> Konstantin Scheglov wrote:
>>
>>  
>>
>>>>Hello Stephen,
>>>>
>>>>Wednesday, June 11, 2003, 7:11:16 PM, you wrote:
>>>>
>>>> Ok, now I am sure, that this is bug in BCEL.
>>>>
>>>> Here is code from LDC_W:
>>>> protected void initFromFile(ByteSequence bytes, boolean wide)
>>>>      throws IOException
>>>> {
>>>>   setIndex(bytes.readUnsignedShort());
>>>>   // Override just in case it has been changed
>>>>   opcode = org.apache.bcel.Constants.LDC_W;
>>>> }
>>>> As you can see, it forces instruction code to LDC_W.
>>>>
>>>> And here is code from LDC:
>>>> public final void setIndex(int index) {
>>>>   super.setIndex(index);
>>>>   setSize();
>>>> }
>>>> protected final void setSize() {
>>>>   if(index <= org.apache.bcel.Constants.MAX_BYTE) { // Fits in one byte?
>>>>     opcode = org.apache.bcel.Constants.LDC;
>>>>     length = 2;
>>>>   } else {
>>>>     opcode = org.apache.bcel.Constants.LDC_W;
>>>>     length = 3;
>>>>   }
>>>> }
>>>>
>>>> I.e. setSize() changes inscruction code and length. Then, length
>>>>used in dump() to detect, that byte or short argument is needed:
>>>> public void dump(DataOutputStream out) throws IOException {
>>>>   out.writeByte(opcode);
>>>>   if(length == 2)
>>>>     out.writeByte(index);
>>>>   else // Applies for LDC_W
>>>>     out.writeShort(index);
>>>> }
>>>>
>>>> But we have (in my case) length == 2, i.e. one byte and LDC_W
>>>>instruction! So, when it tryies to create String for this instruction,
>>>>it reads one random byte (in reallity next instruction)!
>>>>
>>>> When I change dump() to this code, I receive no exceptions.
>>>>
>>>> public void dump(DataOutputStream out) throws IOException {
>>>>   out.writeByte(opcode);
>>>>   if(opcode == org.apache.bcel.Constants.LDC)
>>>>     out.writeByte(index);
>>>>   else // Applies for LDC_W
>>>>     out.writeShort(index);
>>>> }
>>>>
>>>> 
>>>>
>>>>SK> The code you sent is OK, at least for BCEL 5.0 and 5.1 (I have 
>>>>SK> experience with those). The problem is elsewere.
>>>>SK> Btw, did you checked if your original (not instrumented) classes are 
>>>>SK> acceptible? It is so stupid mistake, that you have to be genious to 
>>>>SK> avoid it, at least I can not :))).
>>>>SK> Beside this: if you copy method from one class to another (i do not what 
>>>>SK> are your real application), you must change the constant pool indices of 
>>>>SK> the instructions.
>>>>
>>>>SK> Konstantin Scheglov wrote:
>>>>
>>>> 
>>>>
>>>>      
>>>>
>>>>>>I use following code to instrument one class.
>>>>>>But when I instrument some classes and try to print debug
>>>>>>information, I receive following exception.
>>>>>>
>>>>>>org.apache.bcel.classfile.ClassFormatException: Invalid constant pool reference: 28088. Constant pool size is: 1024
>>>>>>      at org.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:242)
>>>>>>      at org.apache.bcel.classfile.Utility.codeToString(Utility.java:369)
>>>>>>      at org.apache.bcel.classfile.Utility.codeToString(Utility.java:166)
>>>>>>      at org.apache.bcel.classfile.Code.toString(Code.java:326)
>>>>>>      at org.apache.bcel.classfile.Code.toString(Code.java:352)
>>>>>>      at java.lang.String.valueOf(String.java:2131)
>>>>>>      at java.io.PrintStream.print(PrintStream.java:462)
>>>>>>      at java.io.PrintStream.println(PrintStream.java:599)
>>>>>>      at ru.nlmk.eclipse.plugins.profiler.trace.Trace.instrumentClass(Trace.java:1190)
>>>>>>      at ru.nlmk.eclipse.plugins.profiler.trace.test.TestBCEL.main(TestBCEL.java:23)
>>>>>>
>>>>>>
>>>>>>As you can see, I just copy code from one method to another (in real application
>>>>>>I change code a little). And when I try to load this class in real application
>>>>>>I receive exception like this from JVM:  "VerifyError: Illegal constant pool index".
>>>>>>
>>>>>>
>>>>>>      public static JavaClass instrumentClass(JavaClass clazz) throws Exception {
>>>>>>              ClassGen classGen = new ClassGen(clazz);
>>>>>>              ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
>>>>>>              classGen.setConstantPool(cp);
>>>>>>              //
>>>>>>              for (int i = 0; i < clazz.getMethods().length; i++) {
>>>>>>                      Method method = clazz.getMethods()[i];
>>>>>>                      if (method.isAbstract() || method.isNative())
>>>>>>                              continue;
>>>>>>                      if (method.getName().equals("finalize"))
>>>>>>                              continue;
>>>>>>                      MethodGen mg = new MethodGen(method, clazz.getClassName(), cp);
>>>>>>                      mg.setConstantPool(cp);
>>>>>>                      Method newMethod = mg.getMethod();
>>>>>>                      if (m_Debug) {
>>>>>>                              System.out.println(method.getCode());
>>>>>>                              System.out.println(newMethod.getCode());
>>>>>>                      }
>>>>>>                      classGen.replaceMethod(method, newMethod);
>>>>>>              }
>>>>>>              //
>>>>>>              JavaClass newClazz = classGen.getJavaClass();
>>>>>>              newClazz.setConstantPool(cp.getFinalConstantPool());
>>>>>>              return newClazz;
>>>>>>      }
>>>>>>
>>>>>>What I do wrong?
>>>>>>I see such exception only on few classes (methods).
>>>>>>I have example of such class.
>>>>>>      
>>>>>>
>>>>>>
>>>>>>
>>>>>>     
>>>>>>
>>>>>>          
>>>>>>
>>>>
>>>>SK> ---------------------------------------------------------------------
>>>>SK> To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
>>>>SK> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>>>>
>>>>
>>>>
>>>> 
>>>>
>>>>      
>>>>
>>
>>
>>
>>
>>  
>>




-- 
Best regards,
 Konstantin                            mailto:scheglov_ke@nlmk.ru


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


Re: Invalid constant pool reference: 28088. Constant pool size is: 1024

Posted by Stephen Kolaroff <ch...@riflexo.com>.
Hello Konstantin

I found the problem (again:)), and posting this so anybody interested 
can read from one place.
Last time I did not noticed the setSize() invokation from within 
initFromFile.
What happens:
setSize() makes the proper length and changes the opcode (hmm, I am not 
sure I want BCEL to change compiled code without my confirmation, but 
who cares!). The next line in the initFromFile _restores_ the old opcode 
(LDC_W), thus making opcode and length inconsistent. The problem shows 
only when compiled code contains LDC_W with index less than MAX_BYTE 
(when LDC suffice), and, therefore, shows up very rarely.

Konstantin Scheglov wrote:

>Hello Stephen,
>
>Thursday, June 12, 2003, 11:56:21 AM, you wrote:
>
>SK> Kosja, we are strange guys.
>SK> Who checked the bug reports?
>SK> Nobody...
>SK> But should:
>SK> http://nagoya.apache.org/bugzilla/show_bug.cgi?id=18323
>  Ok, thanks. But to find this bug I should already to know, what to
>search. :-)
>
>SK> (I investigated the code. Actually nobody invokes setSize(), when 
>SK> reading from file; and NOONE sets proper length of LDC_W, when reading 
>SK> from file (i think), and it stays 0 all the time. The fix you made in 
>SK> dump() forces dumping with proper length  for the proper instruction).
>  LDC_W.initFromFile calls LDC.setIndex, which call LDC.setSize()
>  Well, may be my fix is not enough, it just dumps right bytes, but
>length is still wrong.
>  As I can see, there was version 1.2 of LDC_W with:
>    opcode = org.apache.bcel.Constants.LDC_W;
>    length = 3;
>  but in 1.3 there was "bug fix" and length change was removed.
>
>SK> Strange, I have passed near a MB bytecode through BCEL, and had never 
>SK> seen this bug in action.
>  Yes, I and users of my tool also process many MB of code, but
>as you can see, sometimes this happens. I have sample class (about 500
>bytes length). Most probably this class also was automatically
>generated, and generator is not smart enough to use LDC when index is
>small, so it uses LDC_W and this causes problem. I think javac/jikes
>use LDC where this is possible, so you just never see such cases.
>
>SK> About method copy:
>SK> class Class1 {
>SK> void method1() {
>SK> // getstatic <System.out>
>SK> // ldc #3 <String "Hello world">!!!!!
>SK> // invokevirtual <PrintStream::println(String)>
>SK> // return
>SK> }
>SK> }
>
>SK> if you want to copy method1 to _another_ class, you have to make sure 
>SK> that ldc "Hello world" points somewhere in the new constantpool where 
>SK> you have "Hello world". Complications are pouring in when you want the 
>SK> copied method to reference methods of its containing class; or to 
>SK> checkcast if a reference points to instance of the enclosing class.
>  Thank you.
>  I just replace methods in each class with a little changed methods,
>so I think, that changing of constant pool is not required.
>
>SK> Konstantin Scheglov wrote:
>
>  
>
>>>Hello Stephen,
>>>
>>>Wednesday, June 11, 2003, 7:11:16 PM, you wrote:
>>>
>>> Ok, now I am sure, that this is bug in BCEL.
>>>
>>> Here is code from LDC_W:
>>> protected void initFromFile(ByteSequence bytes, boolean wide)
>>>      throws IOException
>>> {
>>>   setIndex(bytes.readUnsignedShort());
>>>   // Override just in case it has been changed
>>>   opcode = org.apache.bcel.Constants.LDC_W;
>>> }
>>> As you can see, it forces instruction code to LDC_W.
>>>
>>> And here is code from LDC:
>>> public final void setIndex(int index) {
>>>   super.setIndex(index);
>>>   setSize();
>>> }
>>> protected final void setSize() {
>>>   if(index <= org.apache.bcel.Constants.MAX_BYTE) { // Fits in one byte?
>>>     opcode = org.apache.bcel.Constants.LDC;
>>>     length = 2;
>>>   } else {
>>>     opcode = org.apache.bcel.Constants.LDC_W;
>>>     length = 3;
>>>   }
>>> }
>>>
>>> I.e. setSize() changes inscruction code and length. Then, length
>>>used in dump() to detect, that byte or short argument is needed:
>>> public void dump(DataOutputStream out) throws IOException {
>>>   out.writeByte(opcode);
>>>   if(length == 2)
>>>     out.writeByte(index);
>>>   else // Applies for LDC_W
>>>     out.writeShort(index);
>>> }
>>>
>>> But we have (in my case) length == 2, i.e. one byte and LDC_W
>>>instruction! So, when it tryies to create String for this instruction,
>>>it reads one random byte (in reallity next instruction)!
>>>
>>> When I change dump() to this code, I receive no exceptions.
>>>
>>> public void dump(DataOutputStream out) throws IOException {
>>>   out.writeByte(opcode);
>>>   if(opcode == org.apache.bcel.Constants.LDC)
>>>     out.writeByte(index);
>>>   else // Applies for LDC_W
>>>     out.writeShort(index);
>>> }
>>>
>>> 
>>>
>>>SK> The code you sent is OK, at least for BCEL 5.0 and 5.1 (I have 
>>>SK> experience with those). The problem is elsewere.
>>>SK> Btw, did you checked if your original (not instrumented) classes are 
>>>SK> acceptible? It is so stupid mistake, that you have to be genious to 
>>>SK> avoid it, at least I can not :))).
>>>SK> Beside this: if you copy method from one class to another (i do not what 
>>>SK> are your real application), you must change the constant pool indices of 
>>>SK> the instructions.
>>>
>>>SK> Konstantin Scheglov wrote:
>>>
>>> 
>>>
>>>      
>>>
>>>>>I use following code to instrument one class.
>>>>>But when I instrument some classes and try to print debug
>>>>>information, I receive following exception.
>>>>>
>>>>>org.apache.bcel.classfile.ClassFormatException: Invalid constant pool reference: 28088. Constant pool size is: 1024
>>>>>      at org.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:242)
>>>>>      at org.apache.bcel.classfile.Utility.codeToString(Utility.java:369)
>>>>>      at org.apache.bcel.classfile.Utility.codeToString(Utility.java:166)
>>>>>      at org.apache.bcel.classfile.Code.toString(Code.java:326)
>>>>>      at org.apache.bcel.classfile.Code.toString(Code.java:352)
>>>>>      at java.lang.String.valueOf(String.java:2131)
>>>>>      at java.io.PrintStream.print(PrintStream.java:462)
>>>>>      at java.io.PrintStream.println(PrintStream.java:599)
>>>>>      at ru.nlmk.eclipse.plugins.profiler.trace.Trace.instrumentClass(Trace.java:1190)
>>>>>      at ru.nlmk.eclipse.plugins.profiler.trace.test.TestBCEL.main(TestBCEL.java:23)
>>>>>
>>>>>
>>>>>As you can see, I just copy code from one method to another (in real application
>>>>>I change code a little). And when I try to load this class in real application
>>>>>I receive exception like this from JVM:  "VerifyError: Illegal constant pool index".
>>>>>
>>>>>
>>>>>      public static JavaClass instrumentClass(JavaClass clazz) throws Exception {
>>>>>              ClassGen classGen = new ClassGen(clazz);
>>>>>              ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
>>>>>              classGen.setConstantPool(cp);
>>>>>              //
>>>>>              for (int i = 0; i < clazz.getMethods().length; i++) {
>>>>>                      Method method = clazz.getMethods()[i];
>>>>>                      if (method.isAbstract() || method.isNative())
>>>>>                              continue;
>>>>>                      if (method.getName().equals("finalize"))
>>>>>                              continue;
>>>>>                      MethodGen mg = new MethodGen(method, clazz.getClassName(), cp);
>>>>>                      mg.setConstantPool(cp);
>>>>>                      Method newMethod = mg.getMethod();
>>>>>                      if (m_Debug) {
>>>>>                              System.out.println(method.getCode());
>>>>>                              System.out.println(newMethod.getCode());
>>>>>                      }
>>>>>                      classGen.replaceMethod(method, newMethod);
>>>>>              }
>>>>>              //
>>>>>              JavaClass newClazz = classGen.getJavaClass();
>>>>>              newClazz.setConstantPool(cp.getFinalConstantPool());
>>>>>              return newClazz;
>>>>>      }
>>>>>
>>>>>What I do wrong?
>>>>>I see such exception only on few classes (methods).
>>>>>I have example of such class.
>>>>>      
>>>>>
>>>>>
>>>>>
>>>>>     
>>>>>
>>>>>          
>>>>>
>>>
>>>SK> ---------------------------------------------------------------------
>>>SK> To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
>>>SK> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>>>
>>>
>>>
>>> 
>>>
>>>      
>>>
>
>
>
>
>  
>


Re[2]: Invalid constant pool reference: 28088. Constant pool size is: 1024

Posted by Konstantin Scheglov <sc...@nlmk.ru>.
Hello Stephen,

Thursday, June 12, 2003, 11:56:21 AM, you wrote:

SK> Kosja, we are strange guys.
SK> Who checked the bug reports?
SK> Nobody...
SK> But should:
SK> http://nagoya.apache.org/bugzilla/show_bug.cgi?id=18323
  Ok, thanks. But to find this bug I should already to know, what to
search. :-)

SK> (I investigated the code. Actually nobody invokes setSize(), when 
SK> reading from file; and NOONE sets proper length of LDC_W, when reading 
SK> from file (i think), and it stays 0 all the time. The fix you made in 
SK> dump() forces dumping with proper length  for the proper instruction).
  LDC_W.initFromFile calls LDC.setIndex, which call LDC.setSize()
  Well, may be my fix is not enough, it just dumps right bytes, but
length is still wrong.
  As I can see, there was version 1.2 of LDC_W with:
    opcode = org.apache.bcel.Constants.LDC_W;
    length = 3;
  but in 1.3 there was "bug fix" and length change was removed.

SK> Strange, I have passed near a MB bytecode through BCEL, and had never 
SK> seen this bug in action.
  Yes, I and users of my tool also process many MB of code, but
as you can see, sometimes this happens. I have sample class (about 500
bytes length). Most probably this class also was automatically
generated, and generator is not smart enough to use LDC when index is
small, so it uses LDC_W and this causes problem. I think javac/jikes
use LDC where this is possible, so you just never see such cases.

SK> About method copy:
SK> class Class1 {
SK> void method1() {
SK> // getstatic <System.out>
SK> // ldc #3 <String "Hello world">!!!!!
SK> // invokevirtual <PrintStream::println(String)>
SK> // return
SK> }
SK> }

SK> if you want to copy method1 to _another_ class, you have to make sure 
SK> that ldc "Hello world" points somewhere in the new constantpool where 
SK> you have "Hello world". Complications are pouring in when you want the 
SK> copied method to reference methods of its containing class; or to 
SK> checkcast if a reference points to instance of the enclosing class.
  Thank you.
  I just replace methods in each class with a little changed methods,
so I think, that changing of constant pool is not required.

SK> Konstantin Scheglov wrote:

>>Hello Stephen,
>>
>>Wednesday, June 11, 2003, 7:11:16 PM, you wrote:
>>
>>  Ok, now I am sure, that this is bug in BCEL.
>>
>>  Here is code from LDC_W:
>>  protected void initFromFile(ByteSequence bytes, boolean wide)
>>       throws IOException
>>  {
>>    setIndex(bytes.readUnsignedShort());
>>    // Override just in case it has been changed
>>    opcode = org.apache.bcel.Constants.LDC_W;
>>  }
>>  As you can see, it forces instruction code to LDC_W.
>>
>>  And here is code from LDC:
>>  public final void setIndex(int index) {
>>    super.setIndex(index);
>>    setSize();
>>  }
>>  protected final void setSize() {
>>    if(index <= org.apache.bcel.Constants.MAX_BYTE) { // Fits in one byte?
>>      opcode = org.apache.bcel.Constants.LDC;
>>      length = 2;
>>    } else {
>>      opcode = org.apache.bcel.Constants.LDC_W;
>>      length = 3;
>>    }
>>  }
>>
>>  I.e. setSize() changes inscruction code and length. Then, length
>>used in dump() to detect, that byte or short argument is needed:
>>  public void dump(DataOutputStream out) throws IOException {
>>    out.writeByte(opcode);
>>    if(length == 2)
>>      out.writeByte(index);
>>    else // Applies for LDC_W
>>      out.writeShort(index);
>>  }
>>
>>  But we have (in my case) length == 2, i.e. one byte and LDC_W
>>instruction! So, when it tryies to create String for this instruction,
>>it reads one random byte (in reallity next instruction)!
>>
>>  When I change dump() to this code, I receive no exceptions.
>>
>>  public void dump(DataOutputStream out) throws IOException {
>>    out.writeByte(opcode);
>>    if(opcode == org.apache.bcel.Constants.LDC)
>>      out.writeByte(index);
>>    else // Applies for LDC_W
>>      out.writeShort(index);
>>  }
>>
>>  
>>
>>SK> The code you sent is OK, at least for BCEL 5.0 and 5.1 (I have 
>>SK> experience with those). The problem is elsewere.
>>SK> Btw, did you checked if your original (not instrumented) classes are 
>>SK> acceptible? It is so stupid mistake, that you have to be genious to 
>>SK> avoid it, at least I can not :))).
>>SK> Beside this: if you copy method from one class to another (i do not what 
>>SK> are your real application), you must change the constant pool indices of 
>>SK> the instructions.
>>
>>SK> Konstantin Scheglov wrote:
>>
>>  
>>
>>>> I use following code to instrument one class.
>>>> But when I instrument some classes and try to print debug
>>>>information, I receive following exception.
>>>>
>>>>org.apache.bcel.classfile.ClassFormatException: Invalid constant pool reference: 28088. Constant pool size is: 1024
>>>>       at org.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:242)
>>>>       at org.apache.bcel.classfile.Utility.codeToString(Utility.java:369)
>>>>       at org.apache.bcel.classfile.Utility.codeToString(Utility.java:166)
>>>>       at org.apache.bcel.classfile.Code.toString(Code.java:326)
>>>>       at org.apache.bcel.classfile.Code.toString(Code.java:352)
>>>>       at java.lang.String.valueOf(String.java:2131)
>>>>       at java.io.PrintStream.print(PrintStream.java:462)
>>>>       at java.io.PrintStream.println(PrintStream.java:599)
>>>>       at ru.nlmk.eclipse.plugins.profiler.trace.Trace.instrumentClass(Trace.java:1190)
>>>>       at ru.nlmk.eclipse.plugins.profiler.trace.test.TestBCEL.main(TestBCEL.java:23)
>>>>
>>>>
>>>>As you can see, I just copy code from one method to another (in real application
>>>>I change code a little). And when I try to load this class in real application
>>>>I receive exception like this from JVM:  "VerifyError: Illegal constant pool index".
>>>>
>>>>
>>>>       public static JavaClass instrumentClass(JavaClass clazz) throws Exception {
>>>>               ClassGen classGen = new ClassGen(clazz);
>>>>               ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
>>>>               classGen.setConstantPool(cp);
>>>>               //
>>>>               for (int i = 0; i < clazz.getMethods().length; i++) {
>>>>                       Method method = clazz.getMethods()[i];
>>>>                       if (method.isAbstract() || method.isNative())
>>>>                               continue;
>>>>                       if (method.getName().equals("finalize"))
>>>>                               continue;
>>>>                       MethodGen mg = new MethodGen(method, clazz.getClassName(), cp);
>>>>                       mg.setConstantPool(cp);
>>>>                       Method newMethod = mg.getMethod();
>>>>                       if (m_Debug) {
>>>>                               System.out.println(method.getCode());
>>>>                               System.out.println(newMethod.getCode());
>>>>                       }
>>>>                       classGen.replaceMethod(method, newMethod);
>>>>               }
>>>>               //
>>>>               JavaClass newClazz = classGen.getJavaClass();
>>>>               newClazz.setConstantPool(cp.getFinalConstantPool());
>>>>               return newClazz;
>>>>       }
>>>>
>>>> What I do wrong?
>>>> I see such exception only on few classes (methods).
>>>> I have example of such class.
>>>>       
>>>>
>>>> 
>>>>
>>>>      
>>>>
>>
>>
>>
>>SK> ---------------------------------------------------------------------
>>SK> To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
>>SK> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>>
>>
>>
>>  
>>




-- 
Best regards,
 Konstantin                            mailto:scheglov_ke@nlmk.ru


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


Re: Invalid constant pool reference: 28088. Constant pool size is: 1024

Posted by Stephen Kolaroff <ch...@riflexo.com>.
Kosja, we are strange guys.
Who checked the bug reports?
Nobody...
But should:
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=18323

(I investigated the code. Actually nobody invokes setSize(), when 
reading from file; and NOONE sets proper length of LDC_W, when reading 
from file (i think), and it stays 0 all the time. The fix you made in 
dump() forces dumping with proper length  for the proper instruction).

Strange, I have passed near a MB bytecode through BCEL, and had never 
seen this bug in action.

About method copy:
class Class1 {
void method1() {
// getstatic <System.out>
// ldc #3 <String "Hello world">!!!!!
// invokevirtual <PrintStream::println(String)>
// return
}
}

if you want to copy method1 to _another_ class, you have to make sure 
that ldc "Hello world" points somewhere in the new constantpool where 
you have "Hello world". Complications are pouring in when you want the 
copied method to reference methods of its containing class; or to 
checkcast if a reference points to instance of the enclosing class.

Konstantin Scheglov wrote:

>Hello Stephen,
>
>Wednesday, June 11, 2003, 7:11:16 PM, you wrote:
>
>  Ok, now I am sure, that this is bug in BCEL.
>
>  Here is code from LDC_W:
>  protected void initFromFile(ByteSequence bytes, boolean wide)
>       throws IOException
>  {
>    setIndex(bytes.readUnsignedShort());
>    // Override just in case it has been changed
>    opcode = org.apache.bcel.Constants.LDC_W;
>  }
>  As you can see, it forces instruction code to LDC_W.
>
>  And here is code from LDC:
>  public final void setIndex(int index) {
>    super.setIndex(index);
>    setSize();
>  }
>  protected final void setSize() {
>    if(index <= org.apache.bcel.Constants.MAX_BYTE) { // Fits in one byte?
>      opcode = org.apache.bcel.Constants.LDC;
>      length = 2;
>    } else {
>      opcode = org.apache.bcel.Constants.LDC_W;
>      length = 3;
>    }
>  }
>
>  I.e. setSize() changes inscruction code and length. Then, length
>used in dump() to detect, that byte or short argument is needed:
>  public void dump(DataOutputStream out) throws IOException {
>    out.writeByte(opcode);
>    if(length == 2)
>      out.writeByte(index);
>    else // Applies for LDC_W
>      out.writeShort(index);
>  }
>
>  But we have (in my case) length == 2, i.e. one byte and LDC_W
>instruction! So, when it tryies to create String for this instruction,
>it reads one random byte (in reallity next instruction)!
>
>  When I change dump() to this code, I receive no exceptions.
>
>  public void dump(DataOutputStream out) throws IOException {
>    out.writeByte(opcode);
>    if(opcode == org.apache.bcel.Constants.LDC)
>      out.writeByte(index);
>    else // Applies for LDC_W
>      out.writeShort(index);
>  }
>
>  
>
>SK> The code you sent is OK, at least for BCEL 5.0 and 5.1 (I have 
>SK> experience with those). The problem is elsewere.
>SK> Btw, did you checked if your original (not instrumented) classes are 
>SK> acceptible? It is so stupid mistake, that you have to be genious to 
>SK> avoid it, at least I can not :))).
>SK> Beside this: if you copy method from one class to another (i do not what 
>SK> are your real application), you must change the constant pool indices of 
>SK> the instructions.
>
>SK> Konstantin Scheglov wrote:
>
>  
>
>>> I use following code to instrument one class.
>>> But when I instrument some classes and try to print debug
>>>information, I receive following exception.
>>>
>>>org.apache.bcel.classfile.ClassFormatException: Invalid constant pool reference: 28088. Constant pool size is: 1024
>>>       at org.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:242)
>>>       at org.apache.bcel.classfile.Utility.codeToString(Utility.java:369)
>>>       at org.apache.bcel.classfile.Utility.codeToString(Utility.java:166)
>>>       at org.apache.bcel.classfile.Code.toString(Code.java:326)
>>>       at org.apache.bcel.classfile.Code.toString(Code.java:352)
>>>       at java.lang.String.valueOf(String.java:2131)
>>>       at java.io.PrintStream.print(PrintStream.java:462)
>>>       at java.io.PrintStream.println(PrintStream.java:599)
>>>       at ru.nlmk.eclipse.plugins.profiler.trace.Trace.instrumentClass(Trace.java:1190)
>>>       at ru.nlmk.eclipse.plugins.profiler.trace.test.TestBCEL.main(TestBCEL.java:23)
>>>
>>>
>>>As you can see, I just copy code from one method to another (in real application
>>>I change code a little). And when I try to load this class in real application
>>>I receive exception like this from JVM:  "VerifyError: Illegal constant pool index".
>>>
>>>
>>>       public static JavaClass instrumentClass(JavaClass clazz) throws Exception {
>>>               ClassGen classGen = new ClassGen(clazz);
>>>               ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
>>>               classGen.setConstantPool(cp);
>>>               //
>>>               for (int i = 0; i < clazz.getMethods().length; i++) {
>>>                       Method method = clazz.getMethods()[i];
>>>                       if (method.isAbstract() || method.isNative())
>>>                               continue;
>>>                       if (method.getName().equals("finalize"))
>>>                               continue;
>>>                       MethodGen mg = new MethodGen(method, clazz.getClassName(), cp);
>>>                       mg.setConstantPool(cp);
>>>                       Method newMethod = mg.getMethod();
>>>                       if (m_Debug) {
>>>                               System.out.println(method.getCode());
>>>                               System.out.println(newMethod.getCode());
>>>                       }
>>>                       classGen.replaceMethod(method, newMethod);
>>>               }
>>>               //
>>>               JavaClass newClazz = classGen.getJavaClass();
>>>               newClazz.setConstantPool(cp.getFinalConstantPool());
>>>               return newClazz;
>>>       }
>>>
>>> What I do wrong?
>>> I see such exception only on few classes (methods).
>>> I have example of such class.
>>>       
>>>
>>> 
>>>
>>>      
>>>
>
>
>
>SK> ---------------------------------------------------------------------
>SK> To unsubscribe, e-mail: bcel-user-unsubscribe@jakarta.apache.org
>SK> For additional commands, e-mail: bcel-user-help@jakarta.apache.org
>
>
>
>  
>


Re[2]: Invalid constant pool reference: 28088. Constant pool size is: 1024

Posted by Konstantin Scheglov <sc...@nlmk.ru>.
Hello Stephen,

Wednesday, June 11, 2003, 7:11:16 PM, you wrote:

  Ok, now I am sure, that this is bug in BCEL.

  Here is code from LDC_W:
  protected void initFromFile(ByteSequence bytes, boolean wide)
       throws IOException
  {
    setIndex(bytes.readUnsignedShort());
    // Override just in case it has been changed
    opcode = org.apache.bcel.Constants.LDC_W;
  }
  As you can see, it forces instruction code to LDC_W.

  And here is code from LDC:
  public final void setIndex(int index) {
    super.setIndex(index);
    setSize();
  }
  protected final void setSize() {
    if(index <= org.apache.bcel.Constants.MAX_BYTE) { // Fits in one byte?
      opcode = org.apache.bcel.Constants.LDC;
      length = 2;
    } else {
      opcode = org.apache.bcel.Constants.LDC_W;
      length = 3;
    }
  }

  I.e. setSize() changes inscruction code and length. Then, length
used in dump() to detect, that byte or short argument is needed:
  public void dump(DataOutputStream out) throws IOException {
    out.writeByte(opcode);
    if(length == 2)
      out.writeByte(index);
    else // Applies for LDC_W
      out.writeShort(index);
  }

  But we have (in my case) length == 2, i.e. one byte and LDC_W
instruction! So, when it tryies to create String for this instruction,
it reads one random byte (in reallity next instruction)!

  When I change dump() to this code, I receive no exceptions.

  public void dump(DataOutputStream out) throws IOException {
    out.writeByte(opcode);
    if(opcode == org.apache.bcel.Constants.LDC)
      out.writeByte(index);
    else // Applies for LDC_W
      out.writeShort(index);
  }

  

SK> The code you sent is OK, at least for BCEL 5.0 and 5.1 (I have 
SK> experience with those). The problem is elsewere.
SK> Btw, did you checked if your original (not instrumented) classes are 
SK> acceptible? It is so stupid mistake, that you have to be genious to 
SK> avoid it, at least I can not :))).
SK> Beside this: if you copy method from one class to another (i do not what 
SK> are your real application), you must change the constant pool indices of 
SK> the instructions.

SK> Konstantin Scheglov wrote:

>>  I use following code to instrument one class.
>>  But when I instrument some classes and try to print debug
>>information, I receive following exception.
>>
>>org.apache.bcel.classfile.ClassFormatException: Invalid constant pool reference: 28088. Constant pool size is: 1024
>>        at org.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:242)
>>        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:369)
>>        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:166)
>>        at org.apache.bcel.classfile.Code.toString(Code.java:326)
>>        at org.apache.bcel.classfile.Code.toString(Code.java:352)
>>        at java.lang.String.valueOf(String.java:2131)
>>        at java.io.PrintStream.print(PrintStream.java:462)
>>        at java.io.PrintStream.println(PrintStream.java:599)
>>        at ru.nlmk.eclipse.plugins.profiler.trace.Trace.instrumentClass(Trace.java:1190)
>>        at ru.nlmk.eclipse.plugins.profiler.trace.test.TestBCEL.main(TestBCEL.java:23)
>>
>>
>> As you can see, I just copy code from one method to another (in real application
>>I change code a little). And when I try to load this class in real application
>>I receive exception like this from JVM:  "VerifyError: Illegal constant pool index".
>>
>>
>>        public static JavaClass instrumentClass(JavaClass clazz) throws Exception {
>>                ClassGen classGen = new ClassGen(clazz);
>>                ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
>>                classGen.setConstantPool(cp);
>>                //
>>                for (int i = 0; i < clazz.getMethods().length; i++) {
>>                        Method method = clazz.getMethods()[i];
>>                        if (method.isAbstract() || method.isNative())
>>                                continue;
>>                        if (method.getName().equals("finalize"))
>>                                continue;
>>                        MethodGen mg = new MethodGen(method, clazz.getClassName(), cp);
>>                        mg.setConstantPool(cp);
>>                        Method newMethod = mg.getMethod();
>>                        if (m_Debug) {
>>                                System.out.println(method.getCode());
>>                                System.out.println(newMethod.getCode());
>>                        }
>>                        classGen.replaceMethod(method, newMethod);
>>                }
>>                //
>>                JavaClass newClazz = classGen.getJavaClass();
>>                newClazz.setConstantPool(cp.getFinalConstantPool());
>>                return newClazz;
>>        }
>>
>>  What I do wrong?
>>  I see such exception only on few classes (methods).
>>  I have example of such class.
>>        
>>
>>  
>>



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



-- 
Best regards,
 Konstantin                            mailto:scheglov_ke@nlmk.ru


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


Re[2]: Invalid constant pool reference: 28088. Constant pool size is: 1024

Posted by Konstantin Scheglov <sc...@nlmk.ru>.
Hello Stephen,

Wednesday, June 11, 2003, 7:11:16 PM, you wrote:

SK> The code you sent is OK, at least for BCEL 5.0 and 5.1 (I have 
SK> experience with those). The problem is elsewere.
  I also used 5.0 and when saw exception switched to 5.1, but
exception is still here. :-(

SK> Btw, did you checked if your original (not instrumented) classes are 
SK> acceptible? It is so stupid mistake, that you have to be genious to 
SK> avoid it, at least I can not :))).
  I tryied to post UUE with original class, but it seems, that UUE are
not accepted by mail list.
  I am not sure, but I think, that original class itself is generated
directly in bytecode. It is EJB skeleton, generated by WebLogic. I
write profiler for Eclipse, it can handle almost all classes except
such already generated classes from WebLogic and CGLIB. For CGLIB I
don't have example, but for WebLogic I do.
  I do try to check with _original_ class. And this exception ("Invalid
constant pool reference: 28088. Constant pool size is: 1024") appears
with it! I.e. I just load this class and create copy of each method
using MethodGen. I don't change code. Just copy, as you can see in
code. And even in this case I receive such exception. :-(

SK> Beside this: if you copy method from one class to another (i do not what 
SK> are your real application), you must change the constant pool indices of 
SK> the instructions.
  In my test code I just copy code. Do I still need to make these
changes? Can you give me example?


SK> Konstantin Scheglov wrote:

>>  I use following code to instrument one class.
>>  But when I instrument some classes and try to print debug
>>information, I receive following exception.
>>
>>org.apache.bcel.classfile.ClassFormatException: Invalid constant pool reference: 28088. Constant pool size is: 1024
>>        at org.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:242)
>>        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:369)
>>        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:166)
>>        at org.apache.bcel.classfile.Code.toString(Code.java:326)
>>        at org.apache.bcel.classfile.Code.toString(Code.java:352)
>>        at java.lang.String.valueOf(String.java:2131)
>>        at java.io.PrintStream.print(PrintStream.java:462)
>>        at java.io.PrintStream.println(PrintStream.java:599)
>>        at ru.nlmk.eclipse.plugins.profiler.trace.Trace.instrumentClass(Trace.java:1190)
>>        at ru.nlmk.eclipse.plugins.profiler.trace.test.TestBCEL.main(TestBCEL.java:23)
>>
>>
>> As you can see, I just copy code from one method to another (in real application
>>I change code a little). And when I try to load this class in real application
>>I receive exception like this from JVM:  "VerifyError: Illegal constant pool index".
>>
>>
>>        public static JavaClass instrumentClass(JavaClass clazz) throws Exception {
>>                ClassGen classGen = new ClassGen(clazz);
>>                ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
>>                classGen.setConstantPool(cp);
>>                //
>>                for (int i = 0; i < clazz.getMethods().length; i++) {
>>                        Method method = clazz.getMethods()[i];
>>                        if (method.isAbstract() || method.isNative())
>>                                continue;
>>                        if (method.getName().equals("finalize"))
>>                                continue;
>>                        MethodGen mg = new MethodGen(method, clazz.getClassName(), cp);
>>                        mg.setConstantPool(cp);
>>                        Method newMethod = mg.getMethod();
>>                        if (m_Debug) {
>>                                System.out.println(method.getCode());
>>                                System.out.println(newMethod.getCode());
>>                        }
>>                        classGen.replaceMethod(method, newMethod);
>>                }
>>                //
>>                JavaClass newClazz = classGen.getJavaClass();
>>                newClazz.setConstantPool(cp.getFinalConstantPool());
>>                return newClazz;
>>        }
>>
>>  What I do wrong?
>>  I see such exception only on few classes (methods).
>>  I have example of such class.
>>        
>>
>>  
>>



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



-- 
Best regards,
 Konstantin                            mailto:scheglov_ke@nlmk.ru


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


Re: Invalid constant pool reference: 28088. Constant pool size is: 1024

Posted by Stephen Kolaroff <ch...@riflexo.com>.
The code you sent is OK, at least for BCEL 5.0 and 5.1 (I have 
experience with those). The problem is elsewere.
Btw, did you checked if your original (not instrumented) classes are 
acceptible? It is so stupid mistake, that you have to be genious to 
avoid it, at least I can not :))).
Beside this: if you copy method from one class to another (i do not what 
are your real application), you must change the constant pool indices of 
the instructions.

Konstantin Scheglov wrote:

>  I use following code to instrument one class.
>  But when I instrument some classes and try to print debug
>information, I receive following exception.
>
>org.apache.bcel.classfile.ClassFormatException: Invalid constant pool reference: 28088. Constant pool size is: 1024
>        at org.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:242)
>        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:369)
>        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:166)
>        at org.apache.bcel.classfile.Code.toString(Code.java:326)
>        at org.apache.bcel.classfile.Code.toString(Code.java:352)
>        at java.lang.String.valueOf(String.java:2131)
>        at java.io.PrintStream.print(PrintStream.java:462)
>        at java.io.PrintStream.println(PrintStream.java:599)
>        at ru.nlmk.eclipse.plugins.profiler.trace.Trace.instrumentClass(Trace.java:1190)
>        at ru.nlmk.eclipse.plugins.profiler.trace.test.TestBCEL.main(TestBCEL.java:23)
>
>
> As you can see, I just copy code from one method to another (in real application
>I change code a little). And when I try to load this class in real application
>I receive exception like this from JVM:  "VerifyError: Illegal constant pool index".
>
>
>        public static JavaClass instrumentClass(JavaClass clazz) throws Exception {
>                ClassGen classGen = new ClassGen(clazz);
>                ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
>                classGen.setConstantPool(cp);
>                //
>                for (int i = 0; i < clazz.getMethods().length; i++) {
>                        Method method = clazz.getMethods()[i];
>                        if (method.isAbstract() || method.isNative())
>                                continue;
>                        if (method.getName().equals("finalize"))
>                                continue;
>                        MethodGen mg = new MethodGen(method, clazz.getClassName(), cp);
>                        mg.setConstantPool(cp);
>                        Method newMethod = mg.getMethod();
>                        if (m_Debug) {
>                                System.out.println(method.getCode());
>                                System.out.println(newMethod.getCode());
>                        }
>                        classGen.replaceMethod(method, newMethod);
>                }
>                //
>                JavaClass newClazz = classGen.getJavaClass();
>                newClazz.setConstantPool(cp.getFinalConstantPool());
>                return newClazz;
>        }
>
>  What I do wrong?
>  I see such exception only on few classes (methods).
>  I have example of such class.
>        
>
>  
>



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


Re[2]: Invalid constant pool reference: 28088. Constant pool size is: 1024

Posted by Konstantin Scheglov <sc...@nlmk.ru>.
Hello Simon,

Wednesday, June 11, 2003, 6:52:25 PM, you wrote:

SB> I'm no BCEL guru, but I used it for a while a few weeks back, so maybe I
SB> can help you.
  Would be great. :-)

SB> I think the problem must come from the few operations you says you do, 
SB> but that don't show up on the listing you sent ... Maybe you could send 
SB> the whole thing.
  No, problem appears even when I don't modify method. I.e. when I use
code in initial mail.

SB> Maybe one thing, I think you need to call classGen.update() once you 
SB> changed the method ... But I don't think this will be the cause of your 
SB> problem.
  Yes, just tryed - still same exception.

  Here is archive with class. Name of class is broken, but I don't
think, that this is reason of exception.

section 1 of uuencode 5.25 of file clazz.zip    by R.E.M.

sum -r/size 64782/3098 section (from "begin" to "end")
sum -r/size 25249/2228 entire input file


SB> Simon.

SB> Konstantin Scheglov wrote:

>>  I use following code to instrument one class.
>>  But when I instrument some classes and try to print debug
>>information, I receive following exception.
>>
>>org.apache.bcel.classfile.ClassFormatException: Invalid constant pool reference: 28088. Constant pool size is: 1024
>>        at org.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:242)
>>        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:369)
>>        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:166)
>>        at org.apache.bcel.classfile.Code.toString(Code.java:326)
>>        at org.apache.bcel.classfile.Code.toString(Code.java:352)
>>        at java.lang.String.valueOf(String.java:2131)
>>        at java.io.PrintStream.print(PrintStream.java:462)
>>        at java.io.PrintStream.println(PrintStream.java:599)
>>        at ru.nlmk.eclipse.plugins.profiler.trace.Trace.instrumentClass(Trace.java:1190)
>>        at ru.nlmk.eclipse.plugins.profiler.trace.test.TestBCEL.main(TestBCEL.java:23)
>>
>>
>> As you can see, I just copy code from one method to another (in real application
>>I change code a little). And when I try to load this class in real application
>>I receive exception like this from JVM:  "VerifyError: Illegal constant pool index".
>>
>>
>>        public static JavaClass instrumentClass(JavaClass clazz) throws Exception {
>>                ClassGen classGen = new ClassGen(clazz);
>>                ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
>>                classGen.setConstantPool(cp);
>>                //
>>                for (int i = 0; i < clazz.getMethods().length; i++) {
>>                        Method method = clazz.getMethods()[i];
>>                        if (method.isAbstract() || method.isNative())
>>                                continue;
>>                        if (method.getName().equals("finalize"))
>>                                continue;
>>                        MethodGen mg = new MethodGen(method, clazz.getClassName(), cp);
>>                        mg.setConstantPool(cp);
>>                        Method newMethod = mg.getMethod();
>>                        if (m_Debug) {
>>                                System.out.println(method.getCode());
>>                                System.out.println(newMethod.getCode());
>>                        }
>>                        classGen.replaceMethod(method, newMethod);
>>                }
>>                //
>>                JavaClass newClazz = classGen.getJavaClass();
>>                newClazz.setConstantPool(cp.getFinalConstantPool());
>>                return newClazz;
>>        }
>>
>>  What I do wrong?
>>  I see such exception only on few classes (methods).
>>  I have example of such class.
>>        
>>
>>  
>>


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



-- 
Best regards,
 Konstantin                            mailto:scheglov_ke@nlmk.ru


Re: Invalid constant pool reference: 28088. Constant pool size is: 1024

Posted by Simon Bretin <si...@anyware-tech.com>.
Hi,

I'm no BCEL guru, but I used it for a while a few weeks back, so maybe I 
can help you.

I think the problem must come from the few operations you says you do, 
but that don't show up on the listing you sent ... Maybe you could send 
the whole thing.

Maybe one thing, I think you need to call classGen.update() once you 
changed the method ... But I don't think this will be the cause of your 
problem.

Simon.

Konstantin Scheglov wrote:

>  I use following code to instrument one class.
>  But when I instrument some classes and try to print debug
>information, I receive following exception.
>
>org.apache.bcel.classfile.ClassFormatException: Invalid constant pool reference: 28088. Constant pool size is: 1024
>        at org.apache.bcel.classfile.ConstantPool.getConstant(ConstantPool.java:242)
>        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:369)
>        at org.apache.bcel.classfile.Utility.codeToString(Utility.java:166)
>        at org.apache.bcel.classfile.Code.toString(Code.java:326)
>        at org.apache.bcel.classfile.Code.toString(Code.java:352)
>        at java.lang.String.valueOf(String.java:2131)
>        at java.io.PrintStream.print(PrintStream.java:462)
>        at java.io.PrintStream.println(PrintStream.java:599)
>        at ru.nlmk.eclipse.plugins.profiler.trace.Trace.instrumentClass(Trace.java:1190)
>        at ru.nlmk.eclipse.plugins.profiler.trace.test.TestBCEL.main(TestBCEL.java:23)
>
>
> As you can see, I just copy code from one method to another (in real application
>I change code a little). And when I try to load this class in real application
>I receive exception like this from JVM:  "VerifyError: Illegal constant pool index".
>
>
>        public static JavaClass instrumentClass(JavaClass clazz) throws Exception {
>                ClassGen classGen = new ClassGen(clazz);
>                ConstantPoolGen cp = new ConstantPoolGen(clazz.getConstantPool());
>                classGen.setConstantPool(cp);
>                //
>                for (int i = 0; i < clazz.getMethods().length; i++) {
>                        Method method = clazz.getMethods()[i];
>                        if (method.isAbstract() || method.isNative())
>                                continue;
>                        if (method.getName().equals("finalize"))
>                                continue;
>                        MethodGen mg = new MethodGen(method, clazz.getClassName(), cp);
>                        mg.setConstantPool(cp);
>                        Method newMethod = mg.getMethod();
>                        if (m_Debug) {
>                                System.out.println(method.getCode());
>                                System.out.println(newMethod.getCode());
>                        }
>                        classGen.replaceMethod(method, newMethod);
>                }
>                //
>                JavaClass newClazz = classGen.getJavaClass();
>                newClazz.setConstantPool(cp.getFinalConstantPool());
>                return newClazz;
>        }
>
>  What I do wrong?
>  I see such exception only on few classes (methods).
>  I have example of such class.
>        
>
>  
>


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