ClassNotFoundException

ClassNotFoundException

我编写了一个简单的注释和一个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.ClassJavadoc将方法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/

10-10 23:30