簡體   English   中英

無法從tomcat中自定義類加載器加載的類中獲取注釋

[英]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());

做了伎倆。 但令人驚訝的是,找不到注釋而不是ClassNotFoundExceptionNoClassDefError ,這就是我在加載類時未找到注釋時所期望的...

確定你找不到你的注釋,你必須注釋你的注釋以保持運行時間,並添加:

@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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM