2015-05-19 16 views
5

Ho riscontrato un problema con la riflessione. Ho deciso che volevo creare un generatore di query SQL utilizzando la riflessione. Ho creato le mie annotazioni per determinare quali classi possono essere utilizzate, quali attributi possono essere memorizzati ect. Il codice funziona come voglio, tuttavia il problema è che si utilizza questo progetto come una dipendenza in altri.Perdita riflessione Java delle informazioni di annotazione

Ho un altro progetto che utilizza OJDBC e sto cercando di utilizzare la mia libreria per generare le query in base alla classe. Tuttavia quando passo una classe dal mio progetto ojdbc c'è una perdita di tutte le informazioni di classe, la classe appare come java.lang.Class e anche le informazioni di annotaion vengono perse. Qualcuno sa perché questo sta accadendo?

private static <T> void appendTableName(Class<T> cls) throws NotStorableException { 
    Storable storable = cls.getAnnotation(Storable.class); 
    String tableName = null; 
    if (storable != null) { 
     if ((tableName = storable.tableName()).isEmpty()) 
      tableName = cls.getSimpleName(); 
    } else {  
     throw new NotStorableException(
       "The class you are trying to persist must declare the Storable annotaion"); 
    } 
    createStatement.append(tableName.toUpperCase()); 
} 

Il cls.getAnnotation(Storable.class) sta perdendo le informazioni quando la seguente classe viene passata ad esso

package com.fdm.ojdbc; 

import com.fdm.QueryBuilder.annotations.PrimaryKey; 
import com.fdm.QueryBuilder.annotations.Storable; 

@Storable(tableName="ANIMALS") 
public class Animal { 

@PrimaryKey 
private String name; 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 

} 

La classe animale è nel progetto ojdbc e il metodo appendTableName appartiene al mio generatore di query. Ho provato a generare il progetto di querybuilder in un jar e utilizzare l'installazione di maven per aggiungerlo al mio repository e ancora senza fortuna.

Grazie per la risposta rapida, tuttavia questo non è un problema in quanto l'annotazione che ho creato ha Retention set to Runtime, vedi sotto.

package com.fdm.QueryBuilder.annotations; 

import java.lang.annotation.ElementType; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import java.lang.annotation.Target; 

@Target(value = { ElementType.TYPE }) 
@Retention(value = RetentionPolicy.RUNTIME) 
public @interface Storable { 
    public String tableName() default ""; 
} 

La mia annotazione è impostata su runtime ma le informazioni sulla classe sono ancora perse.

+0

Il codice che hai postato dovrebbe funzionare. Cioè, la causa sta altrove. Sei assolutamente sicuro che l'oggetto classe che viene passato corrisponda a una classe con questa annotazione? (E non, ad esempio, qualche runtime ha generato sottoclassi?) Sei sicuro che la classe sia stata definita da una fonte che ha quell'annotazione? (Non stai correndo con una vecchia versione della classe che non ha ancora l'annotazione, vero?) – meriton

+0

No, è in esecuzione con la versione corretta dell'annotazione e im non subtyping al momento. La classe non genera errori di compilazione e fa correttamente riferimento all'annotazione. L'annotazione è confezionata in un jar che è stato aggiunto al progetto tramite dipendenze Maven. –

+1

... e sei sicuro che la classe di annotazione sia disponibile sul percorso della classe di runtime? (Puoi verificarlo controllando che 'Class.forName (" com.whatever.Storable ")' non lanci un'eccezione) – meriton

risposta

5

Quando si desidera un'annotazione utilizzabile in fase di esecuzione, è necessario aggiungervi un'annotazione.

@Retention(RetentionPolicy.RUNTIME) 
public @interface Storable { 

In questo caso, l'annotazione non è visibile in fase di esecuzione.

Per ulteriori informazioni, ecco la fonte di questa annotazione.

/** 
* Indicates how long annotations with the annotated type are to 
* be retained. If no Retention annotation is present on 
* an annotation type declaration, the retention policy defaults to 
* {@code RetentionPolicy.CLASS}. 
* 
* <p>A Retention meta-annotation has effect only if the 
* meta-annotated type is used directly for annotation. It has no 
* effect if the meta-annotated type is used as a member type in 
* another annotation type. 
* 
* @author Joshua Bloch 
* @since 1.5 
* @jls 9.6.3.2 @Retention 
*/ 
@Documented 
@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.ANNOTATION_TYPE) 
public @interface Retention { 
    /** 
    * Returns the retention policy. 
    * @return the retention policy 
    */ 
    RetentionPolicy value(); 
} 
+0

Vedere il codice I enetered below –

+0

Non sono del tutto sicuro di cosa stia sbagliando come ho fatto nessuna modifica al codice e ora sembra funzionare bene. Grazie per l'input. –