- Meta mène depuis plusieurs années un projet de transition de sa base de code Android de Java vers Kotlin
- L’entreprise gère aujourd’hui l’une des plus grandes bases de code Android au monde et en a déjà converti avec succès plus de la moitié vers Kotlin
- Meta a adopté une stratégie de développement Kotlin-first depuis 2020
- Pourquoi convertir l’ensemble du code :
- Pour exploiter au maximum les avantages de Kotlin en matière de « productivité accrue » et de « sûreté vis-à-vis des valeurs nulles », Meta a décidé de convertir aussi ses dizaines de millions de lignes de code Java existantes
- Renforcer la sûreté liée aux valeurs nulles et résoudre les problèmes d’une base de code mixte
- La compilation mixte (compilation simultanée de Java et Kotlin) ralentit le plus la vitesse de build
- Le code Java restant provoque des problèmes de sûreté des valeurs nulles : un code Java non null-safe devient une source potentielle de
NullPointerException (NPE) dans le graphe de dépendances
- Kotlin garantit la sûreté des valeurs nulles via des vérifications à l’exécution
Processus d’automatisation
- Au départ, l’équipe exécutait de façon répétée l’outil de conversion J2K de l’IDE IntelliJ
- Sur l’énorme base de code de Meta, cela nécessitait plus de 100 000 clics, avec plusieurs minutes par exécution
- En conséquence, cette méthode s’est révélée inefficace, faute de scalabilité
- Développement d’un outil d’automatisation : Kotlinator
- Processus de conversion en 6 étapes
- Deep Build : builder le code à convertir pour que l’IDE puisse résoudre tous les symboles, y compris les dépendances tierces et le code généré
- Preprocessing : basé sur l’outil maison de Meta, Editus. Environ 50 étapes, dont la gestion de la sûreté des valeurs nulles, des dépendances et divers contournements de J2K
- Headless J2K : adaptation de J2K pour qu’il puisse s’exécuter dans un environnement serveur
- Postprocessing : environ 150 étapes, dont des modifications spécifiques à Android, la sûreté des valeurs nulles et l’application du style Kotlin
- Linters : amélioration continue de la qualité de conversion via des corrections automatiques
- Corrections basées sur les erreurs de build : analyse des erreurs de build pour appliquer des correctifs supplémentaires
Rendre J2K headless
- Adaptation de J2K pour une exécution à distance :
- J2K était fortement couplé à l’IDE IntelliJ, ce qui rendait son exécution autonome difficile
- Au départ, l’équipe avait envisagé de l’exécuter via l’environnement de test IntelliJ, puis, après échange avec l’expert J2K de JetBrains (Ilya Kirillov), a basculé vers une approche d’inspection headless
- La mise en œuvre s’est faite via un plugin IntelliJ étendant la classe
ApplicationStarter et appelant la classe JavaToKotlinConverter de J2K
- Avantages de l’approche headless
- Résolution des problèmes liés à l’IDE local : les développeurs n’ont plus à cliquer eux-mêmes sur les boutons de l’IDE
- Conversion simultanée de plusieurs fichiers : possible désormais de traiter des volumes importants de fichiers
- Réduction du temps consommé : le temps de conversion lui-même est passé à environ 30 minutes, mais le temps réellement dépensé par les développeurs a fortement diminué
- Support du build et de la correction d’erreurs : des étapes utiles mais coûteuses en temps (comme les corrections après build) peuvent être exécutées automatiquement à distance
- Automatisation et revue de code
- Génération de batch jobs quotidiens via les systèmes internes de Meta :
- Création par lots de diffs selon des critères personnalisés (la version Meta des pull requests)
- Attribution automatique des reviewers, exécution des tests et validations, puis déploiement final des diffs approuvés
- Mise à disposition d’une interface web : les développeurs peuvent déclencher à distance la conversion de fichiers ou modules spécifiques
- Choix de l’ordre de conversion
- Aucun ordre strict n’est imposé :
- priorité aux fichiers en développement actif
- Kotlinator gère automatiquement le graphe de dépendances afin de résoudre les problèmes de compatibilité dans les fichiers externes
- exemple :
foo.getName() est automatiquement mis à jour en foo.name
Divers
- Ajout d’étapes personnalisées de preprocessing (Java->Java) et de postprocessing (Kotlin->Kotlin)
- Amélioration de la qualité de conversion à l’aide de l’outil interne Editus de Meta et de la bibliothèque PSI de JetBrains
- Nullsafe et NullAway
Présent et futur de la conversion vers Kotlin
- Plus de la moitié du code Java Android de Meta a déjà été convertie vers Kotlin (ou partiellement supprimée)
- Mais la moitié facile est terminée :
- le travail restant est complexe et massif
- pour parvenir à une conversion entièrement automatisable, il faudra ajouter des étapes sur mesure ou contribuer à l’amélioration de J2K
- dans le cas d’une conversion semi-automatique, l’objectif est d’améliorer Kotlinator afin de permettre des déploiements fluides et sûrs
- Meta estime que d’autres entreprises rencontrent probablement des problèmes similaires de conversion de code Android
- Meta partage les solutions obtenues au fil de l’amélioration et de l’optimisation de ses outils de conversion
- Proposition de collaboration :
- discussion avec d’autres développeurs sur le canal #j2k de Kotlinlang Slack
- le partage d’expériences et de solutions pourrait permettre de construire une meilleure expérience de conversion
Aucun commentaire pour le moment.