Java代理:未为所有类调用transform()
我有一个非常简单的变压器:Java代理:未为所有类调用transform(),transform,instrumentation,Transform,Instrumentation,我有一个非常简单的变压器: import java.io.ByteArrayInputStream; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.security.ProtectionDomain; import javassist.ClassPool; import javassist.CtClass
import java.io.ByteArrayInputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
//this class will be registered with instrumentation agent
public class PizzaTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader,
String className,
Class classBeingRedefined,
ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws
IllegalClassFormatException {
byte[] byteCode = classfileBuffer;
System.out.println("This class is "+className);
return byteCode;
}
}
代理代码如下:
import java.lang.instrument.Instrumentation;
public class PizzaAgent {
public static void premain(String agentArgs, Instrumentation inst) {
System.out.println("Executing premain.........");
inst.addTransformer(new PizzaTransformer(),true);
}
}
舱单是:
引导类路径:javassist.jar
课程名称:披萨代理
可以重新定义类:true
可以重新转换类:true
令人费解的是,transform()只打印了4000多个类,而通过在命令行启动时打开-verbose:class,报告加载了19000多个类
为什么超过10000个类没有调用transform()
谢谢您只看到在连接代理时尚未加载的类。如果您也想处理加载的类,那么必须显式地重新转换这些类。您可以通过以下方式进行:
instrumentation.retransformClasses(instrumentation.getLoadedClasses());
但是,有些类是不可重传的(
Instrumentation::isModifiable
),您很可能需要拆分数组以避免耗尽内存。可能有两种情况
谢谢你的回答。但是,由于我使用的是premain方式,所以在加载任何类之前,代理不是已经添加了吗?Aka,我希望在附加代理时不会加载任何类。谢谢您的回答。但是,由于我使用的是premain方式,所以在加载任何类之前,代理不是已经添加了吗?Aka,我希望在连接代理时不会加载任何类。虽然我知道有些类是不可重构的,但应用程序类不应该是可重构的吗。在任何情况下,我都希望19000多个类都能调用transformer,这样我就可以用Instrumentation::isModifiable检查它。您的代理是用Java编写的,因此需要先加载它的类和许多系统类。是的!你是对的。有些类(如系统类)需要在代理之前加载,这是有意义的。我仍然没有看到一些应用程序类没有调用transformer。关于为什么会这样,你有什么建议吗?谢谢JVM加载类的子集,如真正需要的对象或线程。其他的,比如HttpUrlConnection,是惰性加载的。