鉴于班级org.popper.example.pages.Login
@Page(name="Login")
public interface Login {
}
导出到c:\pos\example.jar
和以下servlet
public class PopperServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public static void main(String[] args) throws MalformedURLException, ClassNotFoundException {
URLClassLoader ucl = new URLClassLoader(new URL[] {new File("c:/pos/example.jar").toURI().toURL()});
System.out.println(Arrays.asList(ucl.loadClass("org.popper.example.pages.Login").getAnnotations()));
}
public PopperServlet() throws MalformedURLException, ClassNotFoundException {
URLClassLoader ucl = new URLClassLoader(new URL[] {new File("c:/pos/example.jar").toURI().toURL()});
System.out.println(Arrays.asList(ucl.loadClass("org.popper.example.pages.Login").getAnnotations()));
}
}
将代码作为main运行显示预期结果
[@org.popper.fw.annotations.Page(name=Login)]
在tomcat中将代码作为servlet运行时找不到注释
[]
有人可以告诉我为什么吗?
答案 0 :(得分:4)
它总是一样:注意类加载器层次结构!
new URLClassLoader(new URL[] {new File("c:/pos/example.jar").toURI().toURL()}, PopperServlet.class.getClassloader());
做了这个伎俩。但令人惊讶的是,找不到注释而不是ClassNotFoundException
或NoClassDefError
,这就是我在加载类时未找到注释时所期望的...
答案 1 :(得分:1)
确定你找不到你的注释,你必须注释你的注释以保持运行时间,并添加:
@Retention(RetentionPolicy.RUNTIME)
保留Java文档:指示要保留带注释类型的注释的时间长度。如果注释类型声明中没有保留注释,则保留策略默认为RetentionPolicy.CLASS。
了解更多详情:here
答案 2 :(得分:0)
我遇到了同样的问题。我按照我的客户端类加载器解决它,也许你可以尝试一下。
ClassLoader代码:
import java.util.HashMap;
import java.util.Map;
/**
* Load class from byte[] which is compiled in memory.
*
* @author David
*/
class CustomClassLoader extends ClassLoader {
// class name to class bytes:
private Map<String, byte[]> classBytes = new HashMap<String, byte[]>();
public CustomClassLoader(Map<String, byte[]> classBytes) {
super(CustomClassLoader.class.getClassLoader());
Thread.currentThread().setContextClassLoader(this);
this.classBytes.putAll(classBytes);
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
byte[] buf = classBytes.get(name);
if (buf == null) {
return super.findClass(name);
}
classBytes.remove(name);
return defineClass(name, buf, 0, buf.length);
}
}
客户代码:
byte[] code = this.createEntity(logicalTable, keyCount, relationMap);
Map<String, byte[]> results = Maps.newHashMap();
results.put(this.entityPackage + "." + logicalTable.getTableName(), code);
CustomClassLoader classLoader = new CustomClassLoader(results);
Class<?> clazz = classLoader.findClass(this.entityPackage + "." + logicalTable.getTableName());