2012-07-08 14 views
23

Po prostu patrzę w niewłaściwym kierunku, ale uważam, że dokumentacja JSE na przetwarzanie adnotacji jest bardzo ... rzadka. Chcę napisać procesor adnotacji, który przetwarza oznaczone pola String i zmienne lokalne, aby zastąpić je obliczonym wyrażeniem String. To nie powinno być zbyt skomplikowane, ale jestem dość zagubiony w Javadoc dla javax.annotation.processing.Jak napisać procesor adnotacji Java?

EDYCJA: Potrzebuję przetwarzać adnotacje w czasie kompilacji, ponieważ chcę zmodyfikować wygenerowany kod. Powinien zastąpić adnotowane stałe wyrażenia String z wyliczonym wyrażeniem String.

+0

Uzgodnione, mój punkt wyjścia był ten samouczek: http://tutorials.jenkov.com/java-reflection/annotations.html –

+2

Czy chcesz przetwarzać adnotacje w czasie kompilacji lub środowiska wykonawczego? Zauważ, że adnotacje na zmiennych lokalnych są efektywnie bezużyteczne z powodu głupiego ograniczenia javac. –

+0

Chcę przetworzyć je w czasie kompilacji, więc to oczywiście działa tylko dla stałych wyrażeń łańcuchowych. –

Odpowiedz

14

Nie można tego zrobić za pomocą procesora adnotacji czasu kompilacji. Procesory adnotacji czasu kompilacji mogą generować tylko nowe pliki (i klasy), które nie mogą modyfikować istniejących klas. Możesz robić refleksje w czasie wykonywania, ale mówiąc ściśle, że nie nazywa się przetwarzaniem adnotacji. Ponadto nie będziesz mieć dostępu do zmiennych lokalnych.

Jeśli szukasz na jak napisać procesor kompilacji adnotacji sprawdzeniu https://github.com/pellaton/spring-configuration-validation-processor

+0

Teoretycznie możesz użyć procesora adnotacji + Apache BCEL (lub czegoś podobnego), aby zmodyfikować oryginalny plik .class. Ale to brzmi niechlujnie. – vanza

+0

Err ... co? Nie mogę zmodyfikować kodu źródłowego przed kompilacją za pomocą struktury adnotacji? –

+1

Spojrzałem na połączony kod. Oczywiście nie generuje kodu, tylko go potwierdza.Miałem nadzieję, że będę mógł zmodyfikować abstrakcyjne drzewo składniowe przed faktycznym krokiem generowania kodu. –

4
+0

Przyjrzałem się Javassist i ASM. Może wykonaliby zadanie, ale chodziło im o manipulację kodami bajtowymi. Bardzo bym chciał użyć narzędzia, które pozwoli mi manipulować drzewem składni abstrakcyjnej. Manipulowanie bajtami byłoby moją ostatecznością. –

+0

OK, po zbadaniu opcji wydaje się, że manipulacja kodami bajtowymi jest jedyną możliwą opcją. Kolejnym wyzwaniem jest zintegrowanie tego z budową Mavena - nie tylko dla mnie, ale także dla użytkowników mojej biblioteki. –

+0

Hmm ... manipulacja AST byłaby ostatnią deską ratunku :) –

8

Dwa narzędzia to: Project Lombok i DuctileJ. Oba te narzędzia istniały w momencie, gdy pierwotnie zadano pytanie; dodatkowe narzędzia na pewno istnieją.

Kluczową ideą jest napisanie procesora adnotacji, który przetrawia i modyfikuje AST programu (abstrakcyjne drzewo składniowe) podczas kompilacji, przed wygenerowaniem kodu. Kompilator nie zmieni kodu źródłowego na dysku, ale wygenerowany plik .class będzie odzwierciedlał zmiany wprowadzone przez procesor adnotacji.

Możliwe jest dostosowanie jednego z tych narzędzi do własnych potrzeb lub wdrożenie własnego narzędzia inspirowanego przez techniki implementacji.

Przetwarzanie podczas kompilacji ma dwie zalety w stosunku do przetwarzania plików klas. Po pierwsze, kompilator zwykle ma więcej informacji niż jest dostępnych w skompilowanym kodzie. Innym jest to, że wszystko dzieje się w jednym kroku podczas kompilacji, zamiast wymagać od programisty uruchomienia oddzielnego narzędzia do przepisywania plików .class po kompilacji.

+0

na pewno, i warto wspomnieć, że oba używają hacka do modyfikowania AST, wykorzystując błąd w bieżącym procesorze adnotacji w Javie, wykorzystując wewnętrzne interfejsy API javac, które mogą być naprawiono/usunięto niektóre przyszłe JDK (co stanowi dla mnie dużą wadę). –

Powiązane problemy