Sınıf yükleme kural dışı durumları
Bir uygulama geliştirdiğinizde ya da kurulu bir uygulama başlattığınızda ne tür bir sınıf yükleme hatası görüyorsunuz?
ClassCastÖzel Durumu
Sınıf dönüştürme kural dışı durumu, aşağıdaki koşullar varolduğunda ve aşağıdaki işlemler tarafından düzeltilebildiğinde sonuçlanabilir:
- Kaynak nesnenin tipi, hedef sınıfın somut örneği değil (tip).
- Kaynak nesneyi (sınıf) yükleyen sınıf yükleyici, hedef sınıfı yükleyen sınıf yükleyiciden farklı.
- Uygulama, dar bir işlemi gerçekleştiremiyor ya da yanlış bir şekilde gerçekleştiremiyor.
- Kaynak nesnenin tipi, hedef sınıfın (tip) eşgörünümü değil.
- Bu, tipik sınıf dönüşümü kural dışı durumu. Bir cast deyiminin kaynak nesnesinin hedef sınıfın (tip) somut örneği olmadığını, kaynak nesne sınıfının sınıf imzasını inceleyerek tanılayabilirsiniz, daha sonra kaynak nesne sınıfının atasında hedef sınıfı içermediğini ve kaynak nesne sınıfının hedef sınıftan farklı olduğunu doğrulayabilirsiniz. Kodunuza basit bir yazdırma deyimi ekleyerek sınıf bilgilerini elde edebilirsiniz. Örneğin:
Ya da bir javap komutu kullanın. Örneğin:System.out.println( source.getClass().getName() + “:” + target.getClass().getName() );javap java.util.HashMap Compiled from "HashMap.java" public class java.util.HashMap extends java.util.AbstractMap implements java.util.Map,java.lang.Cloneable,java.io.Serializable { - Kaynak nesneyi (sınıf) yükleyen sınıf yükleyici, hedef sınıfı yükleyen sınıf yükleyiciden farklı.
- Kaynak nesnenin tipinin hedef sınıfın bir örneği olduğunu varsayarsak, kaynak nesnenin sınıfını yükleyen sınıf yükleyici hedef sınıfı yükleyen sınıf yükleyicisinin farklıysa, sınıf dönüştürme kural dışı durumu ortaya çıkar. Hedef sınıf, WebSphere® Application Server yürütme ortamı ortamında birden çok sınıf yükleyicisinin sınıf sınıflarında görünür olduğunda bu durum oluşabilir. Bu sorunu gidermek için, sınıf yükleyicilerle ilgili sorunları tanılamak için kullanılan sınıf adı konsol sayfalarına göre Ara ve Ara sayfasını kullanın.
- Search page(Arama sayfası) olanağına erişmek için (Sorun Giderme-> Sınıf yükleyici görüntüleyicisi
- Arama tipiiçin Sınıf/Paketseçeneğini belirleyin.
- Arama terimleriiçin, iki sınıf yükleyicisinin yüklendiği sınıfın adını yazın.
- Tamam'ı tıklatın. Sınıf adı temelinde arama sayfası görüntülenir; sınıfı yükleyen tüm sınıf yükleyicileri listeleniyor.
Listelenen birden fazla sınıf yükleyicisi varsa, hedef sınıf birden çok sınıf yükleyicisi tarafından yüklenmişti. Kaynak nesne hedef sınıfın bir eşgörünümü olduğu için, kaynak nesne sınıfını yükleyen sınıf yükleyici hedef sınıfı yükleyen sınıf yükleyiciden farklı.
- Sınıf yükleyici görüntüleyicisi sayfasına dönün ve iki farklı sınıf yükleyicisinin sınıfı neden yüklemesinin nedenini saptamak için sınıf yolunu inceleyin.
- Kodun yalnızca uygun sınıf yükleyiciye görünmesi için kodunuzu düzeltin.
- Uygulama, dar bir işlemi gerçekleştiremiyor ya da düzgün bir şekilde gerçekleştiremiyor.
- Uygulama uzak bir kurumsal bean (EJB) nesnesini çözümlediğinde uygulama kodu, gerektiği gibi dar bir işlem gerçekleştirmediği için sınıf yayınına ilişkin bir kural dışı durum oluşabilir. Uygulama, uzak bir nesneyi aradıktan sonra dar bir işlem gerçekleştirmelidir. Uygulamayı inceleyin ve uzak bir nesne görünüp görünmediğini saptayın ve bu durumda arama sonucunun dar bir yönteme sunulmasını sağlar.
Dar yöntemin EJB 2.0 programlama modeline göre çağrılması gerekir. Özellikle, dar yönteme sunulan hedef sınıf, EJB ' nin en çok türetilen arabirimi olmalıdır. Bu durum, WebSphere Application Server yürütme ortamında sınıf yayınının kural dışı durumuna neden olur. Uygulamayı inceleyin ve dar yönteme gönderilen hedef sınıfın tam EJB tipinde değil, belirtilen EJB ' nin bir üst arabirimi olup olmadığını saptayın; bu durumda, uygulamayı tam EJB arabirimiyle daraltmaya çağırmak için uygulamayı değiştirin.
Son olarak, dar bir işlem sırasında sınıf dönüşümü kural dışı durumu oluşursa, dar yöntemin yerel bir kurum Bean 'e değil, uzak EJB aramasının sonucuna uygulandığını doğrulayın. Yerel aramalar için dar bir değer kullanılmaz. Daraltılan nesnenin yerel bir nesne olmadığından emin olmak için uygulama ya da modül konuşlandırma tanımlayıcısını inceleyin.
ClassNotFoundException
Aşağıdaki koşullar varolduğunda ve aşağıdaki işlemler tarafından düzeltilebilecek bir sınıf bulunamadı kural dışı durumu ortaya çıktı:
- Bağlam sınıf yükleyicisinin mantıksal sınıf yolunda (classpath) sınıf görünmez.
- Uygulama, sınıf yükleyici API ' yı yanlış kullanıyor.
- Bağımlı bir sınıf görünür değil.
- Sınıf, bağlam sınıfı yükleyicisinin mantıksal sınıf yolunda görünür değil.
- Bulunamayan sınıf, yürürlükteki iş parçacığıyle ilişkilendirilmiş sınıf yükleyicisinin mantıksal sınıf yolunda değil. Mantıksal sınıf yolu (classpath), sınıf yükleyiciye bir yükleme işlemi çağrıldığında aranan tüm sınıf yollarının birikimidir. Bu sorunu düzeltmek için, Ara sayfasını sınıf adına göre ve Java™ arşiv (JAR) adına göre aramak için kullanın:
- Search page(Arama sayfası) olanağına erişmek için (Sorun Giderme-> Sınıf yükleyici görüntüleyicisi
- Arama tipiiçin Sınıf/Paketseçeneğini belirleyin.
- Arama terimleriiçin, bulunamayan sınıfın adını yazın.
- Tamam'ı tıklatın. Sınıf adı temelinde arama sayfası görüntülenir; sınıfı yükleyen tüm sınıf yükleyicileri listeleniyor.
- Sınıfın listede var olup olmadığını görmek için sayfayı inceleyin.
- Sınıf listede yoksa, Ara sayfasına dönün. Arama terimleriiçin, sınıfa ilişkin .jar dosyasının adını yazın; Arama tipiiçin JAR/Dizin' i seçin.
- Tamam'ı tıklatın. JAR dosyasını tutan tüm dizinleri listeleyen, Yol Temelinde Arama sayfası görüntülenir.
JAR dosyası listede yoksa, büyük olasılıkla mantıksal sınıf yolunda değil, okunabilir değil ya da diğer sınıf zaten yüklenmemiş. Sınıfı, yüklenmesini sağlayan bir konuma taşıyın.
- Uygulama, sınıf yükleyici API ' yı yanlış kullanıyor.
- Bir uygulama, bir sınıf yükleyicisinin eşgörünümünü alabilir ve o sınıf yükleyicisinde loadClass yöntemini çağırabilir ya da o sınıf yükleyiciyle Class.forName(sınıf_adı, initialize, class_loader) yöntemini çağırabilir. Sınıf yükleyici uygulama programlama arabirimi (API) kullanılarak uygulama yanlış olabilir. Örneğin, sınıf adı yanlış; sınıf, o sınıf yükleyicisinin mantıksal sınıf yolunda ya da yanlış sınıf yükleyicisinin çalıştırıldığı sınıf tarafından görülemez.
Bu sorunu gidermek için, sınıfın var olup olmadığını ve uygulamanın sınıf yükleyici API ' yı kullanıp kullanmadığını saptayın. Sınıfın yüklenip yüklenmediğini belirlemek için Bağlam sınıf yükleyicisinin mantıksal sınıf yolunda (classpath) sınıf görüntülenmiyor başlıklı adımdaki adımları izleyin. Sınıf yüklenmediyse, uygulamayı düzeltmeye çalışın ve sınıf yüklerinin olup olmadığını görün. Sınıf, uygun izne sahip sınıf yollardaysa ve başka bir üretici sınıfı tarafından geçersiz kılınmadıysa, sınıfı yüklemek için kullanılan API ' yi inceleyin.
- Sınıf yükleyicisine Ara sayfasıerişmek için öğelerini seçin.
- Arama tipiiçin Sınıf/Paketseçeneğini belirleyin.
- Arama terimleriiçin, sınıfın adını yazın.
- Tamam'ı tıklatın. Sınıf adı temelinde arama sayfası görüntülenir; sınıfı yükleyen tüm sınıf yükleyicileri listeleniyor.
- Sınıfın listede var olup olmadığını görmek için sayfayı inceleyin.
- Sınıf bir listede yer alıyorsa ve bir ClassNotFound exception yayınlandıysa, .jar dosyası ya da sınıfı doğru bağlamda değil ya da geçerli bağlamda yanlış bir API çağrısı kullanıldı.Sınıf listede yoksa, Arama sayfasına dönün ve aşağıdaki işlemi gerçekleştirin:
- Kural dışı durumu oluşturan sınıfı arayın; bu, Class.forNamesınıfından oluşan sınıf.
- Sınıfı yükleyen sınıf yükleyicisine bakın.
- Sınıf yükleyicisinin, sınıf yükleyicisinin sınıf yolunu değerlendirerek erişip yüklemediğini ya da sınıf yükünün yüklenip yüklenemeyeceğini saptayın.
- Bağımlı sınıf görünür değildir.
- When a class loader clsldr loads a class cls, the Java virtual machine (JVM) invokes clsldr to load the classes on which cls depends. Bağımlı sınıfların, clsldrmantıksal sınıf yolunda görünür olması gerekir; tersi durumda, kural dışı durum oluşur. This condition typically occurs when users make WebSphere Application Server classes visible to the JVM, or make application classes visible to the JVM or to the WebSphere extensions class loader. Örneğin:
- A sınıfı B sınıfına göre değişir.
- A sınıfı, WebSphere uzantıları sınıf yükleyicisi tarafından görülebilir.
- B sınıfı bir WAR modül sınıf yükleyicisinin yerel sınıf yolunda (classpath) görünür; WebSphere uzantı sınıfı yükleyici sınıf yolu (classpath) değil.
JVM WebSphere uzantılı sınıf yükleyicisini kullanarak A sınıfı yüklediğinde, aynı sınıf yükleyicisini kullanarak Sınıf B ' yi yüklemeye çalışır ve sonuç olarak bir sınıf bulunamadı kural dışı durumu yaratır.
Bu sorunu düzeltmek için:
- Uygulamaya özgü sınıfları, uygun uygulama sınıfı yükleyicisi için görünür duruma getirmeniz gerekir.
- Sınıfı arama bulunamadı (Sınıf B).
- B Sınıfı uygun bir konumdaysa, Sınıf yükleyici görüntüleyicisinde bağımlı sınıfı (Class A) yükleyen sınıfı ara .
- Sınıf yüklenirse ve bir ClassNot(ClassNotFound) kural dışı durumu yayınlandıysa,.jardosya ya da sınıf uygun bir bağlamda değil ya da yürürlükteki bağlamda yanlış API çağrısı kullanıldı.Sınıf bulunamazsa, aşağıdaki işlemi gerçekleştirin:
- Kural dışı durumu oluşturan sınıfı arayın; bu, Class.forNamesınıfından oluşan sınıf.
- Sınıfı yükleyen sınıf yükleyicisine bakın.
- Sınıf yükleyicisinin, sınıf yükleyicisinin sınıf yolunu değerlendirerek erişip yüklemediğini ya da sınıf yükünün yüklenip yüklenemeyeceğini saptayın.
- Çağıran sınıfın (Sınıf B), JVM ya da WebSphere uzantı sınıfı yükleyicisi tarafından görülebildiğinden emin olun.
NoClassDefFoundKural Dışı Durumu
Aşağıdaki koşullar varolduğunda ve aşağıdaki işlemler tarafından düzeltilebilecek bir sınıf tanımı kural dışı durum sonucu bulunamadı:
- Sınıf, mantıksal sınıf yolunda değil.
- Bilgi için ClassNotFoundException belgesine bakın.
- Sınıf yüklenemiyor.
- Bir sınıfın yüklenmemesi için çeşitli nedenler vardır. Nedenler şunlardır: Bağımlı sınıfın yüklenmemesi, bağımlı sınıfın biçimi hatalı ya da bir sınıfın sürüm numarası.
UnsatisfiedLinkHatası
Aşağıdaki koşullar var olduğunda ve aşağıdaki işlemler tarafından düzeltilebilecek bir bağ hatası ortaya çıktı:
- Bir kullanıcı işlemi hataya neden oldu.
System.mapLibraryName , yanlış kitaplık dosyasını döndürür.- Yerel kitaplık zaten yüklendi.
- Bağımlı bir yerel kitaplık kullanıldı.
- Bir kullanıcı işlemi hataya neden oldu.
Bazı kullanıcı işlemleri bir bağ hatasıyla sonuçlanabilir:
- Altyapı için bir kitaplık uzantısı adı yanlış.
Bir kitaplığın dinamik bağlantı kitaplığı adı ( library_name.dll) vardır.
Kitaplık, library_name.so ya da library_name.aadına sahiptir.- System.loadLibrary yanlış bir değiştirgeden geçirilir.
Name.dlladlı devingen bir bağlantı kitaplığı yüklemek için,
Nameadlı bir loadLibrary çağrısına geçilmesi gerekir.
To load a library named libName.so or libName.a, libNameis passed to the load library.- Kitaplık görünür değil.
- En iyi uygulama olarak, yerli kitaplıkları bulmak ya da yüklemek için JVM sınıf yükleyicisini kullanın. WebSphere Application Server , başlatma sırasında Java kitaplık yolunu (java.library.path) yazdırır. JVM sınıf yükleyicisi kitaplığı yüklemek için amaçlandıysa, yerel kitaplık dosyasını içeren yolun Java kitaplık yolunda olduğunu doğrulayın. Tersi durumda, platforma özgü yerel kitaplık ortamı değişkeninin yolunu ya da sunucu işlemi tanımlamasının java.library.path sistem özelliğine yolunu ekleyin.
Genel olarak, Java sanal makinesi Tamam. sınıf yükleyicisinde System.loadLibrary() çağrısını çağıran sınıfı yükleyen findLibrary() işlevini çağırır. Tamam..findLibrary() başarısız olursa, Java sanal makinesi, JVM kitaplık yolunu araştıran JVM sınıf yükleyicisini kullanarak kitaplığı bulmayı dener. Kitaplık bulunamazsa, Java sanal makinesi bir UnsatisfiedLink(UnsatisfiedLink) hatası kural dışı durumu yaratır.
Dolayısıyla, bir WebSphere sınıf yükleyicisinin yerel bir kitaplığı ( myNativeLib) bulunması amaçlandıysa, kitaplığın System.loadLibrary(myNativeLib) adını çağıran sınıfı yükleyen sınıf yükleyicisinin
nativelibpathüzerinde görünür olması gerekir. Bu uygulama aşağıdaki durumlarda gereklidir ya da istenmektedir:- Paylaşılan kitaplıklarda, yapılanışlarında bir Yerel kitaplık yolu vardır. Paylaşılan kitaplıklar uygulamaya özgü kitaplıkların sürüm oluşturmasını etkinleştirdiğinden, paylaşılan kitaplık yapılanışındaki paylaşılan kitaplık kodu tarafından kullanılan yerel kitaplıkların yollarını belirtmeyi düşünün.
Doğru WebSphere sınıf yükleyicinin System.loadLibrary() öğesini çağıran sınıfı yüklediğinden ve yerel kitaplığın Native library path (Yerel kitaplık yolu) ayarında görünür olduğundan emin olun.
![[AIX HP-UX Solaris]](../images/unix.gif)
- System.mapLibraryName , yanlış kitaplık dosyasını döndürür.
- Paylaşılan bir kitaplık yüklenirken, JVM libName öğesini platforma özgü bir ada dönüştürmek için mapLibraryName (libName) çağrısını çağırır. AIX®, HP-UX ya da Solaris işletim sistemlerinde, bu çağrı yanlış uzantıya sahip bir dosya adı döndürebilir (örneğin, libName.ayerine libName.so ). Bu hatayı ayıklamak için, System.mapLibraryName() çağrısına bir program yazın ve doğru dosya adını döndürdiğini doğrulayın.
- Yerli kitaplık zaten yüklenmiş.
- Bu durum aşağıdaki hatalardan biriyle sonuçlanabilir:
- Kullanıcı hatası
- System.loadLibrary ' e birden çok çağrı olup olmadığını denetleyin ve varsa, yapılan dış aramaları kaldırın.
- Uygulama yeniden başlatıldığında hata oluştu
- JVM, bir kerede yalnızca bir sınıf yükleyicinin yerel bir kitaplığı yükleyebileceği bir sınırlamaya sahiptir. Bir uygulama, çöp toplayıcı durdurulan uygulamadan sınıf yükleyicisini temizlemeden önce yeniden başlatıldığında bir hata sonucu ortaya çıktı. Yerel kitaplığı yükleyen sınıf taşındığında, o yerel kitaplığa bağlı olan tüm sınıflar ve bağımlılıkları da taşınmalıdır.
Bu koşulu düzeltmek için, yerel kitaplığın yüklenmesini yeniden yüklenmeyen bir sınıf yükleyiciye taşıyın:
- Yerli kitaplıkları yükleyen ya da yerli yöntemlere sahip tüm uygulama sınıflarını bulun.
- 1. adımda (günlüğe kaydetme paketleri gibi) sınıflara ilişkin bağımlı sınıfları saptayın.
- Sunucuya ilişkin paylaşılan bir kitaplık ya da yalıtılmış bir paylaşılan kitaplık yaratın.
- 1. ve 2. adımlardaki sınıflar için yüklenen JAR dosyalarını, uygulamadaki 3. adımda oluşturulan paylaşılan kitaplığa taşıyın.
- Değişikliklerinizi kaydedin.
- Uygulamayı yeniden konuşlandırın ve senaryoyı yeniden çalıştırın.
Sunucu kapsamlı kitaplıklardaki sınıflar, her bir sunucu yaşam çevrimi için bir kez yüklenir ve uygulamanın yaşam döngüsü ne olursa olsun, uygulamanın gerektirdiği yerel kitaplığın her bir Java sanal makinesi için bir kez yüklenmesini sağlar.
- Bağımlı bir yerel kitaplık kullanıldı.
- Bağımlı yerel kitaplıklar, JVM sınıf yükleyici tarafından bulunmalı ya da yüklenmelidir. Yani, NL yerel kitaplığı başka bir yerel kitaplığa ( DNL) bağımlıysa, JVM sınıf yükleyicisi Java kitaplık yolunda DNL ' yi bulmalıdır. Bunun nedeni, JVM 'nin NL' yi yüklerken yerel kodu çalıştırmasıdır; DNL bağımlılığına rastlandığında JVM yerel kodu, bağımlılığı çözümlemek için yalnızca JVM sınıf yükleyicisine çağırabilir. WebSphere sınıf yükleyici bağımlı bir yerel kitaplığı yükleyemez.
Çözülmemiş yerli kitaplığı içeren yolu içerecek şekilde, altyapıya özgü ortam değişkenini (LIBPATH) tanımlamak için, altyapıya özgü ortam değişkenini değiştirin.