为了账号安全,请及时绑定邮箱和手机立即绑定

执行 Java AnnotationProcessor 时出现 ClassNotFound 异常

执行 Java AnnotationProcessor 时出现 ClassNotFound 异常

慕田峪9158850 2023-04-26 16:31:07
我写了一个简单的注释和一个 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。有什么想法吗?
查看完整描述

1 回答

?
Cats萌萌

TA贡献1805条经验 获得超9个赞

这是典型的 ClassLoader 问题。您正在尝试查找当前类加载器未加载的类,因此ClassNotFoundException抛出 a 。


Javadoc将java.lang.Class方法定义为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)


查看完整回答
反对 回复 2023-04-26
  • 1 回答
  • 0 关注
  • 185 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信