Gunnar Hilling Selbstständig

JavaPoet zeichnet sich durch seine einfache Benutzbarkeit aus, da es nicht direkt einen Syntaxbaum abbildet, sondern die Möglichkeit mitbringt, Code auch frei zu erzeugen.

Jede Programmiersprache hat in bestimmten Bereichen Defizite, insbesondere wenn sie wie Java bereits einige Jahre auf dem Buckel hat. Diese Defizite sind entweder schlicht hinderlich oder erschweren ernsthaft die Verwendung geeigneter Entwurfsmuster. Glücklicherweise liegt in der tiefen Java-Werkzeugkiste der unbekannten Tools der Annotation Processor. Er hilft bei vielen Anforderungen auf elegante und flexible Art weiter. Dazu gehören zum Beispiel die Verwendung und Erzeugung von Immutables, von statischen Metamodellen und natürlich auch die Prüfung eigener Annotationen.

Bevor Sie jetzt die Hände über dem Kopf zusammenschlagen: Es geht nicht um das ungeliebte Annotation Processing Tool (apt), das mit Java 5 eingeführt und mit Java 8 endgültig wieder entsorgt wurde, sondern um das Annotation Processing API. Diese mit Java 6 eingeführte Schnittstelle ermöglicht es, den eigentlichen Compilevorgang zu beeinflussen und dabei optional auch neuen Code zu erzeugen.

Drum prüfe …

Der erste Schritt ist, Annotations auf die korrekte Verwendung zu prüfen: Bei der Definition einer Annotation ist es notwendig, die Codeelemente anzugeben, die annotiert werden dürfen. Zum Beispiel soll die Annotation GenerateModel dazu dienen, später aus einer Klasse heraus ein statisches Metamodell zu erzeugen. Deshalb haben wir den Zieltyp TYPE gewählt. Dieser verbietet aber nicht, die Annotation fehlerhaft auf andere Annotations anzuwenden.

@Target(ElementType.TYPE)
  public @interface GenerateModel {
}

… wer Annotations bindet

Dieses Problem dürfte bekannt sein. Besonders, wenn eine Annotation im Rahmen einer Bibliothek per Reflection zur Laufzeit verwendet wird, ist es wichtig sicherzustellen, dass sie auch korrekt verwendet wurde. Ansonsten drohen Laufzeitfehler oder die Annotations werden schlimmstenfalls ignoriert. Für genau diesen Anwendungsfall ist die Annotation-Processing-Bibliothek maßgeschneidert. Listing 1 zeigt dazu einen Processor, der die oben definierte Annotation verarbeitet, aber noch keine Prüfungen ausführt. Durch die Annotation SupportedAnnotationTypes weiß der Compiler, für welche Annotations der Processor aufgerufen werden soll. Die eigentliche Arbeit findet dann in der Methode process statt. Über den Rückgabewert false zeigt sie an, dass die Annotation nicht exklusiv durch diesen Processor verarbeitet werden soll.

Der Quellcode des endgültigen Projekts liegt bei Git-Hub und darf gerne als Vorlage für eigene Projekte verwendet werden. Zum Bauen braucht es lediglich ein JDK und Maven. Das Projekt enthält neben dem Maven-Aggregator ein Schnittstellenprojekt (API), den eigentlichen Processor und ein separates Integration-Tests-Projekt. Der Processor wird nur von Projekten benötigt, die auch wirklich Code erzeugen.

Den vollständigen Artikel lesen Sie in der Ausgabe:

Java Magazin 6.18 - "Scala"

Alle Infos zum Heft
579837775Der Java Annotation Processor
X
- Gib Deinen Standort ein -
- or -