&引用;java.lang.VerifyError“;使用仪器时,添加变压器(变压器,正确);
我想将代理附加到进程并修改vm中的类代码。当我添加transformer并调用RetransformClass时,它抛出&引用;java.lang.VerifyError“;使用仪器时,添加变压器(变压器,正确);,java,Java,我想将代理附加到进程并修改vm中的类代码。当我添加transformer并调用RetransformClass时,它抛出java.lang.VerifyError。代理正在处理中,请在main中调用attach 主要内容: 代理人: public static void attach() throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException, URISyn
java.lang.VerifyError
。代理正在处理中,请在main中调用attach
主要内容:
代理人:
public static void attach() throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException, URISyntaxException {
int processID = getProcessID();
VirtualMachine vm = VirtualMachine.attach(String.valueOf(processID));
String filePath = Agent.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
File file = new File(filePath);
vm.loadAgent(file.getPath());
}
public static int getProcessID() {
RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
return Integer.valueOf(runtimeMXBean.getName().split("@")[0]);
}
public static void agentmain(String agentArgs, Instrumentation instrumentation) throws Throwable {
Agent.instrumentation = instrumentation;
}
public static void premain(String agentArgs, Instrumentation instrumentation) throws Throwable {
Agent.instrumentation = instrumentation;
}
public static void modify(String className) {
Arrays.stream(instrumentation.getAllLoadedClasses()).forEach((aClass) -> {
if (className.equals(aClass.getName())) {
ClassFileTransformer transformer = new ToStringTransformer();
instrumentation.addTransformer(transformer, true);
try {
instrumentation.retransformClasses(new Class[]{aClass});
instrumentation.removeTransformer(transformer);
} catch (UnmodifiableClassException var4) {
var4.printStackTrace();
}
}
});
}
串级变压器
public class ToStringTransformer implements ClassFileTransformer {
public ToStringTransformer() {
}
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
String compareClass = className.replace('/', '.');
System.out.println("transformer..." + compareClass);
if (loader == null) {
return classfileBuffer;
} else {
try {
ClassPool classPool = ClassPool.getDefault();
classPool.appendClassPath(Agent.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath());
CtClass ctClass = classPool.get(compareClass);
CtMethod ctMethod = ctClass.getDeclaredMethod("toString");
ctMethod.setBody("return true;");
ctClass.writeFile();
return ctClass.toBytecode();
} catch (Exception var10) {
var10.printStackTrace();
return new byte[0];
}
}
}
}
在
ToStringTransformer
中,您有以下代码:
CtMethod ctMethod = ctClass.getDeclaredMethod("toString");
ctMethod.setBody("return true;");
ctClass.writeFile();
toString
返回一个字符串
,但在这里,您试图通过返回true使其返回一个布尔值
。当您尝试加载修改后的类时,这将抛出一个VerifyError
,因为堆栈上的返回值(true
)将与toString
方法(String
)的返回值不匹配
transformer...com.tostring.agent.Order
transformer...java.lang.VerifyError Exception in thread "main"
transformer...java.lang.Throwable$WrappedPrintStream
transformer...java.lang.Throwable$PrintStreamOrWriter
transformer...java.util.IdentityHashMap
transformer...java.util.IdentityHashMap$KeySet java.lang.VerifyError
at sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
at sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:144)
at com.tostring.agent.Agent.lambda$modify$0(Agent.java:65)
at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
at com.tostring.agent.Agent.modify(Agent.java:60)
at com.generate.perdicition.PredictionExcel.main(PredictionExcel.java:53)
transformer...java.lang.Shutdown transformer...java.lang.Shutdown$Lock
CtMethod ctMethod = ctClass.getDeclaredMethod("toString");
ctMethod.setBody("return true;");
ctClass.writeFile();