Java 反射:即使存在注释也未找到
Java reflection: annotation not found even if it's present
我正在使用反射在 class 中查找方法,并获取描述操作类型(CREATE、DELETE...)的注释 "PermessiNecessari"实施。
这是一段实现纠察链接的授权检查class PathAuthorizer。
我得到一个名为 url 的文件,我将其拆分并从 url 中找到实现 Web 服务的 class。然后我搜索它将被调用的方法并阅读它使用的操作类型。
这是搜索方法的一部分:
Class facadeinterface = Class.forName(pm); // get the interface
Method metodo = getMetodoClasse(facadeinterface, metodoRest); // find method with @Path annotation
if(metodo != null){
PermessiNecessari rp = metodo.getAnnotation(PermessiNecessari.class);
if(rp != null){ // caso metodo con permessi
return checkPermessiModulo(m, rp);
}
if(metodo.isAnnotationPresent(NonProtetto.class)){
return true;
}
LOG.log(Level.WARNING, "Metodo trovato : {0}/{1}, ma non annotato!", new Object[]{metodoRest,metodo});
例如,这是选中的 class:
public interface VlpgmoduliManagerFacadeRemote
extends InterfacciaFacadeRemote<Vlpgmoduli>{
@POST
@javax.ws.rs.Path("getpermessimoduligruppo")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
@PermessiNecessari(operation = STANDARD_OP.READ)
public GridResponse<Vlpgmoduli> getPermessiModuliGruppo(MultivaluedMap<String, String> formParams,
String callback)
throws BadRequestException;
...
方法是通过@javax.ws.rs.Path注解找到的,但是想获取"PermessiNecessari"注解时,找不到这个注解!
PS : 在其他 classes 中这个系统工作正常。
父接口中的方法也没有找到!
尝试使用另一个扩展相同接口的接口,并找到所有方法(继承的)。
这是我的注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PermessiNecessari {
Class resourceClass() default void.class;
String operation() default "";
String modulo() default "";
}
这是搜索实现web服务的方法的方法:
private Method getMetodoClasse(Class facade, String metodo){
for(Method method : facade.getMethods()){
Path p = method.getAnnotation(Path.class);
if(p != null && ( p.value().equals(metodo) || p.value().equals("/"+metodo) )){
return method;
}
}
for (Class c : facade.getInterfaces()) {
for (Method method : c.getDeclaredMethods()) {
Path p = method.getAnnotation(Path.class);
if(p != null && ( p.value().equals(metodo) || p.value().equals("/"+metodo) )){
return method;
}
}
}
return null;
}
编辑:
这不是注释的问题。我试过这个检查:
public boolean haAnnotazione(Method method, Class annotationType){
Annotation annotazioni[] = method.getAnnotations();
for(Annotation a : annotazioni){
if(a.annotationType().getName().equals(annotationType.getName())){
return true;
}
}
return false;
}
如果我使用 a.annotationType().equals(annotationType) 它 returns false 即使它们相同;如果我使用 class 的名称,就可以了!
可能是 class加载器问题? Wildfly 中的软件运行。
@PermessiNecessari
必须是 Runtime retention,因为如果保留不同,编译器将删除不包含有关该注释的信息到字节码中。
这就是为什么在运行时找不到您的注释的原因 - 它不存在。
已解决!
这是一个依赖性错误。项目中有 2 个不同的依赖版本,所以加载的注释实际上是两个不同的 classes.
下次:如果您有一些转换异常或两个相等的 Class 不相等,请检查您的 pom.xml 以了解不同的依赖项。
...真的没有解决,在EAR/lib和WAR/lib中的class之间有一个classloader问题,但这是另一个问题
我正在使用反射在 class 中查找方法,并获取描述操作类型(CREATE、DELETE...)的注释 "PermessiNecessari"实施。
这是一段实现纠察链接的授权检查class PathAuthorizer。 我得到一个名为 url 的文件,我将其拆分并从 url 中找到实现 Web 服务的 class。然后我搜索它将被调用的方法并阅读它使用的操作类型。
这是搜索方法的一部分:
Class facadeinterface = Class.forName(pm); // get the interface
Method metodo = getMetodoClasse(facadeinterface, metodoRest); // find method with @Path annotation
if(metodo != null){
PermessiNecessari rp = metodo.getAnnotation(PermessiNecessari.class);
if(rp != null){ // caso metodo con permessi
return checkPermessiModulo(m, rp);
}
if(metodo.isAnnotationPresent(NonProtetto.class)){
return true;
}
LOG.log(Level.WARNING, "Metodo trovato : {0}/{1}, ma non annotato!", new Object[]{metodoRest,metodo});
例如,这是选中的 class:
public interface VlpgmoduliManagerFacadeRemote
extends InterfacciaFacadeRemote<Vlpgmoduli>{
@POST
@javax.ws.rs.Path("getpermessimoduligruppo")
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN})
@PermessiNecessari(operation = STANDARD_OP.READ)
public GridResponse<Vlpgmoduli> getPermessiModuliGruppo(MultivaluedMap<String, String> formParams,
String callback)
throws BadRequestException;
...
方法是通过@javax.ws.rs.Path注解找到的,但是想获取"PermessiNecessari"注解时,找不到这个注解!
PS : 在其他 classes 中这个系统工作正常。 父接口中的方法也没有找到! 尝试使用另一个扩展相同接口的接口,并找到所有方法(继承的)。
这是我的注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface PermessiNecessari {
Class resourceClass() default void.class;
String operation() default "";
String modulo() default "";
}
这是搜索实现web服务的方法的方法:
private Method getMetodoClasse(Class facade, String metodo){
for(Method method : facade.getMethods()){
Path p = method.getAnnotation(Path.class);
if(p != null && ( p.value().equals(metodo) || p.value().equals("/"+metodo) )){
return method;
}
}
for (Class c : facade.getInterfaces()) {
for (Method method : c.getDeclaredMethods()) {
Path p = method.getAnnotation(Path.class);
if(p != null && ( p.value().equals(metodo) || p.value().equals("/"+metodo) )){
return method;
}
}
}
return null;
}
编辑: 这不是注释的问题。我试过这个检查:
public boolean haAnnotazione(Method method, Class annotationType){
Annotation annotazioni[] = method.getAnnotations();
for(Annotation a : annotazioni){
if(a.annotationType().getName().equals(annotationType.getName())){
return true;
}
}
return false;
}
如果我使用 a.annotationType().equals(annotationType) 它 returns false 即使它们相同;如果我使用 class 的名称,就可以了!
可能是 class加载器问题? Wildfly 中的软件运行。
@PermessiNecessari
必须是 Runtime retention,因为如果保留不同,编译器将删除不包含有关该注释的信息到字节码中。
这就是为什么在运行时找不到您的注释的原因 - 它不存在。
已解决!
这是一个依赖性错误。项目中有 2 个不同的依赖版本,所以加载的注释实际上是两个不同的 classes.
下次:如果您有一些转换异常或两个相等的 Class 不相等,请检查您的 pom.xml 以了解不同的依赖项。
...真的没有解决,在EAR/lib和WAR/lib中的class之间有一个classloader问题,但这是另一个问题