Meta'nın Android geliştirmesini Java'dan Kotlin'e geçirme nedeni ve yöntemi
(engineering.fb.com)- Meta'nın Android repo'su; Facebook, Instagram, Messenger ve Quest gibi uygulamaları içeren devasa bir depo
- Şu anda yaklaşık 10 milyondan fazla satır Kotlin kodu içeriyor
Kotlin'e geçişin nedenleri
- Popülerliğinin dışında başlıca avantajlar
- Nullability: NPE, Meta'da yaygın bir sorundu ve buna karşı çeşitli önlemler alınmıştı, ancak Kotlin'in yerleşik nullability yönetimi çok daha güçlü ve kullanımı daha kolay
- Fonksiyonel programlama: Kotlin'in inline fonksiyonları ve lambda ifadeleri, çalışma hızı düşmeden FP stilinin uygulanmasını sağlıyor
- Daha kısa kod
- DSL / Type-safe Builder
- Elbette göz ardı edilemeyecek bazı dezavantajlar da var
- Başka bir dili devreye almak, uzun süre karma bir kod tabanını sürdürmek zorunda kalmak anlamına geliyor
- Kotlin popüler olsa da popülerlik açısından Java ile arasında hâlâ bir fark var. Bu yüzden araç sayısı daha az ve birçok Kotlin aracı Kotlin & Java birlikte çalışabilirliğini hesaba katmak zorunda olduğu için uygulaması daha karmaşık
- En büyük endişe derleme süresiydi. En başından beri Kotlin derleme süresinin Java'dan daha yavaş olabileceğini biliyorlardı. Yavaş derleme süresi geliştirici deneyimi için iyi değil
Migrasyona yaklaşım biçimleri
- Kotlin'e geçiş şaşırtıcı derecede kolaydı, ama aynı zamanda çok karmaşıktı
- J2K (Java To Kotlin Converter) olduğu için kullanışlıydı, ama yine de iş karmaşıktı
- J2K her zaman doğru sonuç vermiyor ve Java ile Kotlin'in birlikte çalışabilirliği bazı uç durumlar yaratıyor
- Migrasyon için iki seçenek vardı
- Sadece yeni kodu Kotlin ile yazmak ve kodun büyük kısmını Java olarak bırakmak
- Avantajı daha az iş gerektirmesi, ancak iki dilin karışık kullanımı nedeniyle Kotlin'de platform type kullanılması null pointer dereference kaynaklı crash'lere yol açabiliyordu.
Ayrıca Java'da tip parametrelerini Nullable olarak etiketleyememe (yakın zamana kadar) ve Kotlin'in overload kurallarının null kabulünü hesaba katmasına karşın Java'nın overload kurallarının bunu dikkate almaması gibi sorunlar da vardı
- Avantajı daha az iş gerektirmesi, ancak iki dilin karışık kullanımı nedeniyle Kotlin'de platform type kullanılması null pointer dereference kaynaklı crash'lere yol açabiliyordu.
- Tüm şirket içi kodu Kotlin'e dönüştürmeyi denemek
- Sadece yeni kodu Kotlin ile yazmak ve kodun büyük kısmını Java olarak bırakmak
Migrasyonu nasıl yaptılar
- Her iki seçeneği de değerlendirdiler ve hedef olarak tüm kodu Kotlin'e dönüştürmeye karar verdiler
- Başta biraz yavaştı, ancak bazı engeller çözüldükten sonra büyük ölçekte dönüşüm mümkün oldu
- Şu anda Facebook, Messenger ve Instagram'ın Android uygulamalarının her biri 1 milyon satır Kotlin kodu içeriyor ve dönüşüm oranı giderek artıyor
- Şu anda toplam Android kod tabanında 10 milyon satır Kotlin kodu var
Önü açma çalışmaları
- İlk dönüşüm başladığında bazı sorunlar ortaya çıktı
- Bytecode pattern'leri nedeniyle Redex'in güncellenmesi gerekti
- Bazı iç kütüphaneler performans nedeniyle bytecode transforming yapıyordu ve bu Kotlin'de çalışmıyordu
- İçeride çok sayıda optimizasyon yaptıysanız benzer sorunlar ortaya çıkacaktır
- Mevcut araçlarda da sorunlar yaşandı
- Kod inceleme / wiki gibi yerlerde Kotlin sözdizimi vurgulaması yoktu, bu yüzden Pygments güncellendi
- Ayrı olarak Ktfmt adlı bir Kotlin formatter geliştirildi
Migrasyonu hızlandırmak
- Araçlar hazırdı ve kodu Kotlin'e dönüştürmek için ortam hazırlanmıştı
- Ancak her migrasyonda elle yapılması gereken çok sayıda boilerplate kod vardı
- J2K genel amaçlı bir araç olduğu için koda dair bir anlayışı yoktu. Bu nedenle çok sayıda manuel işlem gerekiyordu
- Örneğin JUnit test kuralları gibi
- Bu yüzden J2K'yi 3 aşamalı bir pipeline'ın ortasına yerleştirdiler
- İlk olarak bir Java package alınarak Kotlin'e dönüştürmeye hazır hâle getirildi. Hata düzeltmeleri yapıldı ve iç araçların ihtiyaç duyduğu dönüşümler uygulandı
- İkinci olarak script aracılığıyla J2K otomatik çalıştırıldı
- Üçüncü olarak yeni Kotlin dosyalarına son işlem uygulandı. En önemli aşama buydu. Otomatik refactoring / linter gibi işlemler headless modda çalıştırıldı
- Otomasyon tüm sorunları çözmese de önce ortak olanlara öncelik verdiler
Kotlin migrasyonundan çıkarılan dersler
- Kod uzunluğu azaldı
- Çalışma hızı korundu
- Build boyutu sorun değil
- Uzayan build süresi sorunu çözüldü: KSP (Kotlin Symbol Processing API) kullanımı
4 yorum
Güzel yazıyı paylaştığınız için teşekkürler. Ben de kişisel olarak
kotlini ilk kullanırkenjavaya göre daha kullanışlı birçok yanı olduğu için hoşuma gitmişti ve ileridekotlinin ana akım olacağını düşünmüştüm; ama biraz kullandıktan sonra, hâlâjavanın daha iyi olduğunu düşündüğüm birçok nokta da olduğunu gördüm.kotlinin kesinlikle daha kullanışlı olduğunu düşünüyorum.javanın ekosistemi ve troubleshooting kaynakları çok daha fazla; buna kıyaslakotlinbu konuda biraz eksik kalıyor.jdksürümü ya dakotlinsürümüne bağlı olarak, yalnızca Java kullansanız yaşamayacağınız epey hata ve sorun olabiliyor.Android tarafında
kotline geçmenin sorun olmayacağını düşünüyorum ama diğer ortamlarda (Springgibi..) istikrar önemliyse, şimdilikJavadaha iyi bir seçim gibi görünüyor.İstikrarla ilgili tek bir örnek verebilir misiniz? Deneyimim az olduğu için henüz böyle bir örnekle karşılaşmadım; bu yüzden çok merak ediyorum.
JetBrains durmadan sürüm çıkardığı için mi bilmiyorum ama şaşırtıcı derecede çok derleyici hata düzeltmesi var.
https://github.com/JetBrains/kotlin/releases/tag/v1.7.20
Derleyicinin kendisinin çökmesi de zaman zaman oluyor (bu, en azından dağıtımdan önce olduğu için o kadar sorun değil), fakat çıktı ürünlerinde de sık sık hatalar bulunuyor.
Üstelik Android tarafında R8 bytecode optimizer da Kotlin sürümüne duyarlı.
Çünkü Kotlin koduna özel optimizasyon özellikleri var, ancak bununla ilgili resmi bir uyumluluk tablosu belgesi (Android Gradle Plugin : Kotlin Version) yok..
Bu yüzden Android projelerinde Kotlin sürümünü değiştirirken dikkatli olmak gerekiyor;;;
İlgili hata raporu: https://issuetracker.google.com/issues/207397158
Teşekkürler. Ne kadar derin ve geniş bir dünya varmış..