Bir Kez Yaz, Her Yerde Çalıştır: Java gerçekte ne kadar geriye dönük uyumludur?

Adanali

Member


  1. Bir Kez Yaz, Her Yerde Çalıştır: Java gerçekte ne kadar geriye dönük uyumludur?

1995’ten başlayarak Sun Microsystems, Java platformunun reklamını “Bir Kez Yaz, Her Yerde Çalıştır” (WORA) sloganı altında yaptı. Bu slogan, Java’nın iki farklı avantajını birleştirdi: JVM’yi (Java Sanal Makinesi) kullanarak, derlenmiş programlar bir JVM’nin mevcut olduğu tüm platformlarda çalışabilir. Örneğin, Windows’ta derlenen bir Java uygulaması, bir JVM’de kolayca Linux üzerinde çalışabilir.







Hendrik Ebbers (@hendrikEbbers), JCP Uzman Grubunun bir üyesi olan Java Şampiyonu ve birçok kez JavaOne’ın Rockstar Konuşmacısı olarak ödüllendirildi. Hendrik, Open Elements şirketi aracılığıyla şu anda Hedera Hashgraph’ın tasarlanmasına ve hizmetlerinin halka sunulmasına yardımcı oluyor. Hendrik, JUG Dortmund ve Cyberland’in kurucu ortağıdır ve dünya çapında Java üzerine dersler ve atölye çalışmaları yapmaktadır. “Mastering JavaFX 8 Controls” adlı kitabı Oracle Press tarafından 2014 yılında yayınlandı. Hendrik, JakartaEE veya Eclipse Adoptium gibi açık kaynaklı projelerde aktif olarak yer alıyor. Hendrik, AdoptOpenJDK TSC ve Eclipse Adoptium WG’nin bir üyesidir.







Sloganın ikinci yönü Java geriye dönük uyumluluktur. Java’nın bir sürümüyle derlenen yazılım, Java’nın gelecekteki sürümlerinde sorunsuz çalışmalıdır. Ancak son yıllarda bu vaat oldukça değişti.


JCL’deki özel API’ler aracılığıyla geriye dönük uyumluluk


Java’da geriye dönük uyumluluk, Java Sınıf Kitaplığı’ndaki (JCL) genel ve özel API’leri ayırarak her zaman mümkün olmalıdır. JCL, günlük olarak birlikte çalıştığımız tüm Java API sınıflarını içerir, örneğin java.lang.String VEYA java.util.List. Ama aynı zamanda daha egzotik sınıflar gibi sun.misc.Unsafe JCL’nin bir parçasıdır. Java Virtual Machine (JVM) ve Java derleyici (javac) gibi çeşitli araçlarla birlikte JCL, geliştiricilerin günlük olarak birlikte çalıştığı JavaSE JDK’yi tanımlar.








JCL’nin özel API’si sınıf yolunda bulunur, ancak asla doğrudan uygulamalar tarafından kullanılmamalıdır. OpenJDK’deki dahili değişiklikler genellikle bu alanda uygulanır ve bu da özel API arabirimlerinde olası değişikliklere yol açabilir. Genel olarak, paketleri olmayan JCL’nin tüm sınıflarının olduğu söylenebilir. java.* VEYA javax.* özel API’ye ait olmaya başlayın, bazı Java dağıtımları JavaFX’i içerdiğinden, onlar için hala yapabilirsiniz javafx.* A ekle.


Bu nedenle, derleme veya çalışma zamanında özel API sınıflarını kullanan yazılım, artık Java’nın her (ana) sürümüyle çalışamama riskiyle karşı karşıyaydı. Derleme zamanı kullanımı doğrudan belirlenebilse de, çalışma zamanı kullanımı sırasında, örneğin yansımalar veya geçişli bağımlılıklar nedeniyle üretimde beklenmeyen sorunlar bile vardı.

Java 9 ve form sisteminin tanıtılmasıyla birlikte, her şey değişti. Modül sistemi, API’leri dış dünyadan gizlemeyi ve böylece yalnızca kendi modülünüzde kullanılabilir hale getirmeyi mümkün kılar. Bu, Java’nın özel API’lerinin tamamen gizlenmesine izin verdi.








Bu özel API’ler birçok program ve kitaplık tarafından kullanıldığından, Java 9 ile yapılan bu kesintinin muazzam dönüşümlere yol açacağı kesindi. Bu nedenle OpenJDK, Java 9’dan Java 15’e kadar özel API’lerin kullanılabileceğine karar verdi. Burada yalnızca yazılım özel API’lere eriştiğinde bir uyarı verilir. Bunun için parametre illegal-access varsayılan olarak Java 9 ila 15’te tanıtıldı warn ayarlandı. Parametre, JVM’yi bir komut satırı parametresi olarak basitçe başlatmak için değiştirilebilir.

Böylece bu sürümlerde ekleyerek de yapabilirsiniz --illegal-access=deny zaten bir Java programının artık JCL’nin özel API’lerini kullanamayacağını garanti ediyorlar. Bu aynı zamanda JDK 16’nın standart davranışıydı. Burada bayrağı etkinleştirmeniz gerekir. warn uygulamanızın özel API’leri kullanmasına izin vermek istiyorsanız ayarlayın. Ancak Java 17 LTS sürümü ile bu seçenek tamamen kaldırılmıştır. permit, warn VE debug onlar bunun içindi illegal-access Özel API’lere genel erişime izin vermeyi artık mümkün kılmayan işaret kaldırıldı. Hala Java 17 ile özel API’leri kullanmak zorundaysanız, bunu yine de --add-opens-bayrak veya dem Add-Opens-Belirli modüller için bildirimde özniteliği etkinleştirin.

Araçlardaki veya JVM’deki değişiklikler


JVM veya araç değişiklikleri de Java ile geriye dönük uyumluluğu etkileyebilir. Örneğin, Java 10 ile JEP 286, Java dilini kullanımını içerecek şekilde genişletti. var büyütülmüş Bu, derleyici tarafından belirlenebiliyorsa, Java’daki bir değişken türünün artık manuel olarak belirtilmesi gerekmediği anlamına gelir. İşte bir örnek:


var list = new ArrayList<String>(); // infers ArrayList<String>
var stream = list.stream(); // infers Stream<String>


Tanımı var Java dilinde bazı yansımaları olmuştur. Olsa bile var Java sözdizimine anahtar kelime olarak eklenmemiştir, bu da yine de mümkün kılmaktadır. var değişken adı olarak kullanmak için. Devlet var Java dilinde “Ayrılmış tür adı” olarak tanımlanır (bkz. JEP 286). Ancak bu, artık sınıflar veya arayüzler oluşturmanın mümkün olmadığı anlamına gelir. var Arama. Bu, yalnızca birkaç Java programında gerçekleşmiş olsa da, Java ile geriye dönük uyumluluğun bozulmasıdır.

Geriye dönük uyumluluğu korumak için kullanımdan kaldırılan API’ler


Java’nın ilk sürümü 1996’da yayınlandı. O zamandan beri sadece bir programlama dili olarak Java değil, aynı zamanda programlama paradigmaları da gelişmeye devam etti, birçok API Java’ya dönüştürüldü. 1996’da hala tipik olan modeller artık kısmen modası geçmiş durumda. Ayrıca, OpenJDK geliştiricileri ara sıra hatalar yaparlar ve bu, mevcut bilgilere göre artık kullanılmaması gereken API’lerle sonuçlanır.

Ancak, Java’nın eski sürümleriyle uyumluluğu korumak için, JCL genel API’lerinin parçasıysalar bu API’ler kaldırılmamıştır. Başlangıçta, JavaDoc kullanımına karşı uyarıda bulundu ve alternatif API’ler genellikle doğrudan önerildi. Java 1.5 ile ek açıklamanın kullanıma sunulmasıyla, bu, @Deprecated-Açıklama hala geliştirilecek. Bu ek açıklama, kullanıcıya yalnızca bir API’nin artık kullanılmaması gerektiğini göstermekle kalmaz, aynı zamanda Java derleyicisinin bir uyarı (hatta yapılandırmaya bağlı olarak bir hata) vermesine neden olur. Bu aynı zamanda günümüz IDE’lerinde de açıkça vurgulanmıştır, böylece program kodunuzun kullanımdan kaldırılmış (eski) olarak işaretlenmiş API’lere erişip erişmediğini hızlıca görebilirsiniz.

Süreç uzun bir süre çalışmış olsa da, onu kullanan OpenJDK’de yıllar geçtikçe daha fazla kod oluşturulmuştur. @Deprecated açıklamalıydı ve bu nedenle her sürüm ve değişiklikle birlikte sürdürülmesi gerekiyordu. Java API’si de giderek daha fazla şişirildi. Java modül sisteminin gelişi ve JCL’nin ayrı modüllere bölünmesiyle, tamamen farklı sorunlar ortaya çıktı: hiçbir zaman kaldırılmayan birçok eski kod bölümü nedeniyle, OpenJDK’de tamamen vahşi bağımlılıklar vardı. kolayca çözüldü.

Bu nedenle, Java 9 ile @Deprecated– Özniteliğin etrafındaki açıklama forRemoval büyütülmüş Bu öznitelik, bir API’nin kullandığını gösterir. @Deprecated(forRemoval=true) belirtilirse, gelecekteki bir Java sürümünde kaldırılabilir. Her altı ayda bir gelen yeni Java sürüm treni ve yeni sürümlerle, bu bazen çok hızlı gerçekleşebilir. Java’nın en son sürümleri de bunun kullanıldığını gösteriyor. Diğer şeylerin yanı sıra, CORBA API, aşağıdaki çeşitli arayüzler java.security.acl.* veya yöntemler java.lang.SecurityManager KALDIRILDI. ONLAR java.lang.SecurityManager ayrıca JCL’den tamamen çıkarılmalıdır.

parça değişiklikleri


Java’nın iki sürümü arasındaki farklılıkları ve değişiklikleri test etmek ve değerlendirmek için javaalmanac.io web sitesi bir süredir kullanılabilir. Java Sınıf Kitaplığı’ndaki iki Java sürümü arasındaki farklar burada görüntülenebilir. Burada yalnızca uzun vadeli destek (LTS) sürümleri değil, aynı zamanda Java 1.0’dan sonraki tüm önemli sürümler listelendiğinden, yazılımınızı bir dönüştürmeden önce veya hatta yeni bir Java LTS sürümü görünmeye başlamadan önce kolayca dönüştürebilirsiniz. Araç, değişikliklere ek olarak, kendisinden türetilen tüm sınıfları, işlevleri ve diğer öğeleri de gösterir. @Deprecated açıklama yapılmıştır.








Ve bu geliştiriciler için ne anlama geliyor?


Java, bir noktada programlama dillerinin yenilikçi ve çevik daha fazla geliştirme ile sürekli aşağı doğru uyumluluk arasında seçim yapması gerektiğini göstermiştir. Bir dil yaşlandıkça, beraberinde daha fazla miras taşır. API’nin birçok bölümü güncelliğini yitirmiştir ve modern paradigmalara uyarlanması zordur. Bu nedenle, bir dilin bazen miras alınan yükleri denize atması mantıklıdır. Elbette kullanıcıları da unutmamalı ve bu konularda hassas davranmalıyız.

Bence Java yapımcıları, uzun süredir kullanılmayan API’leri kaldırmak gibi yeni kavramları duyurarak bu dengeleme eylemini iyi ele aldılar. Ayrıca eleştirilere ve topluluk geri bildirimlerine de yanıt verdiler. Sınıfla uğraşmak kesinlikle burada geçerlidir sun.misc.Unsafe iyi bir örnek olarak. OpenJDK’dan çıkarılması uzun süredir tartışılıyor. Çerçeve ve kitaplık geliştiricileri için geriye dönük uyumluluk sağlamak amacıyla OpenJDK’ya ek işlevler de eklenmiştir. Çok sürümlü JAR dosyalarıyla (JEP 238), Kavanozlar farklı Java sürümleri için belirli sınıflar içerebilir ve böylece uyumluluğu önemli ölçüde artırır.

Ancak bu değişiklikler, bir Java sürümünden diğerine geçmeden önce uzun süre bekleyen geliştiriciler için daha fazla iş anlamına geliyor. Ancak, her zaman Java’nın mevcut LTS sürümüne geçerseniz ve burada açıklanan kavramlara ve araçlara aşina iseniz, iş genellikle yönetilebilir.


(rm)



Haberin Sonu
 
Üst