无法从tomcat中自定义类加载器加载的类中获取注释

时间:2013-12-08 08:50:08

标签: java tomcat annotations classloader

鉴于班级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运行时找不到注释

[]

有人可以告诉我为什么吗?

3 个答案:

答案 0 :(得分:4)

它总是一样:注意类加载器层次结构!

new URLClassLoader(new URL[] {new File("c:/pos/example.jar").toURI().toURL()}, PopperServlet.class.getClassloader());

做了这个伎俩。但令人惊讶的是,找不到注释而不是ClassNotFoundExceptionNoClassDefError,这就是我在加载类时未找到注释时所期望的...

答案 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());