ByteBuddy—在java代理中读取类注释
我试图在用ByteBuddy实现的java代理中应用一些转换之前访问类的注释。 为了访问注释,我试图加载Class对象,但这似乎创建了一个重复的类定义ByteBuddy—在java代理中读取类注释,java,byte-buddy,javaagents,Java,Byte Buddy,Javaagents,我试图在用ByteBuddy实现的java代理中应用一些转换之前访问类的注释。 为了访问注释,我试图加载Class对象,但这似乎创建了一个重复的类定义 import net.bytebuddy.agent.builder.AgentBuilder; import net.bytebuddy.matcher.ElementMatchers; import java.lang.instrument.Instrumentation; public class SimpleTestAgent {
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.matcher.ElementMatchers;
import java.lang.instrument.Instrumentation;
public class SimpleTestAgent {
public static void premain(String arg, Instrumentation inst) {
new AgentBuilder.Default()
.type(ElementMatchers.isAnnotatedWith(SomeAnnotationType.class))
.transform((builder, type, classLoader, javaModule) -> {
try {
Class loadedClass = Class.forName(type.getName(), true, classLoader);
} catch (ClassNotFoundException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return builder;
})
.installOn(inst);
}
}
一个简单类仅创建用预期注释注释的类TestClass的实例,引发以下异常:
线程“main”java.lang.LinkageError中出现异常:加载程序(的实例
sun/misc/Launcher$AppClassLoader):尝试复制类
名称的定义:“TestClass”
我正在尝试实现代理,如中所述的示例:
有没有一种方法可以加载类对象而不引起此问题,或者有没有一种方法可以使用传递给transformation()方法的参数访问注释
转换应该能够实现新的接口,而不仅仅是重写方法。这就是为什么我认为我不能使用“ForAdvice”
更新
以下循环仅在执行Class.forName()后查找TestClass。这意味着该类尚未加载,因此可能不希望使用class.forName来获取注释
for (Class<?> t : inst.getAllLoadedClasses()) {
System.out.println("Class name: " + t.getName());
}
for(类t:inst.getAllLoadedClasses()){
System.out.println(“类名:+t.getName());
}
可以使用传递给transform()方法的net.bytebuddy.description.type.TypeDescription实例获取注释和类的完整信息
问题是,例如,我需要可以使用反射调用的方法对象。如果我能以某种方式访问正在转换的类的类对象,那就容易多了。Byte Buddy已经通过
TypeDescription
API公开了类注释的所有信息,您不应该将类作为在转换过程中加载的类来加载,在应用转换之前加载该类,并使用您观察到的错误中止类加载。相反,实现您自己的匹配器:
.type(type -> check(type.getDeclaredAnnotations().ofType(SomeAnnotation.class).load())
Byte Buddy将在不加载carrier类本身的情况下为您表示注释,而是使用自己的类文件处理器表示注释
在安装代理生成器之前,应确保已加载注释类,以避免此注释的循环性
.type(type -> check(type.getDeclaredAnnotations().ofType(SomeAnnotation.class).load())