Lomboks Java 9+ Support-Story

TL;DR

Über Lombok

Lombok Java9 + IntelliJ-Unterstützung

Es gab ein Problem, das der Build mit Java9 + IntelliJ nicht bestanden hat, und ich habe es behoben, aber ich werde schreiben, welche Art von Korrektur ich vorgenommen habe.

Ich habe ein einfaches Klassendiagramm erstellt, weil ich es nicht erklären kann, ohne die interne Struktur des verwandten Teils zu kennen (nur den Teil, der mit dieser Korrektur zusammenhängt. Ein kleiner Teil des Ganzen).

LombokClassDiagram.png

Klassen im JDK

Erstens enthält das Paket javax.tools die folgenden Klassen als öffentliche Klassen des JDK. Alle sind Klassen, mit denen Quellcode und Klassendateien bearbeitet werden.

Die Implementierungsklasse für die obige Schnittstelle befindet sich im Paket com.sun.tools.javac. Dies ist die innere Klasse des JDK.

Implementierung rund um den Dateizugriff von Lombok

LombokFileObject Lombok verwendet den Annotation Processor, um eine AST-Konvertierung durchzuführen, unterbricht jedoch zusätzlich zur AST-Konvertierungsverarbeitung auch das Schreiben von Klassendateien. (Weitere Informationen finden Sie unter PostCompiler.wrapOutputStream (). Das Umschreiben des Byte-Codes wird durchgeführt. Wir entfernen unnötigen Code um @SneakyThrows und null check.) (2018/2/22 Korrigiert, weil ein Erkennungsfehler aufgetreten ist)

InterceptiongJavaFileObject bietet eine Unterbrechung zum Schreiben einer Datei. Diese Klasse wird auf der Javac-Seite beim Initialisieren von [LombokProcessor] angezeigt (https://github.com/rzwitserloot/lombok/blob/master/src/core/lombok/javac/apt/LombokProcessor.java). Es ist wie geworden. Diese Klasse implementiert die Schnittstelle LombokFileObject. LombokFileObject erbt von JavaFileObject.

Lombok gibt dies zur Verarbeitung an die Javac-Seite weiter, aber es gibt ein Problem. Die Javac-Seite soll das obige BaseFileObject oder PathFileObject intern anfordern (innen gegossen), damit sie die Implementierung der JavaFileObject-Schnittstelle nicht akzeptiert (ehrlich gesagt, dies ist eine verdammte Implementierung von Javac). Ich denke,,,) Daher müssen Sie eine Klasse vorbereiten, die BaseFileObject oder PathFileObject erbt, und diese auf die Lombok-Seite übertragen. Lombok bietet dazu die folgenden drei Wrapper-Klassen an.

Zu diesem Zeitpunkt fühle ich mich etwas unangenehm, aber der Punkt ist, dass wir Wrapper mit unterschiedlichen Implementierungen für jede Version von Javac vorbereitet haben. Es ist nicht zu leugnen, dass es in Zukunft immer mehr geben wird, wenn die JDK-Version veröffentlicht wird. Beide Klassen delegieren einfach alle Methoden an LombokFileObject.

LombokFileObjects Es ist endlich die Produktion von hier. Verwenden Sie LombokFileObjects, um eine Verarbeitung wie das Umschließen von JavaFileManager durchzuführen.

Erstens verfügt LombokFileObjects über eine Compiler-Schnittstelle. Dies ist eine Klasse zum Umschließen eines JavaFileObject und zum Zurückgeben eines LombokFileObject (implementiert mit der Methode wrap ()). Dies hat auch eine andere Klassenimplementierung für Javac 6, 7, 9. Jedes ist eine Implementierung, die den oben erwähnten Javac [679] BaseFileObjectWrapper zurückgibt.

Der Compiler gibt die Methode LombokFileObjects.getCompiler (JavaFileManager jfm) zurück. Die Implementierung überprüft die im Argument übergebene JavaFileManager-Implementierungsklasse und gibt den entsprechenden Compiler zurück. Es gibt eine Liste bekannter JavaFileManager-Implementierungsklassennamen mit dem Namen KNOWN_JAVA9_FILE_MANAGERS, die voller unangenehmer Gefühle ist.

Probleme und Lösungen in JDK9

Die Compiler-Implementierung für javac9 ist Java9Compiler. Diese Implementierung ist etwas komplizierter als 6 und 7. Dies liegt daran, dass PathFileObject, die Basisklasse für Java9BaseFileObjectWrapper, BaseFileManager in seinem Konstruktor benötigt.

Wenn der an getCompiler () übergebene JavaFileManager eine Instanz von BaseFileManager ist, ist dies in Ordnung (Sie können ihn umwandeln). Dies kann aber eine andere Klasse sein. Wenn beispielsweise von IntelliJ aufgerufen wird, wird eine Klasse übergeben, die StandardJavaFileManager implementiert. In diesem Fall funktioniert das Casting nicht.

Aus diesem Grund habe ich eine neue FileManagerWrapper-Klasse erstellt, die von BaseFileManager erbt, und sie so geändert, dass sie für die Delegierung verwendet wird. Die Pull-Anfrage lautet hier. Dieser Fix wurde erfolgreich integriert und wird derzeit als 1.16.20 veröffentlicht. Jetzt habe ich es geschafft, dass der Build IntelliJ korrekt weitergibt.

Wo

Zukünftige Aufgaben

Lombok stützt sich stark auf die innere Klasse des JDK (com.sun.). Daher funktioniert es nicht, wenn sich die interne Struktur mit einem JDK-Update ändert. Insbesondere der Aktualisierungszyklus von Java war bisher relativ lang, wird jedoch alle 6 Monate aktualisiert (obwohl dies bei LTS alle 3 Jahre der Fall ist), sodass ich denke, dass dies große Auswirkungen haben wird. Tatsächlich steckt es bereits in OpenJDK10 Early Access fest. Pfui.

Ein weiteres Problem besteht darin, dass es nicht nur vom JDK, sondern auch von der Implementierung von IDEs und Build-Tools (wie Maven / Gradle) betroffen ist. Da die Kernentwicklungsmitglieder von Lombok auf Eclipse basieren, kann sich die Unterstützung für IntelliJ, Netbeans usw. verzögern. Ich bin der Haupt-IntelliJ, also werde ich das Problem beheben und einen Beitrag leisten.

Wenn Sie Lombok fest anwenden, sollten Sie sich bewusst sein, dass solche Risiken bestehen.

Recommended Posts

Lomboks Java 9+ Support-Story
Statische Java-Geschichte
Unterstützung für SonarQube Java 11
Java-Support-Zeitraum
Supportzeitraum für Java8, 9, 10
Die Geschichte des Java-Initialisierers
Java generische Geschichte
Eine Geschichte über die Java 11-Unterstützung für Webdienste
Zusammenfassung der Java-Unterstützung 2018
[Java] Aizu Online Judges Geschichte 2
[Java] Aizu Online Judges Geschichte 1
C # und Java überschreiben Story
[Java Edition] Geschichte der Serialisierung
Die Geschichte von Java Gold SE8
Java
Java
CORS-Unterstützung mit Angular + Rest (Java)
Geschichte von paiza.jp [Java Standard Input Solution]
Die Geschichte von Java SE11 Silber erhalten
Die Geschichte des Schreibens von Java in Emacs