![](/img/trans.png)
[英]Why classes loaded with boot classloader (bootclasspath) doesn't include annotations
[英]Can't get annotations from classes loaded by custom classloader in tomcat
給定類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運行時找不到注釋
[]
誰能告訴我為什么?
它總是一樣:注意類加載器層次結構!
new URLClassLoader(new URL[] {new File("c:/pos/example.jar").toURI().toURL()}, PopperServlet.class.getClassloader());
做了伎倆。 但令人驚訝的是,找不到注釋而不是ClassNotFoundException
或NoClassDefError
,這就是我在加載類時未找到注釋時所期望的...
確定你找不到你的注釋,你必須注釋你的注釋以保持運行時間,並添加:
@Retention(RetentionPolicy.RUNTIME)
保留Java文檔:指示要保留帶注釋類型的注釋的時間長度。 如果注釋類型聲明中不存在保留注釋,則保留策略默認為RetentionPolicy.CLASS。
了解更多詳情: 這里
我遇到了同樣的問題。 我按照我的客戶端類加載器解決它,也許你可以嘗試一下。
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());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.