java.lang.NoClassDefFoundError: XXX sınıfı başlatılamadı


165
public class PropHolder {
  public static Properties prop;

  static {
    //code for loading properties from file
  }
}

// Referencing the class somewhere else:
Properties prop = PropHolder.prop;

class PropHolderkendi sınıfım. Sınıf, ana sınıfın aynı JAR dosyasında bulunur. Bu nedenle, sınıf yolunda herhangi bir JAR eksik olduğu için olmamalıdır.

Ben JAR dosyasına baktığımda, orada listelenen jar tf myjarfilegörebilirsiniz PropHolder.class.

BTW: Kod yerel makinemde iyi çalışıyor. Ama ben bir Linux sunucusuna bazı komut dosyası ile dağıttığımda çalışamadı. Bu yüzden kodun sorunu olmadığını düşünüyorum. Ama bir nedenden dolayı. konuşlandırma sürecini izlemek çok zordur.

Sorun ne olabilir?


Kavanozunuzdaki uygun dizin yapısı sınıf paketiyle eşleşiyor mu?
John B

bir kaynak görmeniz gerekiyor, birçok şey buna neden olabilir. örneğin, bir 'paket' ifadesi ancak dosya aslında ilgili yolda
bulunmuyor

3
Bir neden başlatma sırasında bir istisnadır - başka bir hata çıktısı var mı?
Michael Brewer-Davis

Yanıtlar:


211

En iyi seçeneğim burada bir sorun var:

static {
    //code for loading properties from file
}

Yakalanmamış bir istisna oluştu ve sınıfı yüklemeye çalışan gerçek ClassLoader'a kadar yayıldı. Ancak bunu onaylamak için bir yığın izine ihtiyacımız var.

Ya bu ya da PropHolder.propstatik değişken oluşturulurken meydana geldi .


Aynı sorunla tekrar tekrar karşılaşıyorum. staticSorun yüzünden eminim . Sorunu çözmek için ne yapılması gerekiyor?
engerek

1
staticBloktan hangi istisna atıldığını tanımlamanız gerekir . Hata ayıklamak try/catch(Exception e)için tüm bloğun çevresine koy ve istisnayı günlüğe kaydet. Bu istisnayı düzeltmeniz gerekecek. Genellikle istisna günlüğe kaydedilir ancak sınıf yüklemesi sırasında çok erken gerçekleşen günlüğe kaydedildiğinden bulmak zor olabilir
John Vint

Evet kodu try catchblokta sakladım ve dedi Failed to initialize ClassA. Bence bu bir problem JVM. Sistemimi yeniden başlattım ve her şey yolunda gitti. Sistemimi yeniden başlatmadan bu sorunu gelecekte nasıl çözerim ve basit bir çözümle nasıl çözebilirim?
engerek

ClassA başlatılamadı, başka bir şeyden kaynaklanan bir yan etkidir. causeVarsa bakmak isteyeceksiniz . A NoClassDefFoundErrorher zaman başka bir hatayla ilişkilendirilir, günlüklerde aramanız veya daha uygun şekilde kaydetmeye çalışmanız gerekir (dosya sistemindeki yeni bir dosyaya giriş yapmaya zorlamak gibi)
John Vint

Java CouldNotInitializeStaticPartOfClassError ya da onun gibi bir hata verirse daha kolay izlenebilir. Sonra biz geliştirici olarak nereye bakacağımızı bilirdik.
Maarten

126

java.lang.NoClassDefFoundErrorSınıfınızın eksik olduğu anlamına gelmeyen bir (A java.lang.ClassNotFoundException) elde edersiniz . ClassLoader, sınıfı okumaya çalışırken sınıf tanımını okurken bir hatayla karşılaştı.

Statik başlatıcısına bir deneme / yakalama koyun ve istisnayı inceleyin. Orada bazı dosyaları okursanız ve yerel ortamınızdan farklıysa, sorunun nedeni büyük olasılıkladır (belki dosya bulunamaz, izinler vb.).


1
bir açıklama NoClassDefFoundError bir ClassNotFoundException ima etmese de, hala NoClassDefFoundError olası bir nedenidir.
John Vint

1
Eğer bir ClassNotFoundException varsa buf o zaman ClassLoader sınıf yüklemeyi denemek / asla, değil mi?
jeha

4
Bir sınıf, bulunmayan başka bir sınıfı yüklüyor olabilir. Bu örnekte hala bir ClassNotFoundException var
John Vint

1
Açıklığa kavuşturmalıydım, sadece bir istisna demek istedim.
GetCause

1
JAR (bildirilen sınıfın ait olduğu) doğrulamak için yaklaşık 20 dakika geçirdim çünkü bu gerçekten yararlı oldu. Bir kez yanlış yöne baktığımı fark ettim, muhtemelen bazı ek açıklama sınıflarının eksik ve voila olduğunu anladım, rapor edilen olarak ilan edildi @Stateless, bu yüzden karşılık gelen bağımlılığı ekledim ve daha ileri gidebildim. Bahşiş için teşekkürler!
RAM237

33

NoClassDefFoundError, statik blok içinde neyin yanlış gittiğine dair bir ipucu vermez. Statik {...} başlatma kodunun içinde her zaman böyle bir blok olması iyi bir uygulamadır:

static {
  try {

    ... your init code here

  } catch (Throwable t) {
    LOG.error("Failure during static initialization", t);
    throw t;
  }
}

Bunu kotlin'de nasıl yapabilirim?
Marlon

İpucu verdiğin için teşekkürler. Benim durumumda statik hat başlatmada NPE alıyordum.
Abhishek

3

Aynı istisnayı yaşadım, sorunu şu şekilde çözdüm:

Ön koşullar:

  1. Junit sınıfı (ve testi), başka bir sınıfı genişletti.

  2. ApplicationContext, projeyi başlatan yay kullanılarak başlatıldı.

  3. Uygulama içeriği @Before yönteminde başlatıldı

Çözüm:

Üst sınıf ayrıca uygulama bağlamından başlatılan bazı sınıflar gerektirdiğinden, @BeforeClass yönteminden uygulama bağlamını başlatın.

Umarım bu yardımcı olur.


2

Yukarıda belirtildiği gibi, bu birkaç şey olabilir. Benim durumumda, özellikler dosyamda eksik bir girdiye dayanan statik olarak başlatılmış bir değişkenim vardı. Özellikler dosyasına eksik girdi eklendi ve sorun çözüldü.


1

Daha birkaç gün önce, aynı soruyu seninki gibi gördüm. Tüm kod yerel makinemde iyi çalışıyor, ancak hata çıkıyor (noclassdeffound & başlat). Bu yüzden çözümümü gönderiyorum, ama nedenini bilmiyorum, sadece bir olasılığı ilerletiyorum. Umarım birisi bunu açıklar. @ John Vint Öncelikle size sorunumu göstereceğim. Kodumda statik değişken ve statik blok var. Bu sorunla ilk karşılaştığımda, John Vint'in çözümünü denedim ve istisnayı yakalamaya çalıştım. Ancak hiçbir şey yakalayamadım. Ben statik değişken (ama şimdi aynı şey olduğunu biliyorum) ve hala hiçbir şey bulamadığını düşündüm. Bu nedenle, linux makinesi ile bilgisayarım arasındaki farkı bulmaya çalışıyorum. Daha sonra bu sorunun sadece bir işlemde birkaç iş parçacığı çalıştırıldığında ortaya çıktığını buldum (Bu arada, linux makinesinde çift çekirdek ve çift işlem var). Bu, aynı işlemde iki görev varsa (her ikisi de statik blok veya değişkenleri olan kodu kullanırsa), yanlış gider, ancak farklı işlemlerde çalışırlarsa, her ikisi de tamamdır. Linux makinesinde kullanıyorum

mvn -U clean  test -Dtest=path 

statik değişkenim bir kapsayıcı başlatmak (veya belki de yeni bir sınıf yükleyici başlatmak) olduğundan, jvm durana kadar kalır ve jvm yalnızca bir işlemdeki tüm görevler durduğunda durur. Her görev yeni bir kapsayıcı (veya sınıf yükleyici) başlatır ve jvm'yi karıştırır. Sonuç olarak, hata olur. Peki, nasıl çözülür? Çözümüm maven komutuna yeni bir komut eklemek ve her görevin aynı kapsayıcıya gitmesini sağlamak.

-Dxxx.version=xxxxx #sorry can't post more

Belki bu sorunu zaten çözdünüz, ancak yine de aynı sorunu çözen diğerlerine yardımcı olacağını umuyoruz.


Dahası, kod linux makinesinde çalıştığında, yukarıdaki hatayı takip edin, başka bir sorun var: Bu java.lang.ExceptionInInitializerError: null, sınıf yükleyicide sınıfı bulamadığınız veya hangisini yüklemediğini bilmediğim anlamına gelir (sanırım). Bununla tanıştın mı?
MonkeyKing

1

Ben aynı istisna vardı - ama sadece hata ayıklama modunda çalışırken, bu nasıl (3 tam gün sonra) sorunu çözdü: build.gradle ben vardı: "multiDexEnabled true" defaultConfig bölümünde ayarlanmış.

        defaultConfig {
    applicationId "com.xxx.yyy"
    minSdkVersion 15
    targetSdkVersion 28
    versionCode 5123
    versionName "5123"
    // Enabling multidex support.
    multiDexEnabled true
}

ama görünüşe göre bu yeterli değildi. ama değiştiğimde:

public class MyAppClass  extends Application 

için:

public class MyAppClass  extends MultiDexApplication 

bu çözdü. umarım bu birine yardım eder


0

Bir Android projesi üzerinde çalışıyorsanız, herhangi bir Android sınıfında statik yöntem aramadığınızdan emin olun. Sadece JUnit + Mockito kullanıyorum, bu yüzden belki de başka çerçeveler sorunu tamamen önlemenize yardımcı olabilir, emin değilim.

Benim sorunum Uri.parse(uriString)birim testi için statik başlatıcı bir parçası olarak çağırıyordu . Uri sınıfı bir Android API'sıdır, bu yüzden birim test derlemesi onu bulamadı. Bunun nullyerine bu değeri değiştirdim ve her şey normale döndü.


0

Aynı sorunları yaşadım :java.lang.NoClassDefFoundError: Sınıf com.xxx.HttpUtils başlatılamadı

static {
    //code for loading properties from file
}

çevre sorunudur.Bu application.yml özellikleri yanlış veya boş demektir!


0

Aynı problemle karşılaşıyorum. Aşağıdaki gibi statik blokta bir fasulye nesnesini başlattım:

static {
    try{
        mqttConfiguration = SpringBootBeanUtils.<MqttConfiguration>getBean(MqttConfiguration.class);
    }catch (Throwable e){
        System.out.println(e);
    }
 }

Fasulye obejct inition'ımın işleminin bir NPE'ye neden olması nedeniyle, sorun yaşıyorum. Bu yüzden size statik kod bloğunu dikkatlice kontrol etmeniz gerektiğini düşünüyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.