我使用Reflections查找具有特定注释的类。我的项目结构如下
一个战争包: WEB-INF/classes/...packages.../ClassAnnoted1.class
包含在war中的一个JAR包,它有一个执行以下代码的类:
Reflections reflections= new Reflections(ClasspathHelper.forWebInfClasses(servletContext))
Set set= reflections.getTypesAnnotatedWith(CustomAnnotation.class)CustomAnnotation也出现在JAR包中。
设置的大小是正确的(例如,如果我在jar中有3个带注释的类,那么设置的大小返回为3),但是其中的所有元素都是空的,而不是Class。我需要获取类并检查JAR类中的注释参数。
有人知道为什么会发生这种事吗?
编辑:
Reflections reflections= new Reflections("com.my.customAnnotededClasses"); //package that my annoted class is in
Set set= reflections.getTypesAnnotatedWith(CustomAnnotation.class);也不起作用,在这种情况下,设置的长度为零,而不是带有注释的类的数量。
编辑2:好的,真正的问题是我把我的整个应用程序打包成了一个EAR,所以我有以下内容:
EAR
----> WAR
----> JARjar包含在EAR lib文件夹中,而不在WAR lib文件夹中。所以jar类看不到war类,一旦我让WAR类直接依赖于JAR,就像这样:
EAR
----> WAR
---------> JAR它开始工作了。但最初的问题仍然存在,在某些情况下,我可能希望Jar类包含在EAR中,而不是WAR中(例如,如果我有多个WAR需要使用我的jar )。
发布于 2013-04-09 03:30:24
我想我不能使用反射库来做这件事。所以我亲手完成了:
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中不存在,所以要小心。如果您正在与由第三方编写的模块进行交互,这也可能存在一些安全问题。
发布于 2013-04-08 20:25:39
我也有一台类似的problem。你确定你把注解类包含到你的类路径中了吗?如果它们未加载,则会以某种方式找到它们,但不会真正返回它们,并且不会出现任何异常或任何情况
发布于 2013-04-10 17:10:19
Reflections库给我带来了各种问题。现在我使用的是Guava库的反射部分:到目前为止,还没有发生任何意外的行为。无论如何,我认为问题的根源是Java类加载器,这是非常罕见的。在Reflections中使用类CustomAnnotation.class之前,可以尝试加载它。
https://stackoverflow.com/questions/15842024
复制相似问题