2011-07-13 4 views
23

Próbuję utworzyć nową adnotację, za pomocą której wykonam okablowanie środowiska wykonawczego, ale z wielu powodów chciałbym podczas kompilacji zweryfikować, że moje okablowanie zakończy się powodzeniem z pewnymi podstawowymi kontrolami.Tworzenie niestandardowego procesora AbstractProcessor i integracja z Eclipse

Załóżmy utworzyć nową adnotację:

@Target(ElementType.FIELD) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface CustomAnnotation{ 
} 

Teraz chcę zrobić jakiś rodzaj walidacji w czasie kompilacji, jak sprawdzić pole, które CustomAnnotation annotates jest określonego typu: ParticularType. Pracuję w Javie 6, więc stworzył AbstractProcessor:

@SupportedAnnotationTypes("com.example.CustomAnnotation") 
public class CompileTimeAnnotationProcessor extends AbstractProcessor { 

    @Override 
    public boolean process(Set<? extends TypeElement> annotations, 
          RoundEnvironment roundEnv) { 
     Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(CustomAnnotation.class); 
     for(Element e : elements){ 
      if(!e.getClass().equals(ParticularType.class)){ 
       processingEnv.getMessager().printMessage(Kind.ERROR, 
        "@CustomAnnotation annotated fields must be of type ParticularType"); 
      } 
     } 
     return true; 
    } 

} 

Następnie, na podstawie niektórych instrukcji znalazłem, stworzyłem folder META-INF/services i utworzony plik javax.annotation.processing.Processor z zawartością:

com.example.CompileTimeAnnotationProcessor 

Następnie wyeksportowałem projekt jako słoik.

W innym projekcie, I zbudował prostą klasę testową:

public class TestClass { 
    @CustomAnnotation 
    private String bar; // not `ParticularType` 
} 

I skonfigurowane właściwości projektu Eclipse następująco:

  • Set Java Compiler -> Produkcja adnotacji: "Włącz przetwarzanie adnotacji" i "Włącz przetwarzanie w edytorze"
  • Ustaw Java Kompilator -> Przetwarzanie adnotacji -> Ścieżka fabryczna, aby uwzględnić wyeksportowany słoik i zaznaczony jako zaawansowany, że pojawi się moja w pełni kwalifikowana klasa.

Kliknąłem "zastosuj", a Eclipse wyświetli monit o przebudowę projektu, trafiłem w porządku - ale nie zgłoszono błędu, pomimo posiadania procesora adnotacji.

Gdzie popełniłem błąd?


wpadłem to za pomocą javac jak

javac -classpath "..\bin;path\to\tools.jar" -processorpath ..\bin -processor com.example.CompileTimeAnnotationProcessor com\test\TestClass.java 

z wyjściem

@CustomAnnotation adnotacją pola muszą być typu ParticularType

+0

Po pierwsze, czy procesor adnotacji działa z javac poza środowiskiem Eclipse? – antlersoft

+0

@antlersoft: tak, działa poza środowiskiem Eclipse z prostym javac (zmiany to odzwierciedlają). –

+4

Czy sprawdziłeś dziennik błędów w Eclipse (Okno> Pokaż widok> Dziennik błędów na wypadek, gdy go nie widzisz)? Gdy procesor adnotacji ulegnie awarii, może nie zostać wyświetlone okno dialogowe z błędem, ale w dzienniku błędów pojawi się błąd. Możesz także spróbować debugować swój procesor w Eclipse, spryskując Messager.printMessage() typem = NOTE w twoim procesorze, ponieważ są one również widoczne w dzienniku błędów. – prunge

Odpowiedz

17

Aby mieć błędy pojawiają się w redaktor, Element powodując t błąd musi być oznaczony w funkcji printMessage. W powyższym przykładzie oznacza to, że podczas sprawdzania kompilacji należy użyć:

processingEnv.getMessager().printMessage(Kind.ERROR, 
    "@CustomAnnotation annotated fields must be of type ParticularType", 
    e); // note we explicitly pass the element "e" as the location of the error 
+1

Zajęło mi trochę czasu, aby dowiedzieć się, i jako notatkę dla przyszłych widzów, różnica między "processingEnv.getMessager(). PrintMessage" autora (i głosowanie jako prawidłowe rozwiązanie jest takie, że trzeci argument "e" jest przekazywany. – corgrath

+0

Dzięki za rozwiązanie, już miałem zamiar rzucić mój procesor adnotacji w/bin, ale teraz działa świetnie! –