The problem is that your jsr's into the finally block occur from places that have a different number of
entries on the stack, and the verifier doesn't support that.
Either don't implement your finally with a jsr (inline the content directly), or clean up your stack prior to
the jsr so it's consistent with the other method exit points.
- Paul
-----Original Message-----
From: Vincent Marquez [mailto:vmarquez <at> totemworks.com]
Sent: Tuesday, December 14, 2004 11:53 AM
To: bcel-user <at> jakarta.apache.org
Subject: Try/Catch Errors
I'm not sure how active the list is, but I'll give it a shot. I'm
having trouble adding bytecode to methods wtih try/catch blocks. I've
been able to modify them correctly without try/catch blocks, but as soon
as I uncomment them, I get the following error:
Exception in thread "main" java.lang.VerifyError: (class: Test, method:
main signature: ([Ljava/lang/String;)V) Inconsistent stack height 0 != 2
I am calling setMaxStack() on the MethodGen instance. I assume there is
some simple trick that i'm missing?
Thanks in advance for any help.
--vince
=======================================================
Hi All, Currently i am planning to instrument each method of a class dynamically with system.out.println() statements. as it is not possible to get it executed, due to the return statements which are available in middle of method, As seen from many sources, implementing it with try and finally is a good idea. finally seems to be more complex to handle compared to catch (atleast to me). however i got the source from internet, i could not understand few things in the source, could some one please clarify me. i have directly put put my understandings and queries in the middle of code IN CAPS, [code is given below, of course not too big]. So please correct me and help me in this regard. Thank you Reddy public void instrumentMethod (ClassGen cg, MethodGen mg) { InstructionList il = mg.getInstructionList(); InstructionFactory ifact = new InstructionFactory(cg); InstructionHandle start = il.getStart(); InstructionHandle end = il.getEnd(); // IN THE FOLLOWING SNIPPET OF CODE, CALL TO SUBROUTINES ARE INSERTED AND ALL THE TARGETS OF RETURN INSTRUCTIONS ARE CHANGED Collection<JSR> jsrs = new ArrayList<JSR>(); for (Iterator i = il.iterator(); i.hasNext(); ) { InstructionHandle ih = (InstructionHandle)i.next(); if (ih.getInstruction() instanceof RETURN) { JSR jsr2 = new JSR(null); jsrs.add(jsr2); InstructionHandle n = il.insert(ih, jsr2); il.redirectBranches(ih, n); } } // END OF ABOVE UNDERSTANDING. AM I CORRECT ?? InstructionHandle h1 = il.append(new ASTORE(0)); // AT THE CURRENT SITUATION, WHAT IS ON THE TOP OF STACK AND WHY IS IT STORED?? JSR jsr = new JSR(null); // WHY A SUBROUTINE CALL IS DONE HERE??? jsrs.add(jsr); il.append(jsr); InstructionHandle h2 = il.append(new ALOAD(0)); // REFLECTS THE ABOVE STORE OPERATION; SO WHAT IS ACTUALLY IN THIS NOW?? il.append(new ATHROW()); // I THINK IT IS TO RETHROW THE EXCEPTION IF AN EXCEPTION ARISES InstructionHandle handler = il.append(new ASTORE(1)); // STORES THE EXCEPTION VARIABLE // I WILL APPEND AN PRINTLN STATEMENT HERE il.append(new RET(1)); // RETURNING FROM SUBROUTINE, BUT DOESNT THE INDEX OF RET START AT 0 for (JSR j : jsrs) { j.setTarget(handler); } mg.addExceptionHandler(start, end, h1, null); // DOESNT THE EXCEPTION HANDLER START AT HANDLE handler(which is just 3 lines above in this code) il.setPositions(true); // IS THIS NECESSARY ?? }
|
http://www.geekyarticles.com/2011/08/manipulating-java-class-files-with-bcel_18.html
总算从两位老外的帖子里面找到答案了,原因就是代码缺少跳转,如果是try,finally注意一下jsr和ret
如果是try catch 注意一下GOTO,我总结的,BCEL还是不熟悉啊,可能还有别的好方法。
用BCEL生成代码一看,反编译的代码一样,但是字节码和高手的差距太大,这充分说明编译器好坏重要性,相当于你自己写了一个编译器,
如果同样的代码,字节码多,肯定效率不是很高,看来还得努力啊。Java水很深啊。