17 ポイント 投稿者 xguru 2022-11-04 | 4件のコメント | WhatsAppで共有
  • MetaのAndroidリポジトリは、Facebook、Instagram、Messenger、Quest などを含む巨大なリポジトリ
  • 現在、約1000万行を超えるKotlinコードを含んでいる

Kotlinへ移行した理由

  • 人気以外にも主な利点がある
    • Nullability : NPEはMetaで共通する問題だったためさまざまな対策をしてきたが、Kotlinの組み込みNullability処理のほうがはるかに強力で、作業もしやすい
    • 関数型プログラミング : Kotlinのインライン関数とラムダ式により、実行速度を落とさずにFPスタイルを適用できる
    • より短いコード
    • DSL / Type-safe Builder
  • もちろん無視できない小さな欠点もある
    • 別の言語を導入することで、混在したコードベースをかなり長い間維持しなければならない点
    • Kotlinは人気があるとはいえ、その人気にはJavaとのギャップがある。そのためツールが少なく、多くのKotlinツールはKotlinとJavaの相互運用性を考慮する必要があるため実装が複雑になる
  • 最大の懸念はビルド時間だった。Kotlinのビルド時間がJavaより遅くなる可能性があることは最初から分かっていた。遅いビルド時間は開発者体験にとって好ましくない

移行へのアプローチ

  • Kotlinへの移行は驚くほど簡単である一方で、非常に複雑でもあった
  • J2K(Java To Kotlin Converter)があるので便利ではあるが、それでも複雑だった
    • J2Kが常に正確とは限らず、JavaとKotlinの相互運用性がいくつかの極端なケースを生む
  • 移行には2つの選択肢があった
    • 新しいコードだけをKotlinで書き、既存コードの大半はJavaのままにする
      • 利点は作業量が少ないことだが、2言語の混在によってKotlinでプラットフォーム型を使うことになり、nullポインタ参照でクラッシュが発生することがある。
        また、Javaでは型パラメータをNullableとしてタグ付けできないことがある(最近まで)うえ、Kotlinのオーバーロード規則はnull許容かどうかを考慮するが、Javaのオーバーロード規則はそれを考慮しないという問題もある
    • すべての社内コードをKotlinに変換することを試みる

実際の移行方法

  • 2つの選択肢をどちらも検討したうえで、すべてのコードをKotlinに変換することを目標に決定
    • 最初はやや遅かったが、いくつかのブロッカーを解消してからは大規模変換が可能になった
    • 現在はFacebook、Messenger、InstagramそれぞれのAndroidアプリが100万行のKotlinコードを含んでおり、変換率は徐々に上がっている
    • 現在、Androidコードベース全体には1000万行のKotlinコードがある

Unblocking

  • 変換を始めた当初、いくつかの問題が発生した
    • バイトコードのパターンのため、Redexの更新が必要だった
    • 一部の内部ライブラリは性能のためにバイトコード変換を行っており、これがKotlinでは動作しなかった
    • 内部で多くの最適化をしているなら、似たような問題が起こるはず
  • 既存ツールにも問題が発生した
    • コードレビューやWikiなどでKotlinのシンタックスハイライトが効かなかったため、Pygmentsを更新した
    • Kotlinフォーマッタである Ktfmt を別途開発した

移行を加速する

  • ツールの準備が整い、コードをKotlinへ変換する準備ができた
  • しかし各移行では、手作業で進めなければならないボイラープレートコードが多かった
  • J2Kは汎用ツールなので、コードそのものを理解しているわけではない。このため多くの手作業が必要だった
    • たとえばJUnitのテスト規則のようなもの
  • そこでJ2Kを3段階パイプラインの中央に置いた
    • まずJavaパッケージを1つ取り出し、Kotlinへ変換する準備を行う。バグ修正や内部ツールに必要な変換もここで行う
    • 次にスクリプトでJ2Kを自動実行する
    • 最後に新しいKotlinファイルを後処理する。これが最も重要。自動リファクタリングやリンタなどをヘッドレスモードで実行する
  • 自動化ですべての問題を解決できるわけではないが、共通するものを優先して対処した

Kotlin移行で学んだこと

  • コード量が減った
  • 実行速度は維持
  • ビルドサイズは問題ではない
  • 長くなったビルド時間の問題を解決 : KSP(Kotlin Symbol Processing API)を使用

4件のコメント

 
sungeuns 2022-11-04

良い記事の共有ありがとうございます。個人的に Kotlin を最初に使ったときは、Java より便利な点が多くて良いと思いましたし、これからは Kotlin が主流になるのではないかとも感じていましたが、しばらく使ってみると、まだ Java のほうが良いと思える部分も多いですね。

  • 言語自体は Kotlin のほうが確かに便利だと思います。
  • Java は ecosystem やトラブルシューティング資料が豊富なのに比べて、Kotlin は少し不足している部分があります。
  • JDK のバージョンや Kotlin のバージョンによっては、Java だけを使っていれば遭遇しなくて済むバグや問題がかなりあります。
    Android は Kotlin でも問題ないと思いますが、他の環境(Spring など)では、安定性が重要ならまだ Java のほうがより良い選択だと思います。
 
roxie 2022-11-05

安定性の事例を一つだけ教えていただけますか? まだ経験が浅く、そのような事例に出会ったことがないので、とても気になります。

 
ganadist 2022-11-06

JetBrainsが次々とリリースを出しているからかもしれませんが、意外とコンパイラのバグ修正が多いです。
https://github.com/JetBrains/kotlin/releases/tag/v1.7.20

コンパイラ自体が落ちることもしばしばありますし(これはまだリリース前なのでその点では大丈夫ですが)、生成物にも時々バグが含まれます。

さらにAndroidの場合は、R8 bytecode optimiser も Kotlin のバージョンを選びます。
なぜなら、Kotlin コード専用の最適化機能があるのに、これに関する公式の互換性テーブル文書(Android Gradle Plugin : Kotlin Version)がありません。..
そのため、Android プロジェクトで Kotlin のバージョンを変更するときは注意が必要です;;;

関連バグレポート : https://issuetracker.google.com/issues/207397158

 
roxie 2022-11-06

ありがとうございます。深くて広い世界があるのですね..