6

Ich habe eine Annotation erstellt, sie auf ein DTO angewendet und einen Java 1.6 AnnotationProcessor geschrieben. Ich kann sehen, wie man den annotationProcessor eine neue Quelldatei schreiben lässt, was ich nicht machen will, ich kann nicht sehen oder herausfinden, wie man die existierende Klasse modifizieren kann (im Idealfall modifiziere einfach den Byte-Code). Die Änderung ist eigentlich ziemlich trivial, ich möchte nur, dass der Prozessor einen neuen Getter und Setter einfügt, wobei der Name von dem Wert der Annotation kommt, die verarbeitet wird.Wie verwenden Sie Java 1.6 Annotation Processing, um die Kompilierungszeit beim Weben durchzuführen?

Mein Annotationsprozessor sieht so aus;

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

Antwort

-2

Sie haben die javac Compiler für diese zu erweitern, die Ihr Programm bedeutet Aufbau wird als regelmäßige Anwendung nicht als tragbar sein. Siehe http://weblogs.java.net/blog/cayhorstmann/archive/2006/06/say_no_to_prope.html für weitere Details, wie jemand dies erreicht hat.

+1

Das ist sicherlich eine Lösung, aber ich bin mir ziemlich sicher, dass es nicht die einzige Lösung ist. Was ich tun möchte, könnte von mehreren existierenden Frameworks/Toolsets, zB javassist, getan werden. Ich versuchte zu vermeiden, eine Abhängigkeit einzuführen, die nicht unbedingt notwendig erscheint, aber die Einführung der Annotationsverarbeitung in JDK1.6 sah so aus, als würde die Funktionalität von javassist eingebaut. Vielleicht lag ich aber falsch und brauche immer noch eine 3rd-Party-Tool, um die Kompilierzeit Weben durchzuführen. – Steve

6

Die Annotationsverarbeitungsfunktion erlaubt nicht die direkte Änderung des Quellcodes, der gerade verarbeitet wird. Es können jedoch Unterklassen des gerade verarbeiteten Typs oder die Oberklasse des gerade verarbeiteten Typs generiert werden. Mit etwas Planung ermöglicht dies einen gewissen Effekt des Modifizierens des fraglichen Typs. Ich habe ein Beispiel dafür geschrieben, wie das zusammenpassen kann; Eine ausführlichere Erklärung und einen Beispielcode finden Sie unter this blog entry.

6

Sie suchen nach "Instrumentation", was Frameworks wie AspectJ tun. In diesem Fall müssen Sie in der Befehlszeile mit der Option "-agent" ein jar angeben und haben dann die Möglichkeit, alle geladenen Klassen zu filtern. Während dieses Filterschritts können Sie nach Anmerkungen suchen und den Bytecode ändern, bevor er in die virtuelle Maschine geladen wird. Bibliotheken zum Durchführen der tatsächlichen Bytecode-Modifikation enthalten "asm" und möglicherweise die Highlevel-Wrapper "cglib" und "javassist". Sie könnten Ihre Klassen sogar vorkompilieren, um eine Liste von Klassen zu erstellen, die von Ihnen instrumentiert werden müssen, um die Filterung zu Beginn etwas schneller zu machen.

Weitere Informationen finden Sie unter java.lang.instrumentation.

4

Sie haben interne Compiler-Klassen verwenden - Inspiration:

Aber es ist brinkmanship. Ihr Programm kompiliert nur auf Sun/OpenJDK und es kann Probleme in zukünftigen Versionen geben (interne API kann sich ändern). Obwohl es einmal kompiliert wurde, ist es Standard-Bytecode und wird überall ausgeführt.

BTW: Wenn Sie es in Eclipse verwenden möchten, sollten Sie einige spezielle Unterstützung dafür hinzufügen, da Eclipse nicht-standard Compiler verwendet. Ihr Design sollte komplexer sein und Sie sollten Ihrem Prozessor eine Abstraktionsebene hinzufügen - wie Lombok.

+0

Das sind tolle Beispiele. Vielen Dank! –