Aracılığıyla paylaş


Java 8'den Java 11'e geçiş

Java 8'den Java 11'e kod geçişi için herkese uygun tek bir çözüm yoktur. Önemsiz olmayan bir uygulama için Java 8'den Java 11'e geçmek önemli miktarda iş olabilir. Olası sorunlar arasında kaldırılan API, kullanım dışı paketler, iç API kullanımı, sınıf yükleyicilerde yapılan değişiklikler ve çöp toplamada yapılan değişiklikler yer alır.

Genel olarak yaklaşımlar java 11'de yeniden derlemeden çalıştırmayı veya önce JDK 11 ile derlemeyi denemektir. Amaç bir uygulamayı mümkün olan en hızlı şekilde çalışır duruma getirmekse, en iyi yaklaşım genellikle Java 11'de çalıştırmaya çalışmaktır. Bir kitaplık için amaç, JDK 11 ile derlenmiş ve test edilmiş bir yapıt yayımlamaktır.

Java 11'e geçmek çabaya değer. Java 8'den bu yana yeni özellikler eklendi ve geliştirmeler yapıldı. Bu özellikler ve geliştirmeler başlatmayı, performansı, bellek kullanımını geliştirir ve kapsayıcılarla daha iyi tümleştirme sağlar. Ayrıca api'de geliştirici üretkenliğini geliştiren eklemeler ve değişiklikler vardır.

Bu belge, kodu incelemek için araçlara değinir. Ayrıca karşılaşabileceğiniz sorunları ve bunları çözmeye yönelik önerileri de kapsar. Oracle JDK Geçiş Kılavuzu gibi diğer kılavuzlara da başvurmalısınız. Mevcut kodu modüler hale getirme burada ele alınmamıştır.

Araç kutusu

Java 11'de olası sorunları algılamak için yararlı olan jdeprscan ve jdeps adlı iki araç vardır. Bu araçlar mevcut sınıf veya jar dosyalarında çalıştırılabilir. Yeniden derlemeye gerek kalmadan geçiş eforunu değerlendirebilirsiniz.

jdeprscan kullanım dışı bırakılmış veya kaldırılmış API'nin kullanımını arar. Kullanım dışı API kullanımı engelleyici bir sorun değildir, ancak göz önünde bulundurulması gereken bir konudur. Güncelleştirilmiş bir jar dosyası var mı? Kullanım dışı API'yi gidermek için bir sorunu raporlamanız gerekiyor mu? Kaldırılan API kullanımı, Java 11'de çalıştırmayı denemeden önce çözülmesi gereken bir engelleme sorunudur.

jdeps, bir Java sınıf bağımlılık çözümleyicisi. seçeneğiyle kullanıldığında --jdk-internalsjdeps size hangi sınıfın hangi iç API'ye bağlı olduğunu bildirir. Java 11'de iç API'yi kullanmaya devam edebilirsiniz, ancak kullanımı değiştirmek bir öncelik olmalıdır. OpenJDK wiki sayfası Java Bağımlılık Analizi Aracı , yaygın olarak kullanılan bazı JDK iç API'leri için değişiklik önermiştir.

Hem Gradle hem de Maven için jdeps ve jdeprscan eklentileri vardır. Bu araçları derleme betiklerinize eklemenizi öneririz.

Java derleyicisinin kendisi olan javac, araç kutunuzdaki başka bir araçtır. jdeprscan ve jdeps'den edindiğiniz uyarılar ve hatalar derleyiciden çıkar. jdeprscan ve jdeps kullanmanın avantajı, bu araçları üçüncü taraf kitaplıklar da dahil olmak üzere mevcut jar'lar ve sınıf dosyaları üzerinde çalıştırabilmenizdir.

Jdeprscan ve jdeps'in yapamayacağı şey, kapsüllenmiş API'ye erişmek için yansıma kullanımı hakkında uyarmaktır. Yansıtmalı erişim çalışma zamanında denetleniyor. Sonuç olarak, kesin olarak bilmek için kodu Java 11'de çalıştırmanız gerekir.

jdeprscan'ı kullanma

jdeprscan kullanmanın en kolay yolu, mevcut bir derlemeden jar dosyası vermektir. Ayrıca, derleyici çıkış dizini gibi bir dizin veya tek bir sınıf adı verebilirsiniz. --release 11 Kullanımdan kaldırılan API'nin en eksiksiz listesini almak için seçeneğini kullanın. Öncelikli olarak hangi kullanım dışı API'yi hedefleyeceğinizi belirlemek istiyorsanız, ayarı --release 8 olarak geri alın. Java 8'de kullanım dışı bırakılan API,yakın zamanda kullanım dışı bırakılan API'den daha erken kaldırılacaktır.

jdeprscan --release 11 my-application.jar

Jdeprscan aracı, bağımlı bir sınıfı çözümlemede sorun yaşıyorsa bir hata iletisi oluşturur. Örneğin, error: cannot find class org/apache/logging/log4j/Logger. uygulamasına --class-path veya uygulama sınıf yolunu kullanarak bağımlı sınıflar eklenmesi önerilir, ancak araç taramaya onsuz devam eder. Bağımsız değişken --class-path şeklindedir. class-path değişkeninin başka hiçbir varyasyonu çalışmaz.

jdeprscan --release 11 --class-path log4j-api-2.13.0.jar my-application.jar
error: cannot find class sun/misc/BASE64Encoder
class com/company/Util uses deprecated method java/lang/Double::<init>(D)V

Bu çıkış, com.company.Util sınıfının, java.lang.Double sınıfının kullanım dışı bir oluşturucusunu çağırdığını bildirir. Javadoc, API'nin kullanım dışı api yerine kullanılmasını önerir. Kaldırılmış olan API olduğu için hiçbir miktar çalışma error: cannot find class sun/misc/BASE64Encoder sorununu çözmeyecektir. Java 8'den bu yana java.util.Base64 kullanılmalıdır.

Java 8'den bu yana hangi API'nin kullanım dışı bırakıldığını öğrenmek için komutunu çalıştırın jdeprscan --release 11 --list . Kaldırılan API'nin listesini almak için komutunu çalıştırın jdeprscan --release 11 --list --for-removal.

Jdeps'in kullanılması

JDK iç API'sine bağımlılıkları bulma seçeneğiyle birlikte --jdk-internals kullanın. Log4j-core-2.13.0.jar --multi-release 11olduğundan bu örnek için komut satırı seçeneği gereklidir. Bu seçenek olmadan, çok sürümlü bir jar dosyası bulursa jdeps şikayet eder. seçeneği, sınıf dosyalarının hangi sürümünün denetlendiğini belirtir.

jdeps --jdk-internals --multi-release 11 --class-path log4j-core-2.13.0.jar my-application.jar
Util.class -> JDK removed internal API
Util.class -> jdk.base
Util.class -> jdk.unsupported
   com.company.Util        -> sun.misc.BASE64Encoder        JDK internal API (JDK removed internal API)
   com.company.Util        -> sun.misc.Unsafe               JDK internal API (jdk.unsupported)
   com.company.Util        -> sun.nio.ch.Util               JDK internal API (java.base)

Warning: JDK internal APIs are unsupported and private to JDK implementation that are
subject to be removed or changed incompatibly and could break your application.
Please modify your code to eliminate dependence on any JDK internal APIs.
For the most recent update on JDK internal API replacements, please check:
https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool

JDK Internal API                         Suggested Replacement
----------------                         ---------------------
sun.misc.BASE64Encoder                   Use java.util.Base64 @since 1.8
sun.misc.Unsafe                          See http://openjdk.java.net/jeps/260   

Çıktı, JDK iç API'sinin kullanımını ortadan kaldırma konusunda bazı iyi öneriler sunar! Mümkün olduğunda, değiştirme API'si önerilir. Paketin kapsüllendiği modülün adı parantez içinde verilir. Modül adı, kapsüllemeyi açıkça bozmak gerektiğinde, --add-exports veya --add-opens ile kullanılabilir.

sun.misc.BASE64Encoder veya sun.misc.BASE64Decoder kullanımı Java 11'de java.lang.NoClassDefFoundError ile sonuçlanır. Bu API'leri kullanan kodun java.util.Base64 kullanacak şekilde değiştirilmesi gerekir.

jdk.unsupported modülünden gelen tüm API'lerin kullanımını ortadan kaldırmayı deneyin. Bu modülden alınan API, JDK Geliştirme Teklifi (JEP) 260'a önerilen bir yedek olarak başvuracaktır. Özetle JEP 260, değiştirme API'si kullanılabilir olana kadar iç API kullanımının desteklendiğini söylüyor. Kodunuz JDK iç API'sini kullansa da, en azından bir süre boyunca çalışmaya devam eder. JEP 260'a göz atın çünkü bu, bazı iç API'lerin yerine geçebilecek alternatifleri işaret etmektedir. değişken tutamaçları , örneğin bazı sun.misc.Unsafe API'leri yerine kullanılabilir.

jdeps , JDK iç işlevlerinin kullanımını taramaktan fazlasını yapabilir. Bağımlılıkları analiz etmek ve modül bilgisi dosyaları oluşturmak için kullanışlı bir araçtır. Daha fazla bilgi için belgelere göz atın.

javac kullanımı

JDK 11 ile derlemek için betikler, araçlar, test çerçeveleri ve dahil edilen kitaplıklar için güncelleştirmeler gerekir. -Xlint:unchecked JDK iç API'sinin ve diğer uyarıların kullanımıyla ilgili ayrıntıları almak için javac seçeneğini kullanın. Ayrıca, kapsüllenmiş paketleri derleyiciye açmak için --add-opens veya --add-reads kullanılması da gerekebilir (bkz. JEP 261).

Kitaplıklar paketlemeyi çok sürümlü jar dosyası olarak değerlendirebilir. Çok sürümlü jar dosyaları, aynı jar dosyasından hem Java 8 hem de Java 11 çalışma zamanlarını desteklemenizi sağlar. Derlemeye karmaşıklık ekler. Çoklu sürüm jar'ları oluşturma işlemi bu belgenin kapsamının dışındadır.

Java 11'de çalışıyor

Çoğu uygulama, java 11'de değişiklik yapmadan çalıştırılmalıdır. Denenecek ilk şey, kodu yeniden derlemeden Java 11'de çalıştırmaktır. Sadece çalıştırmanın amacı, yürütme sırasında ortaya çıkan uyarı ve hataları görmektir. Bu yaklaşım bir sonuca varır.
Java 11'de daha hızlı çalışması için uygulamayı, yapılacak en az işi merkeze alarak optimize et.

Karşılaşabileceğiniz sorunların çoğu kodu yeniden derlemek zorunda kalmadan çözülebilir. Kodda bir sorunun düzeltilmesi gerekiyorsa düzeltmeyi yapın ancak JDK 8 ile derlemeye devam edin. Mümkünse, JDK 11 ile java önce uygulamanın sürüm 11 ile çalışmasını sağlama üzerinde çalışın.

Komut satırı seçeneklerini denetleme

Java 11'de çalıştırmadan önce komut satırı seçeneklerini hızlı bir şekilde tarayın. Kaldırılan seçenekler Java Sanal Makinesi'nin (JVM) çıkışına neden olur. Bu denetim özellikle GC günlüğü seçeneklerini kullanıyorsanız önemlidir çünkü bunlar Java 8'den önemli ölçüde değişmiştir. JaCoLine aracı, komut satırı seçenekleriyle ilgili sorunları algılamak için iyi bir araçtır.

Üçüncü taraf kitaplıklarını denetleme

Olası bir sorun kaynağı, denetlemediğiniz üçüncü taraf kitaplıklarıdır. Üçüncü taraf kitaplıklarını önceden daha yeni sürümlere güncelleştirebilirsiniz. Ya da uygulamayı çalıştırarak nelerin ortaya çıktığını görebilir ve yalnızca gerekli olan kitaplıkları güncelleyebilirsiniz. Tüm kitaplıkları son sürüme güncelleştirmeyle ilgili sorun, uygulamada bir hata varsa kök nedeni bulmayı zorlaştırıyor olmasıdır. Güncelleştirilmiş bir kitaplık nedeniyle mi hata oluştu? Ya da hatanın nedeni çalışma zamanındaki bir değişiklik miydi? Yalnızca gerekenleri güncelleştirmeyle ilgili sorun, çözmek için çeşitli yinelemeler gerektirebilir.

Burada öneri, mümkün olduğunca az değişiklik yapmak ve üçüncü taraf kitaplıklarını ayrı bir çaba olarak güncelleştirmektir. Üçüncü taraf kütüphanesini güncellerseniz, genellikle Java 11 ile uyumlu en yeni ve en iyi sürümü istersiniz. Geçerli sürümünüzün ne kadar gerisinde olduğuna bağlı olarak, daha dikkatli bir yaklaşım benimsemek ve ilk Java 9+ uyumlu sürüme yükseltmek isteyebilirsiniz.

Sürüm notlarına bakmanın yanı sıra jar dosyasını değerlendirmek için jdeps ve jdeprscan kullanabilirsiniz. Ayrıca OpenJDK Kalite Grubu, Birçok Ücretsiz Açık Kaynak Yazılım (FOSS) projesinin OpenJDK sürümlerine karşı test durumunu listeleyen bir Kalite Yardım wiki sayfası tutar.

Çöp toplamayı açıkça ayarlama

Paralel çöp toplayıcı (Paralel GC), Java 8'de varsayılan GC'dir. Uygulama varsayılanı kullanıyorsa, GC açıkça komut satırı seçeneğiyle -XX:+UseParallelGCayarlanmalıdır. Java 9'da varsayılan değer, Garbage First çöp toplayıcısı (G1GC) olarak değiştirildi. Java 8 ve Java 11 üzerinde çalışan bir uygulamanın adil bir karşılaştırması yapmak için GC ayarlarının aynı olması gerekir. Uygulama Java 11'de doğrulanana kadar GC ayarlarıyla denemeler ertelenmelidir.

Varsayılan seçenekleri açıkça ayarlama

HotSpot VM'sinde çalıştırılıyorsa, komut satırı seçeneğinin -XX:+PrintCommandLineFlags ayarlanması, özellikle GC tarafından ayarlanan varsayılanlar olmak üzere VM tarafından ayarlanan seçeneklerin değerlerini döküm eder. Java 8'de bu bayrakla çalıştırın ve Java 11'de çalışırken yazdırılan seçenekleri kullanın. Çoğu zaman varsayılan değerler 8 ile 11 aynıdır. Ancak 8'in ayarlarının kullanılması eşliği güvence altına alır.

Komut satırı seçeneğinin --illegal-access=warn ayarlanması önerilir. Java 11'de JDK iç API'sine erişim için yansıma kullanılması , geçersiz yansıtıcı erişim uyarısına neden olur. Varsayılan olarak, uyarı yalnızca ilk yasa dışı erişim için verilir. Ayar --illegal-access=warn , her geçersiz reflektif erişimde uyarıya neden olur. Uyarı olarak ayarlanmış seçenekle yasa dışı erişim durumlarında daha fazla vaka bulacaksınız. Ancak birçok gereksiz uyarı da alırsınız.
Uygulama Java 11'de çalıştırıldıktan sonra Java çalışma zamanının gelecekteki davranışını taklit etmek için ayarlayın --illegal-access=deny . Java 16'dan itibaren varsayılan değer olacaktır --illegal-access=deny.

ClassLoader uyarıları

Java 8'de sistem sınıfı yükleyicisini öğesine URLClassLoaderdönüştürebilirsiniz. Bu genellikle çalışma zamanında sınıf dizinine sınıf enjekte etmek isteyen uygulamalar ve kitaplıklar tarafından yapılır. Java 11'de sınıf yükleyici hiyerarşisi değişti. Sistem sınıfı yükleyicisi (uygulama sınıfı yükleyicisi olarak da bilinir) artık bir iç sınıftır. 'a URLClassLoader atama, çalışma zamanında bir ClassCastException oluşturur. Java 11'de, çalışma zamanında sınıf yolunu dinamik olarak genişletebilecek bir API yoktur, ancak iç API kullanımıyla ilgili bariz sakıncalar ile yansıma yoluyla yapılabilir.

Java 11'de önyükleme sınıfı yükleyicisi yalnızca çekirdek modülleri yükler. Null üst öğeye sahip bir sınıf yükleyicisi oluşturursanız, tüm platform sınıflarını bulamayabilir. Java 11'de, bu gibi durumlarda üst sınıf yükleyicisi olarak ClassLoader.getPlatformClassLoader() yerine null geçirmeniz gerekir.

Yerel ayar verilerindeki değişiklikler

Java 11'de yerel ayar verilerinin varsayılan kaynağı JEP 252 ile Unicode Konsorsiyumun Ortak Yerel Ayar Veri Deposu olarak değiştirildi. Bunun yerelleştirilmiş biçimlendirme üzerinde etkisi olabilir. Gerekirse sistem özelliğini java.locale.providers=COMPAT,SPI Java 8 yerel ayarı davranışına geri dönecek şekilde ayarlayın.

Olası sorunlar

Karşılaşabileceğiniz yaygın sorunlardan bazıları aşağıdadır. Bu sorunlar hakkında daha fazla ayrıntı için bağlantıları izleyin.

Tanınmayan seçenekler

Bir komut satırı seçeneği kaldırıldıysa, uygulama Unrecognized option: veya Unrecognized VM option yazdırır ve ardından sorunlu seçeneğin adını gösterir. Tanınmayan bir seçenek VM'nin çıkışına neden olur. Kullanım dışı bırakılan ancak kaldırılmayan seçenekler bir VM uyarısı oluşturur.

Genel olarak, kaldırılan seçeneklerin hiçbir değiştirmesi yoktur ve tek çare seçeneği komut satırından kaldırmaktır. Tek istisna, çöp toplama kütükleme seçenekleridir. GC günlüğü, birleştirilmiş JVM günlük çerçevesinin kullanılması için Java 9'da yeniden eklendi. Java SE 11 Araçlar Referansı'nın JVM Birleşik Günlükleme Çerçevesi ile Günlüklemeyi Etkinleştirme bölümünde yer alan "Tablo 2-2: Eski Çöp Toplama Günlük Bayraklarını Xlog Yapılandırmasına Eşleme" bölümüne bakın.

VM uyarıları

Kullanım dışı bırakılan seçeneklerin kullanılması bir uyarı oluşturur. Bir seçenek değiştirildiğinde veya artık yararlı olmadığında kullanım dışıdır. Kaldırılan seçeneklerde olduğu gibi, bu seçenekler komut satırından kaldırılmalıdır. Uyarı VM Warning: Option <option> was deprecated , seçeneğin hala desteklendiği, ancak gelecekte bu desteğin kaldırılacağı anlamına gelir. Artık desteklenmeyen ve uyarısını VM Warning: Ignoring optionoluşturacak bir seçenek. Artık desteklenmeyen seçeneklerin çalışma zamanı üzerinde hiçbir etkisi yoktur.

Web sayfası VM Seçenekleri Gezgini , JDK 7'den bu yana Java'ya eklenen veya Java'dan kaldırılan seçeneklerin kapsamlı bir listesini sağlar.

Hata: Java Sanal Makinesi oluşturulamadı

JVM tanınmayan bir seçenekle karşılaştığında bu hata iletisi yazdırılır.

UYARI: Yasadışı yansıtıcı erişim işlemi gerçekleşti

Java kodu JDK iç API'sine erişmek için yansıma kullandığında, çalışma zamanı geçersiz yansıtıcı erişim uyarısı gönderir.

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by my.sample.Main (file:/C:/sample/) to method sun.nio.ch.Util.getTemporaryDirectBuffer(int)
WARNING: Please consider reporting this to the maintainers of com.company.Main
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release

Bu, bir modülün yansıma aracılığıyla erişilen paketi dışarı aktarmadığı anlamına gelir. Paket modülde kapsüllenmiş ve temel olarak iç API'dir. Java 11'e geçişte ilk adım olarak uyarı önemsiz sayılabilir. Java 11 çalışma zamanı, eski kodun çalışmaya devam edebilmesi için yansıtıcı erişime izin verir.

Bu uyarıyı gidermek için, iç API'yi kullanmayan güncelleştirilmiş kodu arayın. Sorun güncelleştirilmiş kodla çözülemezse, --add-exports pakete erişimi açmak için veya --add-opens komut satırı seçeneği kullanılabilir. Bu seçenekler, bir modülden diğerine dışa aktarılmamış türlere erişim sağlar.

--add-exports seçeneği, hedef modülün kaynak modülün adlandırılmış paketinin genel türlerine erişmesini sağlar. Bazen kod, genel olmayan üyelere ve API'ye erişmek için kullanır setAccessible(true) . Bu derin yansıma olarak bilinir. Bu durumda, kodunuzu bir paketin genel olmayan üyelerine erişim vermek için kullanın --add-opens . --add-exports veya --add-opens kullanmak isteyip istemediğinizden emin değilseniz -- add-exports ile başlayın.

--add-exports veya --add-opens seçenekleri, uzun vadeli bir çözüm olarak değil, geçici bir çözüm olarak değerlendirilmelidir. Bu seçeneklerin kullanılması, JDK iç API'sinin kullanılmasını engelleyen modül sisteminin kapsüllemesini keser. İç API kaldırılırsa veya değişirse uygulama başarısız olur. Komut satırı seçenekleri, örneğin --add-opens ile etkinleştirilen erişim dışında, Java 16'da yansıtıcı erişim reddedilecektir. Gelecekteki davranışı taklit etmek için komut satırında ayarlayın --illegal-access=deny .

Yukarıdaki örnekteki uyarı, sun.nio.ch paketi java.base modülü tarafından dışarı aktarılmadığından verilmiştir. Başka bir deyişle, exports sun.nio.ch; modülünün module-info.java dosyasında java.base yoktur. Bu, ile --add-exports=java.base/sun.nio.ch=ALL-UNNAMEDçözülebilir. Bir modülde tanımlanmayan sınıflar, kelimenin tam anlamıyla unnamed olarak adlandırılan ALL-UNNAMED modüle aittir.

java.lang.reflect.InaccessibleObjectException (Erişilemez Obje İstisnası)

Bu istisna, kapsüllenmiş bir sınıfın alanı veya yönteminde setAccessible(true) çağırmaya çalıştığınızı gösterir. Ayrıca yasa dışı yansıtıcı erişim uyarısı alabilirsiniz. Kodunuza bir paketin genel olmayan üyelerine erişim vermek için --add-opens seçeneğini kullanın. Hata mesajı, setAccessible çağrısı yapmaya çalışan modüle paketi açmayan modül hakkında bilgi verir. Modül "adlandırılmamış modül" ise UNNAMED-MODULE--add-opens seçeneğinde hedef modül olarak kullanın.

java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.util.ArrayList jdk.internal.loader.URLClassPath.loaders accessible: 
module java.base does not "opens jdk.internal.loader" to unnamed module @6442b0a6

$ java --add-opens=java.base/jdk.internal.loader=UNNAMED-MODULE example.Main

java.lang.NoClassDefFoundError

NoClassDefFoundError'ın nedeni büyük olasılıkla bölünmüş bir paket veya kaldırılan modüllere başvurmaktır.

Bölünmüş paketlerin neden olduğu NoClassDefFoundError

Bölünmüş paket, bir paketin birden fazla kitaplıkta bulunmasıdır. Bölünmüş paket probleminin belirtisi, sınıf yolunda bulunduğunu bildiğiniz bir sınıfın bulunamamasıdır.

Bu sorun yalnızca modül yolu kullanılırken oluşur. Java modül sistemi, bir paketi adlandırılmış bir modülle kısıtlayarak sınıf aramasını iyileştirir. Çalışma zamanı, bir sınıf araması yaparken modül yolunu sınıf yolu üzerinden tercih eder. Bir paket bir modül ile sınıf yolu arasında bölünürse, sınıf aramasını yapmak için yalnızca modül kullanılır. Bu durum NoClassDefFound hatalara neden olabilir.

Bölünmüş paketi denetlemenin kolay bir yolu, modül yolunuzu ve sınıf yolunuzu jdeps'ye bağlamak ve yol olarak uygulama sınıfı dosyalarınızın <>yolunu kullanmaktır. Bölünmüş bir paket varsa, jdeps bir uyarı yazdırır: Warning: split package: <package-name> <module-path> <split-path>.

Bu sorun, bölünmüş paketi adlandırılmış modüle eklemek için kullanılarak --patch-module <module-name>=<path>[,<path>] çözülebilir.

Java EE veya CORBA modüllerinin kullanılması nedeniyle NoClassDefFoundError

Uygulama Java 8 üzerinde çalışıyor ancak bir java.lang.NoClassDefFoundError veya bir java.lang.ClassNotFoundException oluşturuyorsa, büyük olasılıkla Java EE veya CORBA modüllerinden bir paket kullanıyordur. Bu modüller Java 9'da kullanım dışı bırakıldı ve Java 11'de kaldırıldı.

Sorunu çözmek için projenize bir çalışma zamanı bağımlılığı ekleyin.

Modül kaldırıldı Etkilenen Paket Önerilen bağımlılık
XML Web Hizmetleri için Java API'si (JAX-WS) .ws java.xml JAX WS RI Çalışma Zamanı
XML Bağlama için Java Mimarisi (JAXB) .bind java.xml JAXB Çalışma Zamanı
JavaBeans Etkinleştirme Çerçevesi (JAV) java.activation JavaBeans (TM) Etkinleştirme Çerçevesi
Ortak Ek Açıklamalar .ws.annotation java.xml Javax Ek Açıklama API'si
Ortak Nesne İsteği Aracısı Mimarisi (CORBA) java.corba GlassFish CORBA ORB
Java İşlem API'si (JTA) java.transaction Java İşlem API'si

-Xbootclasspath/p artık desteklenen bir seçenek değil

-Xbootclasspath/p için destek kaldırıldı. Bunun yerine --patch-module kullanın. --patch-module seçeneği JEP 261'de açıklanmıştır. "Modül içeriğine düzeltme eki uygulama" etiketli bölümü arayın. --patch-module, bir modüldeki sınıfları geçersiz kılmak veya artırmak için javac ve java ile kullanılabilir.

--patch-module işlevinin yaptığı şey, düzeltme eki modülünü modül sisteminin sınıf aramasına eklemektir. Modül sistemi önce yama modülünden sınıfı alır. Bu, Java 8'de ön bekleyen bootclasspath ile aynıdır.

UnsupportedClassVersionError (Desteklenmeyen Sınıf Versiyon Hatası)

Bu özel durum, Java'nın daha önceki bir sürümünde Java'nın daha sonraki bir sürümüyle derlenmiş kodu çalıştırmaya çalıştığınız anlamına gelir. Örneğin, Java 11 kullanıyorken JDK 13 ile derlenmiş bir jar dosyası çalıştırıyorsunuz.

Java sürümü Sınıf dosya biçimi sürümü
8 52
9 53
10 54
11 55
12 56
13 (on üç) 57

Sonraki Adımlar

Uygulama Java 11'de çalıştırıldıktan sonra kitaplıkları sınıf yolundan ve modül yoluna taşımayı göz önünde bulundurun. Uygulamanızın bağımlı olduğu kitaplıkların güncelleştirilmiş sürümlerini arayın. Varsa modüler kitaplıkları seçin. Uygulamanızda modülleri kullanmayı planlamıyor olsanız bile modül yolunu mümkün olduğunca kullanın. Modül yolunun kullanılması, sınıf yükleme için sınıf yolundan daha iyi performansa sahiptir.