2016-11-09 4 views
0

Ich verwende Reflection für eine Methode in einer Klasse zu finden und die Annotation "PermessiNecessari", die den Typ der Operation (CREATE, DELETE, ...) beschreiben eine Methode implementiert.Java-Reflektion: Annotation nicht gefunden, auch wenn es vorhanden ist

Dies ist ein Teil der Berechtigungsprüfung zur Implementierung einer Picketlink-Klasse PathAuthorizer. Ich bekomme eine aufgerufene URL, ich teile sie und von der URL finde ich die Klasse, die den Web Service implementiert. Dann suche ich nach der Methode, die aufgerufen wird und lese, welche Art von Operation es verwendet.

Dies ist ein Stück der Suchmethode:

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

Für istance, ist dies die geprüfte Klasse:

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; 
... 

Verfahren via @ javax.ws.rs.Path gefunden Annotation, aber wenn ich die Annotation "PermessiNecessari" erhalten möchte, wird diese Annotation nicht gefunden!

PS: in anderen Klassen funktioniert dieses System gut. Die Methode in der Elternschnittstelle wird nicht gefunden! Versucht mit einer anderen Schnittstelle, die die gleiche Schnittstelle erweitert und alle Methoden (auch die geerbten) gefunden werden.

Dies ist meine Anmerkung:

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface PermessiNecessari {  
    Class resourceClass() default void.class; 
    String operation() default ""; 
    String modulo() default ""; 
} 

Dies ist die Methode, um das Verfahren zu suchen, die den Web-Service implementieren:

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

EDIT: Es ist kein Problem der Anmerkung. Ich mit diesem Scheck 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; 
} 

wenn ich a.annotationType() verwenden equals (annotationType) es false zurück, auch wenn sie gleich sind; Wenn ich den Namen der Klasse verwende, funktioniert es!

Vielleicht ein Classloader-Problem? Die Software läuft in Wildfly.

+0

Mögliche Duplikat von [Wie unterschiedliche Aufbewahrungsrichtlinien meine Anmerkungen beeinflussen?] (http: // Stapelüberlauf.com/questions/3107970/how-do-verschiedene-retention-policies-affect-my-annotations) – Dariusz

+0

@Daniele könntest du bitte deinen Schnitt erklären, da ich keine Ahnung habe, was du vorhattest? – Antoniossss

+0

@Antoniossss ich habe die Frage geändert, ich hoffe, es ist jetzt klarer –

Antwort

1

Gelöst!

Es war ein Abhängigkeitsfehler. Da es im Projekt zwei verschiedene Versionen von Abhängigkeiten gab, waren die geladenen Annotationen wirklich zwei verschiedene Klassen.

Für das nächste Mal: ​​check in Ihre pom.xml für verschiedene Abhängigkeiten, wenn Sie eine Cast-Ausnahme haben oder wenn zwei gleiche Klasse nicht gleich sind.

... wirklich nicht gelöst, gibt es ein Problem zwischen Classloader-Klasse in EAR/lib und in WAR/lib, aber das ist eine andere Frage

+0

Danke für das Update, ich hatte das gleiche Problem - Schreiben Sie den ganzen Weg das Problem behoben: / – Tasgall

0

@PermessiNecessari muss Runtime retention sein, da der Compiler Informationen über diese Annotation nicht in den Bytecode aufnehmen wird, wenn die Retention anders sein wird.

Deshalb wird Ihre Annotation nicht zur Laufzeit gefunden - es ist nicht da.

+0

PermessiNecessari hat @Retention (RetentionPolicy.RUNTIME) :( Die Anmerkung wird von den anderen Klassen gefunden. –

Verwandte Themen