6

Ho creato un'annotazione, l'ho applicata a un DTO e scritto un annotationProcessor in stile Java 1.6. Posso vedere come fare in modo che annotationProcessor scriva un nuovo file sorgente, che non è quello che voglio fare, non riesco a vedere o scoprire come farlo modificare la classe esistente (idealmente basta modificare il codice byte). La modifica è in realtà abbastanza banale, tutto quello che voglio che il processore faccia è inserire un nuovo getter e setter in cui il nome deriva dal valore dell'annotazione che viene elaborata.Come si utilizza l'elaborazione delle annotazioni Java 1.6 per eseguire la tessitura del tempo di compilazione?

Il mio processore di annotazione ha questo aspetto;

@SupportedSourceVersion(SourceVersion.RELEASE_6) 
@SupportedAnnotationTypes({ "com.kn.salog.annotation.AggregateField" }) 
public class SalogDTOAnnotationProcessor extends AbstractProcessor { 

    @Override 
    public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) { 
     //do some stuff 
    } 
} 

risposta

-2

si deve estendere il compilatore javac per questo, il che significa costruire il vostro programma non sarà più portabile una normale applicazione. Vedi http://weblogs.java.net/blog/cayhorstmann/archive/2006/06/say_no_to_prope.html per ulteriori dettagli su come qualcuno ha raggiunto questo obiettivo.

+1

Questa è sicuramente una soluzione, ma sono abbastanza sicuro che non è l'unica soluzione. Quello che voglio fare potrebbe essere fatto da diversi framework/toolset esistenti, ad esempio javassist. Stavo cercando di evitare di introdurre una dipendenza che non sembra essere strettamente necessaria però, l'introduzione dell'elaborazione delle annotazioni in JDK1.6 sembrava come se la funzionalità di javassist fosse in fase di cottura. Forse mi sbagliavo e ho ancora bisogno di un Strumento di terze parti per eseguire la tessitura del tempo di compilazione. – Steve

6

In base alla progettazione, la funzione di elaborazione delle annotazioni non consente la modifica diretta del codice sorgente elaborato. Tuttavia, è possibile generare sottoclassi del tipo in elaborazione o la superclasse del tipo in elaborazione. Con un po 'di pianificazione, questo consente alcuni degli effetti della modifica del tipo in questione. Ho scritto un esempio di come questo possa combaciare; vedi this blog entry per una spiegazione più dettagliata e alcuni esempi di codice.

6

Stai cercando "Strumentazione", che è ciò che fa AspectJ. In questo caso devi specificare un jar nella riga di comando con l'opzione "-agent" e quindi avere la possibilità di filtrare tutte le classi caricate. Durante questa fase del filtro è possibile verificare le annotazioni e modificare il codice byte prima che venga caricato nella macchina virtuale. Le librerie per fare la modifica del codice bytecode includono "asm" e forse i wrapper di livello superiore "cglib" e "javassist". Potresti anche precompilare le tue classi per generare un elenco di classi che devono essere strumentate da te, per rendere il filtro all'inizio un po 'più veloce.

Vedere java.lang.instrumentation per ulteriori informazioni.

4

è necessario utilizzare le classi di compilatore interno - qualche ispirazione:

Ma è rischio calcolato. Il tuo programma verrà compilato solo su Sun/OpenJDK e potrebbero esserci problemi nelle versioni future (l'API interna può cambiare). Sebbene una volta compilato, è standard bytecode e verrà eseguito ovunque.

BTW: se si desidera utilizzarlo in Eclipse, è necessario aggiungere un supporto speciale perché Eclipse utilizza un compilatore non standard. Il tuo progetto dovrebbe essere più complesso e dovresti aggiungere un livello di astrazione al tuo processore, come lo fa Lombok.

+0

Questi sono esempi fantastici. Grazie! –

Problemi correlati