如何让Java代理和反射一起工作?
How to make Java agent and reflection work together?
我有一个项目 (https://github.com/zhihan/janala2-gradle) 使用 java-agent 进行在线检测。我试图为 运行 时间反射添加注释 class。程序因 NoClassDefFoundError
而崩溃
Exception in thread "main" java.lang.NoClassDefFoundError: janala/logger/DJVM
at com.sun.proxy.$Proxy0.<clinit>(Unknown Source)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:739)
at sun.reflect.annotation.AnnotationParser.run(AnnotationParser.java:305)
at sun.reflect.annotation.AnnotationParser.run(AnnotationParser.java:303)
at java.security.AccessController.doPrivileged(Native Method)
at sun.reflect.annotation.AnnotationParser.annotationForMap(AnnotationParser.java:303)
at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:293)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
at sun.reflect.annotation.AnnotationParser.parseSelectAnnotations(AnnotationParser.java:101)
at sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:139)
at sun.reflect.annotation.AnnotationType.getInstance(AnnotationType.java:85)
at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:266)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
at java.lang.reflect.Executable.declaredAnnotations(Executable.java:546)
at java.lang.reflect.Executable.getAnnotation(Executable.java:520)
at java.lang.reflect.Method.getAnnotation(Method.java:607)
at janala.utils.ClassRunner.run(ClassRunner.java:20)
at janala.utils.ClassRunner.main(ClassRunner.java:33)
错误的调用点很简单
Test annotation = method.getAnnotation(Test.class);
如果我将程序更改为首先检测 class,将检测后的 class 写入 .class 文件,然后 运行 使用相同 class路径。那么运行就可以了。
注解声明为
public class Annotations {
/**
* A CATG test.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {}
}
而注解的使用就好
@Test
public void testAnd() {
好吧,原来原因在堆栈跟踪中
at com.sun.proxy.$Proxy0.<clinit>(Unknown Source)
代理 class 由 JVM 自动生成,作为反射支持的一部分。默认情况下,检测器将检测所有内容。过滤此包即可解决问题。
我有一个项目 (https://github.com/zhihan/janala2-gradle) 使用 java-agent 进行在线检测。我试图为 运行 时间反射添加注释 class。程序因 NoClassDefFoundError
而崩溃Exception in thread "main" java.lang.NoClassDefFoundError: janala/logger/DJVM
at com.sun.proxy.$Proxy0.<clinit>(Unknown Source)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:739)
at sun.reflect.annotation.AnnotationParser.run(AnnotationParser.java:305)
at sun.reflect.annotation.AnnotationParser.run(AnnotationParser.java:303)
at java.security.AccessController.doPrivileged(Native Method)
at sun.reflect.annotation.AnnotationParser.annotationForMap(AnnotationParser.java:303)
at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:293)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
at sun.reflect.annotation.AnnotationParser.parseSelectAnnotations(AnnotationParser.java:101)
at sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:139)
at sun.reflect.annotation.AnnotationType.getInstance(AnnotationType.java:85)
at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:266)
at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120)
at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72)
at java.lang.reflect.Executable.declaredAnnotations(Executable.java:546)
at java.lang.reflect.Executable.getAnnotation(Executable.java:520)
at java.lang.reflect.Method.getAnnotation(Method.java:607)
at janala.utils.ClassRunner.run(ClassRunner.java:20)
at janala.utils.ClassRunner.main(ClassRunner.java:33)
错误的调用点很简单
Test annotation = method.getAnnotation(Test.class);
如果我将程序更改为首先检测 class,将检测后的 class 写入 .class 文件,然后 运行 使用相同 class路径。那么运行就可以了。
注解声明为
public class Annotations {
/**
* A CATG test.
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {}
}
而注解的使用就好
@Test
public void testAnd() {
好吧,原来原因在堆栈跟踪中
at com.sun.proxy.$Proxy0.<clinit>(Unknown Source)
代理 class 由 JVM 自动生成,作为反射支持的一部分。默认情况下,检测器将检测所有内容。过滤此包即可解决问题。