Histoire de support Java 9+ de Lombok

TL;DR

À propos de Lombok

Prise en charge de Lombok Java9 + IntelliJ

Il y avait un problème que la construction n'a pas réussi avec Java9 + IntelliJ et je l'ai corrigé, mais j'écrirai le type de correctif que j'ai fait.

J'ai préparé un diagramme de classes simple car je ne peux pas expliquer sans connaître la structure interne de la partie associée (uniquement la partie liée à cette correction. Une petite partie de l'ensemble)

LombokClassDiagram.png

Cours dans le JDK

Tout d'abord, il existe les classes suivantes dans le package javax.tools en tant que classes publiques du JDK. Toutes sont des classes utilisées pour manipuler le code source et les fichiers de classe.

La classe d'implémentation de l'interface ci-dessus se trouve sous le package com.sun.tools.javac. Il s'agit de la classe interne du JDK.

Implémentation autour de l'accès aux fichiers de Lombok

LombokFileObject Lombok utilise le processeur d'annotation pour la conversion AST, mais il interrompt également l'écriture du fichier de classe en plus du traitement de conversion AST. (Voir PostCompiler.wrapOutputStream () pour plus de détails. La réécriture de code d'octet est effectuée. Supprimez le code inutile autour de @SneakyThrows et de la vérification nulle.) (2018/2/22 Corrigé car il y avait une erreur de reconnaissance)

InterceptiongJavaFileObject fournit une interruption pour écrire un fichier. Cette classe se reflète du côté Javac lors de l'initialisation de LombokProcessor. C'est devenu comme. Cette classe implémente l'interface LombokFileObject. LombokFileObject hérite de JavaFileObject.

Lombok transmet cela au côté javac pour le traitement, mais il y a un problème. Le côté javac est censé demander le BaseFileObject ou PathFileObject ci-dessus en interne (cast à l'intérieur), donc il n'acceptera pas l'implémentation de l'interface JavaFileObject (honnêtement, c'est une putain d'implémentation de javac) Je pense,,,) Par conséquent, vous devez préparer une classe qui hérite de BaseFileObject ou PathFileObject et la transférer du côté Lombok. Lombok fournit les trois classes Wrapper suivantes pour ce faire.

À ce stade, je me sens un peu désagréable, mais le fait est que nous avons préparé des wrappers avec des implémentations différentes pour chaque version de javac. Il est indéniable qu'il y en aura de plus en plus dans le futur à mesure que la version JDK montera. Les deux classes délèguent simplement toutes les méthodes à LombokFileObject.

LombokFileObjects C'est finalement la production d'ici. Utilisez LombokFileObjects pour effectuer un traitement tel que l'encapsulation de JavaFileManager.

Tout d'abord, LombokFileObjects a une interface de compilateur. Il s'agit d'une classe pour encapsuler JavaFileObject et renvoyer LombokFileObject (implémenté avec la méthode wrap ()). Cela a également une implémentation de classe différente pour javac 6, 7, 9. Chacun est une implémentation qui renvoie le Javac [679] BaseFileObjectWrapper mentionné ci-dessus.

Le compilateur renvoie la méthode LombokFileObjects.getCompiler (JavaFileManager jfm). L'implémentation examine la classe d'implémentation JavaFileManager passée dans l'argument et renvoie le compilateur approprié. Il existe une liste de noms de classes d'implémentation JavaFileManager connus appelés KNOWN_JAVA9_FILE_MANAGERS, qui regorge de sentiments désagréables.

Problèmes et solutions dans JDK9

L'implémentation du compilateur pour javac9 est Java9Compiler. Cette implémentation est un peu plus compliquée que 6 et 7. En effet, PathFileObject, la classe de base de Java9BaseFileObjectWrapper, requiert BaseFileManager dans son constructeur.

Si le JavaFileManager passé à getCompiler () est une instance de BaseFileManager, c'est correct (il suffit de le convertir). Mais cela peut être une autre classe. Par exemple, lorsqu'elle est appelée depuis IntelliJ, une classe qui implémente StandardJavaFileManager est transmise. Dans ce cas, la diffusion ne fonctionnera pas.

Pour cette raison, j'ai créé une nouvelle classe FileManagerWrapper qui hérite de BaseFileManager et l'ai modifiée pour l'utiliser pour la délégation. La demande d'extraction est ici. Ce correctif a été intégré avec succès et est actuellement publié sous la version 1.16.20. Maintenant, j'ai réussi à faire passer correctement la construction sur IntelliJ.

Tâches futures

Lombok s'appuie fortement sur la classe interne du JDK (com.sun.), Donc cela ne fonctionnera pas si la structure interne change avec une mise à jour JDK. En particulier, le cycle de mise à jour de Java a été relativement long jusqu'à présent, mais il sera mis à jour tous les 6 mois (bien que ce soit tous les 3 ans pour LTS), donc je pense que cela aura un impact important. En fait, il est déjà bloqué dans OpenJDK10 Early Access. Pouah.

Un autre problème est qu'il est affecté non seulement par le JDK mais aussi par l'implémentation des IDE et des outils de construction (tels que Maven / Gradle). Étant donné que les principaux membres de développement de Lombok sont basés sur Eclipse, la prise en charge d'IntelliJ, Netbeans, etc. peut être retardée. Je suis le principal IntelliJ, donc je vais le réparer et contribuer.

Si vous utilisez Lombok fermement, vous devez être conscient qu'il existe de tels risques.

Recommended Posts

Histoire de support Java 9+ de Lombok
Histoire statique Java
Prise en charge de SonarQube Java 11
Période de support Java
Période de support Java8, 9, 10
L'histoire de l'initialiseur Java
Histoire générique Java
Une histoire sur la prise en charge de Java 11 pour les services Web
Résumé du support Java 2018
[Java] Aizu Online Judge's story 2
[Java] Histoire du juge Aizu Online 1
Histoire de remplacement C # et Java
[Édition Java] Histoire de la sérialisation
Histoire du passage de Java Gold SE8
Java
Java
Prise en charge de CORS avec Angular + Rest (Java)
Histoire de paiza.jp [solution d'entrée standard Java]
L'histoire reçue par Java SE11 silver
L'histoire de l'écriture de Java dans Emacs