Error while instrumenting class files (asm.ClassWr

2020-05-28 10:20发布

问题:

Getting error on instrumentation

java.lang.RuntimeException: java.lang.ClassNotFoundException: Deposit
    at org.objectweb.asm.ClassWriter.getCommonSuperClass(Unknown Source)
    at org.objectweb.asm.ClassWriter.a(Unknown Source)
    at org.objectweb.asm.Frame.a(Unknown Source)
    at org.objectweb.asm.Frame.a(Unknown Source)
    at org.objectweb.asm.MethodWriter.visitMaxs(Unknown Source)
    at com.jConSequence.instrumentor.methodProber.AdddataBaseDetailsInstructions$AdddataBaseDetailsMethodInstructions.visitMaxs(AdddataBaseDetailsInstructions.java:131)
    at org.objectweb.asm.ClassReader.accept(Unknown Source)
    at org.objectweb.asm.ClassReader.accept(Unknown Source)
    at com.jConSequence.instrumentor.PrintLoadedClasses.print(PrintLoadedClasses.java:31)
    at com.jConSequence.tooGUI.RevEnggToolGUI.jButton1ActionPerformed(RevEnggToolGUI.java:487)
    at com.jConSequence.tooGUI.RevEnggToolGUI.access$0(RevEnggToolGUI.java:471)
    at com.jConSequence.tooGUI.RevEnggToolGUI$1.actionPerformed(RevEnggToolGUI.java:127)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$000(Unknown Source)
    at java.awt.EventQueue$1.run(Unknown Source)
    at java.awt.EventQueue$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$2.run(Unknown Source)
    at java.awt.EventQueue$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

while instrumenting classes

D:\workspaces\workspace\bankManagement\bin\Account.class
D:\workspaces\workspace\bankManagement\bin\ATM.class
D:\workspaces\workspace\bankManagement\bin\ATMCaseStudy.class
D:\workspaces\workspace\bankManagement\bin\BalanceInquiry.class
D:\workspaces\workspace\bankManagement\bin\BankDatabase.class
D:\workspaces\workspace\bankManagement\bin\CashDispenser.class
D:\workspaces\workspace\bankManagement\bin\Deposit.class
D:\workspaces\workspace\bankManagement\bin\DepositSlot.class
D:\workspaces\workspace\bankManagement\bin\Keypad.class
D:\workspaces\workspace\bankManagement\bin\Screen.class
D:\workspaces\workspace\bankManagement\bin\Transaction.class

I am reading the above set of classes as byte streams using apache commonsIO.

Then using asm library instrumenting them.

Finally they are converted into class files.

It is at this point of instrumentation I am getting this error Can anybody kindly explain the reason and possible solution.

回答1:

This error is occurring because ASM is generating stack map frames, and for some bytecodes, the stack map frames must contain the common superclass of two classes. By default, ASM implements this by loading classes via Class.forName and then implements the proper algorithm using reflection. Presumably, the ASM library is unable to load your Deposit class from its class loader.

To avoid the error, you'll need to either use SKIP_FRAMES (note: version 51.0 of class file used by Java 7 requires stack map frames, so this is a non-option if you're generating Java 7 bytecode), or you need to subclass ClassWriter and override getCommonSuperClass. Depending on what your code is doing, perhaps you can hard-code the answers using string comparisons, or perhaps you can take the ASM implementation and rewrite it to use a ClassLoader that you specify.