我编写了一个简单的注释和一个AnnotationProcessor来处理注释。
批注具有单个值:它应该是现有接口(带有包)的名称。
注释处理器应该获取注释的值,获取接口的Class对象,最后应该打印接口中声明的所有方法。
例:
这是我的注释
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface MyAnnotation{
public String interfaceName();
}
这是带注释的类:
@MyAnnotation(interfaceName = "java.lang.CharSequence")
public class Example{}
我的处理器看起来像
[...]
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment env) {
for (TypeElement te : annotations) {
for(Element e : env.getElementsAnnotatedWith(te)) {
MyAnnotation myAnnotation = e.getAnnotation(MyAnnotation.class);
String iName = myAnnotation.interfaceName();
Class<?> clazz = Class.forName(iName);
// use reflection to cycle through methods and prints them
[...]
}
}
现在,如果我将java.lang.CharSequence之类的接口配置为MyAnnotation的interfaceName,则此方法可以正常工作;
但是,如果将位于.jar文件中的接口(添加到项目的构建路径中)配置为interfaceName,则在尝试执行Class.forName(...)语句时会收到ClassNotFoundException。
有什么想法吗?
谢谢,
干杯
最佳答案
这是一个典型的ClassLoader问题。您正在尝试查找当前类加载器未加载的类,因此抛出了ClassNotFoundException
。java.lang.Class
的Javadoc将方法Class.forName(className)
定义为:
返回具有给定字符串名称的与类或接口关联的Class对象。调用此方法等效于Class.forName(className, true, currentLoader)
,其中currentLoader表示当前类的定义类加载器。
因此,此方法调用将尝试在当前类加载器上下文中查找指定的类。该类加载器尚未加载您要查找的接口,因此将抛出ClassNotFoundException
。
如果.jar
文件位于应用程序的类路径中,则可以简单地使用系统类加载器,就像这样...
ClassLoader systemClassLoader = ClassLoader.getSystemClassloader();
Class<?> clazz = Class.forName(className, true, systemClassLoader)
...但是,如果您的
.jar
文件位于其他位置,并且尚未加载,则需要相应地加载它:ClassLoader urlClassLoader = new URLClassLoader(new URL[]{new URL("path/to/file.jar")});
Class<?> clazz = Class.forName(className, true, urlClassLoader)
等等!
关于java - 执行Java AnnotationProcessor时发生ClassNotFound异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57255374/