2016-11-09 132 views
0

我使用反射來查找類中的方法,並獲取描述操作類型(CREATE,DELETE,...)的註釋「PermessiNecessari」一個方法實現。Java反射:註釋找不到,即使它存在

這是執行picketlink類PathAuthorizer的授權檢查。 我得到一個被調用的url,我將它分開,並從url中找到實現Web服務的類。然後我搜索它將被調用的方法並閱讀它使用的操作類型。

這是一塊搜索法的:

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}); 

對於istance,這是所檢查的等級:

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:在其他類中,這個系統工作正常。 父接口中的方法也找不到! 嘗試使用擴展相同接口的另一個接口,並找到所有方法(繼承的方法)。

這是我的註解:

@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; 
} 

編輯: 這不是註釋的問題。我tryed這個檢查:

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()等於(annotationType)返回,即使他們是相同的錯誤;如果我使用班級的名字,它的工作原理!

也許是類加載器的問題?該軟件在Wildfly中運行。

+0

的可能的複製[如何不同的保留策略影響我的註釋嗎?] (HTTP://計算器。COM /問題/ 3107970 /怎麼辦 - 不同的保留的策略 - 影響 - 我的註解) – Dariusz

+0

@Daniele你能不能解釋一下您的編輯,因爲我不知道你腦子裏想的是什麼? – Antoniossss

+0

@Antoniossss我已經改變了這個問題,我希望現在更清楚 –

回答

1

解決!

這是一個依賴關係錯誤。項目中有兩個不同的依賴項版本,所以加載的註釋實際上是兩個不同的類。

對於下一次:如果您有一些轉換異常或兩個相等的Class不相等,請檢查您的pom.xml是否存在不同的依賴關係。

...真的不解決,有在EAR/lib和在WAR/lib目錄類之間的類加載器的問題,但這是另外一個問題

+0

感謝您的更新,我有同樣的問題 - 寫出整個路徑解決了問題:/ – Tasgall

0

@PermessiNecessari必須是Runtime retention,因爲如果保留時間不同,編譯器將刪除不包含關於該註釋的信息到字節碼中。

這就是爲什麼您的註釋在運行時找不到 - 它不在那裏。

+0

PermessiNecessari有@Retention(RetentionPolicy.RUNTIME):( 註釋是從其他類找到的 –