11 Ağustos 2021

Java Platform Modular System (JPMS) 1

ile gökhan

Gerçek hayatta bir proje, paketler altında gruplanmış yüzlerce ve ya binlerce sınıftan oluşacaktır. Bu paketler, Java arşiv dosyalarında (JAR) gruplandırılmıştır. Uygulamalar çeşitli amaçlara hizmet etmek için JAR dosyalarını barındırırlar. Örneğin; uygulamamız Spring, JUnit gibi kütüphaneler kullananabilir. Bu jarların uyumlu sürümlerini kullanmak önemlidir. Bu karmaşık bağımlılık zinciri ve minimum sürümleri kullanma zorunluluğu JAVA topluluğu tarafından JAR Hell (JAR Cehennemi) olarak adlandırılır. Uygulamamızda kullanacağımız kütüphane yanlış sürüm olabilir bu durum runtime’da class not found exception hatası verebilir. Bu tür bağımlılık karmaşasını çözmek için JAVA 9 ile beraber Java Platform Modular System (JPMS) tanıtıldı.

Bir modülün temel amacı, geliştiricilere belirli bir işlevsellik kümesi sunmak için paket seviyesinin üstünde gruplama yapmayı sağlamaktır. Modül yapısı ile modülümüzün dışarıdan hangi paketlere erişebileceğini ve modülümüzdeki paketlerden hangilerini dışarıya açacağımızı belirleyebiliyoruz. Tüm bu erişim ayarlamalarını module-info.java isimli dosya ile yapılmaktadır. Örnek bir modül yapısı aşağıdaki gibidir:

JPMS’ in sağladığı yararlar:

  • Daha iyi erişim kontrolü: Java’da erişim kontrolünü public, protected, default, private erişim kontrollerini kullanarak sağlamaktayız. Bunlar belirli bir sınıfa veya pakete erişim kısıtlamasına izin verir. Ancak herhangi bir A modülündeki paketlerin, dışarıdaki herhangi bir kod tarafından kullanılabilir hale getirmeden sadece B modülündeki paketler tarafından kullanılmasını istiyorsak bu erişim kontrolleri işe yaramayacaktır. Bu problemi modüler sistem çözmektedir. Modüler sistem, erişim kontrollerinin 5. seviyesi olarak adlandırılabilir. Böylece daha güçlü kapsülleme sağlanır.
  • Bağımlılık Yönetiminin daha net olması: Kürüphanelerin diğer kütüphanelere bağlı olması yaygındır. Örneğin JUnit4 test kütüphanesi eşleştirme mantığı için Hamcrest kütüphanesine bağlıdır. Geliştirici Hamcrest’i eklemeyi unuttuysa runtime anında kod hata verecektir. Eğer modüler bir yapı kullanılırsa, bağımlılıklar module-info.java dosyasında belirtilir, Java Hamcrest’in modül içerisinde olmadığını söyler ve unuttuğumuzu hemen anlamış olurduk.
  • Özelleştirilmiş Java yapıları: JDK 150 MB’dan büyük, JRE bile ayrı bir indirme dosyası olarak sunulduğunda daha da büyük bir hale geliyordu. Geçmişte Java bunu kompakt bir profille çözmeye çalıştı. 3 kompakt profil yerleşik Java sınıflarının bir alt kümesini sağladı, böylece mobil ve gömülü cihazlar için daha küçük bir paket olacaktı. Ancak kompakt profiller esneklikten yoksundu. İşletim sistemine özel programlarla çalışmak için gerekli olan Java Native Interface (JNI) gibi geliştiricilerin kullanma olasılığı düşük olan bir çok paket dahil edildi. Aynı zamanda Image I/O gibi diğer paketleri kullanmak tam bir JRE’ yi kullanmayı gerektiriyordu. JPMS, geliştiricilerin gerçekte ihtiyaç duydukları modülleri belirleme imkanı tanır. Bu durum uygulamanın ihtiyaç duyduğu şeye göre özelleştirilmiş daha küçük bir runtime görüntüsü oluşturmayı mümkün kılar. Kullanıcılar Java’yı hiç yüklemeden bu görüntüyü çalışıtırabilir. Bu runtime görüntüsü için glink adlı bir araç kullanılır. Daha küçük ölçekli bir paket oluşur ve bu durum güvenliği de artırır. Örneğin; AWT kütüphanesi projenizde kullanılmıyor ve AWT’de güvenlik açığı varsa, AWT paketi olmayan bir runtime görüntüsü sizi bu güvenlik açığından koruyacaktır.
  • Geliştirilmiş Performans : Java JPMS sayesinde hangi modüllerle bağımlılığı olduğunu bildiğinde, yalnızca bakması gereken paketlere runtime’da bakar. Bu büyük programlar için başlatma süresini iyileştirir ve çalışması için daha az bellek gerektirir.
  • Benzersiz Paket : Aynı paketin iki Jar dosyasında olması durumu oluşabilir. JPMS bu durumu engeller. Bir paketin yalnızca bir modül tarafından kullanılmasını sağlar.

Module-info.java dosyası mutlaka modülün kök dizininde olmalıdır. İçi boş bir module-info.java dosyası oluşturulabilir. Bir sonraki yazımızda bir modülü nasıl oluşturacağmızı, nasıl konfigure edeceğimizi konuşacağız.