2015-05-19 16 views
5

Mam problem z refleksją. Zdecydowałem, że chcę utworzyć generator kwerend SQL za pomocą refleksji. Stworzyłem własne adnotacje, aby określić, jakie klasy mogą być używane, jakie atrybuty mogą być przechowywane ect. Kod działa tak, jak chcę, ale problem polega na używaniu tego projektu jako zależności w innych.Utrata odbicia w Java informacji o adnotacjach

Mam inny projekt przy użyciu OJDBC i im próbuję użyć mojej biblioteki do generowania kwerend na podstawie klasy. Jednak kiedy przekazuję klasę z mojego projektu ojdbc, następuje utrata wszystkich informacji o klasie, klasa pojawia się jako java.lang.Class, a nawet informacje o annotaion są tracone. Czy ktoś wie, dlaczego tak się dzieje?

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

The cls.getAnnotation(Storable.class) traci informację, gdy następuje klasa jest przekazywana do niego

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

} 

Klasa zwierzę jest w projekcie ojdbc i metoda appendTableName należący do mojego konstruktora zapytań. Próbowałem generowanie projektu querybuilder do słoik i użyj maven install, aby dodać go do mojego repozytorium i nadal nie ma szczęścia.

Dziękuję za szybką odpowiedź, ale nie stanowi to problemu, ponieważ utworzona przeze mnie Adnotacja ma ustawioną Retencję do Środowiska wykonawczego, patrz poniżej.

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

Moja adnotacja jest ustawiona na runtime, ale informacje o klasie są nadal tracone.

+0

Kod, który wysłałeś, powinien działać. To znaczy, przyczyna leży gdzie indziej. Czy jesteś absolutnie pewien, że przekazany obiekt klasy odpowiada klasie z tą adnotacją? (I nie, na przykład, pewna podklasa generowana przez środowisko wykonawcze?) Czy jesteś pewien, że klasa została zdefiniowana ze źródła, które ma tę adnotację? (Nie używasz starej wersji klasy, która jeszcze nie ma adnotacji, prawda?) – meriton

+0

Nie, jej działanie z poprawną wersją adnotacji i nie podporządkowanie w tej chwili. Klasa nie zgłasza błędów kompilacji i poprawnie odwołuje się do adnotacji. Adnotacja jest zapakowana w słoik, który został dodany do projektu za pośrednictwem zależności programu. –

+1

... i jesteś pewien, że klasa adnotacji jest dostępna na ścieżce klasy środowiska wykonawczego? (Możesz to sprawdzić, zaznaczając, że 'Class.forName (" com.whatevertymtorable ")' nie wyrzuca wyjątku) – meriton

Odpowiedz

5

Aby uzyskać adnotację użyteczną w środowisku wykonawczym, należy dodać do niej adnotację.

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

Bez tego adnotacja nie jest widoczna w środowisku wykonawczym.

Aby uzyskać więcej informacji, oto źródło tej adnotacji.

/** 
* 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

Zobacz kod, który wprowadziłem poniżej –

+0

Nie jestem całkowicie pewien, co robiłem źle, jak zrobiłem żadnych zmian w kodzie, a teraz wydaje się, że działa dobrze. Dzięki za wejście. –

Powiązane problemy