首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >反射返回包含null元素的集合

反射返回包含null元素的集合
EN

Stack Overflow用户
提问于 2013-04-06 03:30:23
回答 4查看 1.5K关注 0票数 3

我使用Reflections查找具有特定注释的类。我的项目结构如下

一个战争包: WEB-INF/classes/...packages.../ClassAnnoted1.class

包含在war中的一个JAR包,它有一个执行以下代码的类:

代码语言:javascript
运行
复制
Reflections reflections= new Reflections(ClasspathHelper.forWebInfClasses(servletContext))
Set set= reflections.getTypesAnnotatedWith(CustomAnnotation.class)

CustomAnnotation也出现在JAR包中。

设置的大小是正确的(例如,如果我在jar中有3个带注释的类,那么设置的大小返回为3),但是其中的所有元素都是空的,而不是Class。我需要获取类并检查JAR类中的注释参数。

有人知道为什么会发生这种事吗?

编辑:

代码语言:javascript
运行
复制
Reflections reflections= new Reflections("com.my.customAnnotededClasses"); //package that my annoted class is in
Set set= reflections.getTypesAnnotatedWith(CustomAnnotation.class);

也不起作用,在这种情况下,设置的长度为零,而不是带有注释的类的数量。

编辑2:好的,真正的问题是我把我的整个应用程序打包成了一个EAR,所以我有以下内容:

代码语言:javascript
运行
复制
EAR
----> WAR
----> JAR

jar包含在EAR lib文件夹中,而不在WAR lib文件夹中。所以jar类看不到war类,一旦我让WAR类直接依赖于JAR,就像这样:

代码语言:javascript
运行
复制
EAR
----> WAR
---------> JAR

它开始工作了。但最初的问题仍然存在,在某些情况下,我可能希望Jar类包含在EAR中,而不是WAR中(例如,如果我有多个WAR需要使用我的jar )。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-04-09 03:30:24

我想我不能使用反射库来做这件事。所以我亲手完成了:

代码语言:javascript
运行
复制
public static List<Class<?>> getClassesAnnotatedWith(Class annotation, ServletContext servletContext) {
    List<Class<?>> webClasses, jarClasses;
    webClasses= getClassesAnnotedWithFromClassLoader(annotation, servletContext.getClassLoader());
    jarClasses= getClassesAnnotedWithFromClassLoader(annotation, Thread.currentThread().getContextClassLoader());
    for (Class<?> jarClass : jarClasses) {
        Class<?> elementToAdd= null;
        for (Class<?> webClass : webClasses) {
            if ( ! jarClass.getName().equals(webClass.getName())) {
                elementToAdd= jarClass;
            }
        }
        if(elementToAdd != null) {
            webClasses.add(elementToAdd);
        }
    }
    return webClasses;
}


 private static List<Class<?>> getClassesAnnotedWithFromClassLoader(Class annotation, ClassLoader classLoader) {
        List<Class<?>> classes= new ArrayList<Class<?>>();
        Class<?> classLoaderClass= classLoader.getClass();
        while (! classLoaderClass.getName().equals("java.lang.ClassLoader")) {
            classLoaderClass= classLoaderClass.getSuperclass();
        }
        try {
            Field fldClasses= classLoaderClass.getDeclaredField("classes");
            fldClasses.setAccessible(true);
            Vector<Class<?>> classesVector= (Vector<Class<?>>) fldClasses.get(classLoader);
            for (Class c : classesVector) {
                if (c.isAnnotationPresent(annotation)) {
                    classes.add(c);
                }
            }
        } catch (Exception e) { }
        return classes;
    }

我通过ServletContext对象从我的WAR包中获取ClassLoader。如果在WAR和JAR中定义了带有注释和相同名称的类,还有一种保护措施(您可能应该检查包是否也是相同的)。

请注意,您可能永远不应该在自己的项目中使用此代码(可能仅用于调试)。它涉及到反射ClassLoader类以使"classes“属性成为公共属性。例如,这个属性可能在Java 9中不存在,所以要小心。如果您正在与由第三方编写的模块进行交互,这也可能存在一些安全问题。

票数 2
EN

Stack Overflow用户

发布于 2013-04-08 20:25:39

我也有一台类似的problem。你确定你把注解类包含到你的类路径中了吗?如果它们未加载,则会以某种方式找到它们,但不会真正返回它们,并且不会出现任何异常或任何情况

票数 1
EN

Stack Overflow用户

发布于 2013-04-10 17:10:19

Reflections库给我带来了各种问题。现在我使用的是Guava库的反射部分:到目前为止,还没有发生任何意外的行为。无论如何,我认为问题的根源是Java类加载器,这是非常罕见的。在Reflections中使用类CustomAnnotation.class之前,可以尝试加载它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15842024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档