Javaagent应用程序类未连接到transformer
我正在通过 premain(管柱代理、仪器仪表) 方法,我很好奇为什么ClassFileTransformer不考虑类 简短描述:Javaagent应用程序类未连接到transformer,java,javassist,javaagents,Java,Javassist,Javaagents,我正在通过 premain(管柱代理、仪器仪表) 方法,我很好奇为什么ClassFileTransformer不考虑类 简短描述: 在我的项目中,有两个类应用了javaagent(premain) MyMainClass是具有main方法的类 MyLogicReference类不是通过导入的引用。。。在我的课堂上 ClassFileTransformer转换方法仅为MyMainClass调用,而不为MyLogiCreefence调用 如果我调用java.lang.instrument.Inst
- 在我的项目中,有两个类应用了javaagent(premain)
- MyMainClass是具有main方法的类
- MyLogicReference类不是通过导入的引用。。。在我的课堂上
- ClassFileTransformer转换方法仅为MyMainClass调用,而不为MyLogiCreefence调用
- 如果我调用java.lang.instrument.Instrumentation GetAllLoadedClass,那么我可以看到MyLogicReference类已加载
- ?这是代理的工作方式吗?如果是,如何让代理同时转换第二个(MyLogiCreefence)类?
public class MyMainClass {
... //Main method and call of myMethod();
@MyAnnotationToApplyLogic
public void myMethod(){
//Some code here
}
我更改代码的过程的入口点是我引用另一个类(MyLogicReference)的注释
如果我使用
java.lang.instrument.Instrumentation getAllLoadedClasses方法
我可以看到MyLogicReference类。但是这个类永远不会调用ClassFileTransformer。这对JavaAgent正确吗
例如,如果我在MyMain类中导入MyLogiReference.class,我就知道调用了transformer
所以我目前的假设是,只有
在主类上直接引用的将被发送到
ClassFileTransformer。如果这是正确的,我如何强制
javaagent转换一个以前没有转换过的类
我的javaaagent清单条目(MVN):
com.MyTestAgent
com.MyTestAgent
真的
真的
我将ClassFileTransformer剥离到这个,第二个类仍然没有加载:
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if (!className.startsWith("java/") && !className.startsWith("javax/") && !className.startsWith("sun/")) {
log("NOW PROCESSING: " + className);
return classfileBuffer;
}
return null;
}
//Output:
//NOW PROCESSING: MyMainClass
@覆盖
公共字节[]转换(类加载器加载器、字符串类名、类正在重新定义、ProtectionDomain ProtectionDomain、字节[]类文件缓冲区)引发IllegalClassFormatException{
如果(!className.startsWith(“java/”)&&!className.startsWith(“javax/”&&!className.startsWith(“sun/”)){
日志(“正在处理:“+className”);
返回类文件缓冲区;
}
返回null;
}
//输出:
//现在正在处理:MyMainClass
根据您所说的,我猜您指的是javaagent代码中的某个地方。因此,JVM在检测开始之前加载该类。要记住两件事:
- 将javaagent使用的代码与正在检测的代码分开
- 仅将MyLogicReference作为字符串引用,例如使用
而不是MyLogicReference的foo.getClass().getName().equals(“MyLogicReference”)
foo实例
根据提供的信息,我还想知道您是否考虑改用Annotation Processor()。谢谢您的回答。我已经看过注释处理器(没有详细介绍)。当涉及到修改代码和不构建代理类时,我更喜欢anno之前的代理。有黑客的处理器(如loombok)。此外,代理的速度也适用于我的用例(例如远程JMX…)。另一方面,对于注释驱动的操作,procesor很好(带有编译消息,…)。作为这些主题的新手,对于我来说,使用转换方法的注释处理器将是非常棒的:D
<Premain-Class>com.MyTestAgent</Premain-Class>
<Agent-Class>com.MyTestAgent</Agent-Class>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
@Override
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
if (!className.startsWith("java/") && !className.startsWith("javax/") && !className.startsWith("sun/")) {
log("NOW PROCESSING: " + className);
return classfileBuffer;
}
return null;
}
//Output:
//NOW PROCESSING: MyMainClass