我正在使用ASM 5.0.3和Websphere 8.5.x以及IDM JDK 1.7来使用 org.objectweb.asm.commons.AdviceAdapter
分析方法执行时间Oracle JDBC驱动程序 ojdbc7.jar 用于创建JDBC。我的应用程序工作正常,没有添加-javaagent参数。
当修改字节码时(通过-javaagent),Websphere启动正常但在访问应用程序时会抛出 java.lang.NoClassDefFoundError:oracle / security / pki / OraclePKIProvider 。
我找到了一个链接,详细解释了这个问题。显示某些JVM /驱动程序版本组合发生NoClassDefFoundError
https://plumbr.eu/blog/java/troubleshooting-verifiers-the-rabbit-hole-goes-deep
An exception occurred while invoking method setDataSourceProperties on com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl used by resource jdbc/appDatasource : java.lang.NoClassDefFoundError: oracle/security/pki/OraclePKIProvider
at oracle.jdbc.pool.OracleDataSource.<clinit>(OracleDataSource.java:103)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:383)
at com.ibm.ws.rsadapter.DSConfigHelper.createDataSource(DSConfigHelper.java:747)
at com.ibm.ws.rsadapter.spi.WSRdbDataSource.createNewDataSource(WSRdbDataSource.java:3029)
at com.ibm.ws.rsadapter.spi.WSRdbDataSource.<init>(WSRdbDataSource.java:1358)
at com.ibm.ws.rsadapter.spi.WSManagedConnectionFactoryImpl.setDataSourceProperties(WSManagedConnectionFactoryImpl.java:2653)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
......
确保如果标签访问最初是框架访问,我们会在框架访问后插入我们的说明,而不是框架和标签之间。
有人可以解释&#34;如何使用ASM字节码实现这一点?&#34;
package com.abc.agent.adapter;
import com.abc.jm.TMConstants;
import com.abc.jm.TMLog;
import com.abc.org.objectweb.asm.Label;
import com.abc.org.objectweb.asm.MethodVisitor;
import com.abc.org.objectweb.asm.Opcodes;
import com.abc.org.objectweb.asm.Type;
import com.abc.org.objectweb.asm.commons.AdviceAdapter;
public class DriverMethodAdviceAdapter extends AdviceAdapter {
private String methodName;
private String className;
private String description;
private boolean isConnectMethod;
private static final String INTERFACE_DRIVER_CONNECT_METHOD_DESC = "(Ljava/lang/String;Ljava/util/Properties;)Ljava/sql/Connection;";
private int okFlag = newLocal(Type.BOOLEAN_TYPE);
Label startFinally = new Label();
public DriverMethodAdviceAdapter(int access , MethodVisitor mv , String methodName, String description, String className, int classFileVersion){
super(Opcodes.ASM5, mv, access, methodName, description);
this.className = className;
this.methodName = methodName;
this.description = description;
this.isConnectMethod = false;
if(methodName.equals("connect") && description.equals(INTERFACE_DRIVER_CONNECT_METHOD_DESC)){
isConnectMethod = true;
}
}
public void visitCode() {
super.visitCode();
mv.visitLabel(startFinally);
}
protected void onMethodEnter(){
if(isConnectMethod){
mv.visitInsn(Opcodes.ICONST_0);
mv.visitVarInsn(ISTORE, okFlag);
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitLdcInsn(description);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/abc/agent/trace/Tracer", "jdbcConnectionMethodBegin", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z", false);
mv.visitVarInsn(ISTORE, okFlag);
}
}
protected void onMethodExit(int opcode){
if(opcode!=ATHROW) {
onFinally(opcode);
}
}
public void visitMaxs(int maxStack, int maxLocals){
Label endFinally = new Label();
mv.visitTryCatchBlock(startFinally, endFinally, endFinally, null);
mv.visitLabel(endFinally);
onFinally(ATHROW);
mv.visitInsn(ATHROW);
mv.visitMaxs(maxStack+4, maxLocals);
}
private void onFinally(int opcode){
if(isConnectMethod){
mv.visitInsn(Opcodes.DUP); // This is return object
mv.visitLdcInsn(className);
mv.visitLdcInsn(methodName);
mv.visitLdcInsn(description);
mv.visitVarInsn(ILOAD, okFlag);
mv.visitLdcInsn(opcode);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "com/abc/agent/trace/Tracer", "jdbcConnectionMethodEnd", "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZI)V", false);
}
}
}
我正在使用标志 ClassWriter.COMPUTE_FRAMES 用于ClassWriter和 ClassReader.EXPAND_FRAMES | ClasseReader.accept()的ClassReader.SKIP_FRAMES 。