我编写了一个简单的注释和一个处理注释的注释程序。
注释具有单个值:它应该是现有接口的名称(带有软件包(。
注释处理器应检索注释的值,检索接口的类对象,最后应打印在接口中声明的所有方法。
示例:这是我的注释
@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的Interfaceence,则可以正常工作;
但是,如果我将一个位于.jar文件中的接口配置为InterfaceName(在项目的构建路径中添加(,则在尝试执行class.forname(...(语句时,我会获得classNotFoundException。
有什么想法吗?
谢谢,欢呼
这是一个典型的classloader问题。您正在尝试找到当前类加载程序未加载的类,因此抛出了ClassNotFoundException
。
java.lang.Class
的Javadoc将方法Class.forName(className)
定义为:
返回与类别或给定字符串名称接口关联的类对象。调用此方法等效于
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)
etvoilà!