17 points par xguru 2022-11-04 | 4 commentaires | Partager sur WhatsApp
  • Le repo Android de Meta est un immense dépôt qui contient Facebook, Instagram, Messenger, Quest, etc.
  • Il contient actuellement plus de 10 millions de lignes de code Kotlin.

Pourquoi passer à Kotlin

  • Au-delà de sa popularité, ses principaux avantages
    • Nullability : les NPE étaient un problème récurrent chez Meta, et malgré diverses contre-mesures, la gestion intégrée de la nullabilité de Kotlin est bien plus puissante et plus facile à utiliser.
    • Programmation fonctionnelle : les fonctions inline et les expressions lambda de Kotlin permettent d’adopter un style FP sans dégrader les performances d’exécution.
    • Code plus concis
    • DSL / Type-safe Builder
  • Bien sûr, il y a aussi quelques inconvénients non négligeables
    • Le fait d’introduire un autre langage implique de devoir maintenir un codebase mixte pendant assez longtemps.
    • Kotlin est populaire, mais il existe encore un écart avec Java à ce niveau. Il y a donc moins d’outils, et beaucoup d’outils Kotlin doivent prendre en compte l’interopérabilité Kotlin & Java, ce qui complique leur implémentation.
  • La plus grande inquiétude concernait le temps de build. Dès le départ, ils savaient que le temps de build Kotlin pouvait être plus lent que celui de Java. Un build lent nuit à l’expérience développeur.

Comment ils ont abordé la migration

  • La migration vers Kotlin a été étonnamment simple, tout en étant très complexe.
  • Il existe J2K (Java To Kotlin Converter), ce qui aide, mais cela reste compliqué.
    • J2K n’est pas toujours exact, et l’interopérabilité entre Java et Kotlin crée quelques cas limites.
  • Deux options existaient pour la migration
    • N’écrire que le nouveau code en Kotlin et laisser la majorité du code en Java
      • L’avantage est de réduire la charge de travail, mais l’usage de types de plateforme dans Kotlin à cause du mélange des deux langages peut entraîner des déréférencements de pointeur nul et donc des crashs.
        De plus, Java ne peut pas marquer les paramètres de type comme Nullable (du moins jusqu’à récemment), et les règles de surcharge de Kotlin prennent en compte l’acceptation de null, contrairement à celles de Java.
    • Tenter de convertir tout le code interne vers Kotlin

Comment ils ont migré

  • Les deux options ont été étudiées, puis ils ont décidé de viser la conversion de tout le code vers Kotlin.
    • Au début, c’était un peu lent, mais une fois certains blockers résolus, il est devenu possible de convertir à grande échelle.
    • Aujourd’hui, les applications Android de Facebook, Messenger et Instagram contiennent chacune 1 million de lignes de code Kotlin, et le taux de conversion continue d’augmenter.
    • L’ensemble du codebase Android compte actuellement 10 millions de lignes de code Kotlin.

Unblocking

  • Quelques problèmes sont apparus au début de la conversion
    • Des motifs de bytecode ont nécessité une mise à jour de Redex.
    • Certaines bibliothèques internes faisaient de la transformation de bytecode pour des raisons de performance, et cela ne fonctionnait pas avec Kotlin.
    • Si vous avez déjà beaucoup optimisé en interne, des problèmes similaires peuvent apparaître.
  • Les outils existants ont aussi rencontré des problèmes
    • Comme la coloration syntaxique Kotlin ne fonctionnait pas dans la revue de code, le wiki, etc., ils ont mis à jour Pygments.
    • Ils ont aussi développé séparément Ktfmt, un formateur Kotlin.

Accélérer la migration

  • Les outils étaient prêts, donc le code pouvait être converti vers Kotlin.
  • Mais chaque migration comportait encore beaucoup de boilerplate à traiter manuellement.
  • J2K est un outil générique, donc il ne comprend pas le code lui-même. Cela impliquait beaucoup de travail manuel.
    • Par exemple pour les règles de test JUnit.
  • Ils ont donc placé J2K au milieu d’un pipeline en 3 étapes
    • D’abord, ils prenaient un package Java et le préparaient à la conversion vers Kotlin, avec correction de bugs et conversions nécessaires pour les outils internes.
    • Ensuite, ils exécutaient automatiquement J2K via des scripts.
    • Enfin, ils post-traitaient les nouveaux fichiers Kotlin. C’était l’étape la plus importante. Des refactorings automatiques et des linters étaient exécutés en mode headless.
  • L’automatisation ne règle pas tous les problèmes, mais ils ont priorisé les cas les plus courants.

Ce qu’ils ont appris de la migration vers Kotlin

  • Le code est devenu plus court.
  • Les performances d’exécution ont été maintenues.
  • La taille du build n’est pas un problème.
  • Le problème de l’allongement du temps de build a été résolu grâce à KSP (Kotlin Symbol Processing API).

4 commentaires

 
sungeuns 2022-11-04

Merci de partager cet excellent article. Personnellement, quand j’ai commencé à utiliser Kotlin, j’ai apprécié ses nombreux aspects plus pratiques que Java, et je me suis dit qu’à l’avenir Kotlin allait peut-être s’imposer comme le standard. Mais à force de l’utiliser, j’ai aussi remarqué qu’il y a encore pas mal de points où Java me semble meilleur.

  • Je pense que le langage en lui-même est clairement plus pratique en Kotlin
  • Par rapport à la richesse de l’écosystème Java et à l’abondance des ressources de troubleshooting, Kotlin reste un peu en retrait sur certains points.
  • Selon la version du JDK ou de Kotlin, il y a pas mal de bugs ou de problèmes qu’on n’aurait pas en n’utilisant que Java.
    Je pense qu’Android peut très bien passer à Kotlin, mais dans d’autres environnements (Spring, par exemple), si la stabilité est importante, Java me semble encore être un meilleur choix.
 
roxie 2022-11-05

Pourriez-vous me donner ne serait-ce qu’un seul exemple de stabilité ? Je n’ai pas encore rencontré ce genre de cas faute d’expérience, donc je suis très curieux.

 
ganadist 2022-11-06

Je ne sais pas si c’est parce que JetBrains enchaîne les releases à toute vitesse, mais il y a étonnamment beaucoup de correctifs de bugs du compilateur.
https://github.com/JetBrains/kotlin/releases/tag/v1.7.20

Il arrive aussi assez souvent que le compilateur plante complètement (bon, tant que c’est avant la mise en production, ça reste acceptable), et des bugs se retrouvent aussi parfois dans les artefacts générés.

De plus, dans le cas d’Android, l’optimiseur de bytecode R8 est lui aussi sensible à la version de Kotlin.
En effet, il existe des fonctions d’optimisation dédiées au code Kotlin, mais il n’existe pas de document officiel avec une table de compatibilité à ce sujet (Android Gradle Plugin : Kotlin Version).
Il faut donc faire attention lorsqu’on change la version de Kotlin dans un projet Android ;;;

Bug report lié : https://issuetracker.google.com/issues/207397158

 
roxie 2022-11-06

Merci. Il y a donc un univers vaste et profond..