"Ana sınıf bulunamadı veya yüklenemedi" ne anlama geliyor?

Yeni Java geliştiricilerinin yaşadığı yaygın bir sorun, programlarının hata mesajıyla çalışmamasıdır: Ana sınıf bulunamadı veya yüklenemedi ...

Bu ne anlama geliyor, buna ne sebep oluyor ve bunu nasıl düzeltmelisiniz?

Çözüm

java ` komut sözdizimi

Öncelikle, java (veya javaw) komutunu kullanarak bir programı başlatmanın doğru yolunu anlamanız gerekir. Normal sözdizimi1 şöyledir:

    java [  ... ]  [ ...]

burada bir komut satırı seçeneğidir ("-" karakteriyle başlar), tam nitelikli bir Java sınıf adıdır ve `` uygulamanıza aktarılan rastgele bir komut satırı bağımsız değişkenidir.
1 - "çalıştırılabilir" JAR dosyaları için altta açıklayacağım ikinci bir sözdizimi vardır. Sınıf için tam nitelikli ad (FQN) geleneksel olarak Java kaynak kodunda olduğu gibi yazılır; örn.

    packagename.packagename2.packagename3.ClassName

Ancak java komutunun bazı sürümleri nokta yerine eğik çizgi kullanmanıza izin verir; örn.

    packagename/packagename2/packagename3/ClassName

(kafa karıştırıcı bir şekilde) bir dosya yol adı gibi görünür, ancak değildir. Tam nitelikli ad* teriminin standart Java terminolojisi olduğunu unutmayın... kafanızı karıştırmak için uydurduğum bir şey değil :-) İşte bir java komutunun nasıl görünmesi gerektiğine dair bir örnek:

    java -Xmx100m com.acme.example.ListUsers fred joe bert

Yukarıdakiler java komutunun aşağıdakileri yapmasına neden olacaktır:

  1. com.acme.example.ListUsers` sınıfının derlenmiş sürümünü arayın.
  2. Sınıfı yükleyin.
  3. Sınıfın public static void main(String[]) tarafından verilen imza, geri dönüş türü ve değiştiricileri olan bir main yöntemine sahip olup olmadığını kontrol edin. (Yöntem argümanının adının imzanın bir parçası olmadığına dikkat edin).
  4. Komut satırı argümanlarını ("fred", "joe", "bert") bir String[] olarak geçirerek bu yöntemi çağırın. Java'nın sınıfı bulamamasının nedenleri

    Ana sınıf bulunamadı veya yüklenemedi..." mesajını aldığınızda, bu ilk adımın başarısız olduğu anlamına gelir. javakomutu sınıfı bulamamıştır. Ve aslında, mesajdaki "..."java`nın aradığı tam nitelikli sınıf adı olacaktır. Peki neden sınıfı bulamıyor olabilir?
    Sebep #1 - classname argümanında bir hata yaptınız

    İlk olası neden, yanlış sınıf adı vermiş olmanızdır. (Ya da ... doğru sınıf adı, ancak yanlış biçimde.) Yukarıdaki örneği göz önünde bulundurarak, sınıf adını belirtmenin çeşitli yanlış yollarını burada bulabilirsiniz:

  • Örnek 1 - basit bir sınıf adı:

    java ListUser

    Sınıf com.acme.example gibi bir pakette bildirilmişse, java komutunda paket adı da dahil olmak üzere *tam sınıf adını kullanmanız gerekir; örn. java com.acme.example.ListUser

  • Örnek #2 - sınıf adı yerine bir dosya adı veya yol adı: java ListUser.class java com/acme/example/ListUser.class

  • Örnek #3 - harfleri yanlış yazılmış bir sınıf adı: java com.acme.example.listuser

  • Örnek #4 - bir yazım hatası java com.acme.example.mistuser

  • Örnek #5 - bir kaynak dosya adı java ListUser.java

  • Örnek #6 - sınıf adını tamamen unuttunuz java çok sayıda argüman Neden #2 - uygulamanın sınıf yolu yanlış belirtilmiş

    İkinci olası neden, sınıf adının doğru olması, ancak java komutunun sınıfı bulamamasıdır. Bunu anlamak için "classpath" kavramını anlamanız gerekir. Bu, Oracle dokümantasyonunda iyi bir şekilde açıklanmıştır:

  • The java command documentation

  • Sınıf Yolunun Ayarlanması.

  • Java Eğitimi - PATH ve CLASSPATH Yani ... sınıf adını doğru belirttiyseniz, kontrol etmeniz gereken bir sonraki şey sınıf yolunu doğru belirtip belirtmediğinizdir:

  1. Yukarıda bağlantısı verilen üç belgeyi okuyun. (Evet... Onları OKUYUN. Bir Java programcısının Java sınıf yolu mekanizmalarının nasıl çalıştığına dair en azından temel bilgileri anlaması önemlidir).
  2. Komut satırına ve / veya java komutunu çalıştırdığınızda geçerli olan CLASSPATH ortam değişkenine bakın. Dizin adlarının ve JAR dosya adlarının doğru olup olmadığını kontrol edin.
  3. Sınıf yolunda göreceli yol adları varsa, java komutunu çalıştırdığınızda geçerli olan dizinden ... doğru çözümlendiklerini kontrol edin.
  4. Sınıfın (hata mesajında belirtilen) etkili sınıf yolunda bulunup bulunmadığını kontrol edin.
  5. Sınıf yolu sözdiziminin Windows ile Linux ve Mac OS için farklı olduğunu unutmayın. (Sınıf yolu ayırıcısı Windows'ta ;, diğerlerinde ise : şeklindedir. Platformunuz için yanlış ayırıcı kullanırsanız, açık bir hata mesajı almazsınız. Bunun yerine, yol üzerinde var olmayan bir dosya veya dizin alırsınız ve bu da sessizce yok sayılır). Neden #2a - sınıf yolunda yanlış dizin var

    Sınıf yoluna bir dizin koyduğunuzda, bu dizin kavramsal olarak nitelikli ad alanının köküne karşılık gelir. Sınıflar bu kökün altındaki dizin yapısında, tam nitelikli adın bir yol adına eşlenmesiyle bulunur. Örneğin, sınıf yolunda "/usr/local/acme/classes" varsa, JVM com.acme.example.Foon adında bir sınıf aradığında, bu yol adına sahip bir ".class" dosyası arayacaktır:

  /usr/local/acme/classes/com/acme/example/Foon.class

Sınıf yoluna "/usr/local/acme/classes/com/acme/example" koymuş olsaydınız, JVM sınıfı bulamazdı. Neden #2b - alt dizin yolu FQN ile eşleşmiyor

Sınıflarınızın FQN'si com.acme.example.Foon ise, JVM "com/acme/example" dizininde "Foon.class" arayacaktır:

  • Dizin yapınız yukarıdaki modele göre paket adlandırmasıyla eşleşmiyorsa, JVM sınıfınızı bulamayacaktır.
  • Bir sınıfı taşıyarak yeniden adlandırmayı denerseniz, bu da başarısız olacaktır ... ancak istisna yığın izi farklı olacaktır. Şuna benzer bir şey söyleyebilir: Neden: java.lang.NoClassDefFoundError: <path> (yanlış isim: ) çünkü sınıf dosyasındaki FQN, sınıf yükleyicinin bulmayı beklediği şeyle eşleşmiyor. Somut bir örnek vermek gerekirse, varsayalım ki:
  • com.acme.example.Foon` sınıfını çalıştırmak istiyorsunuz,
  • tam dosya yolu /usr/local/acme/classes/com/acme/example/Foon.class şeklindedir,
  • geçerli çalışma dizininiz /usr/local/acme/classes/com/acme/example/ şeklindedir, O zaman:
# wrong, FQN is needed
java Foon

# wrong, there is no `com/acme/example` folder in the current working directory
java com.acme.example.Foon

# wrong, similar to above
java -classpath . com.acme.example.Foon

# fine; relative classpath set
java -classpath ../../.. com.acme.example.Foon

# fine; absolute classpath set
java -classpath /usr/local/acme/classes com.acme.example.Foon

Notlar:

  • Çoğu Java sürümünde -classpath seçeneği -cp olarak kısaltılabilir. Java,javac` ve benzerleri için ilgili kılavuz girdilerini kontrol edin.

  • Sınıf yollarında mutlak ve göreli yol adları arasında seçim yaparken dikkatlice düşünün. Geçerli dizin değişirse göreceli bir yol adının "break" olabileceğini unutmayın.
    Neden #2c - sınıf yolunda eksik bağımlılıklar

    Sınıf yolunun, uygulamanızın bağımlı olduğu tüm diğer (sistem dışı) sınıfları içermesi gerekir. (Sistem sınıfları otomatik olarak bulunur ve bununla nadiren ilgilenmeniz gerekir). Ana sınıfın doğru şekilde yüklenmesi için JVM'nin şunları bulması gerekir:

  • sınıfın kendisi.

  • üst sınıf hiyerarşisindeki tüm sınıflar ve arayüzler (örneğin bkz. https://stackoverflow.com/questions/42880748)

  • değişken veya değişken bildirimleri ya da yöntem çağrısı veya alan erişim ifadeleri aracılığıyla atıfta bulunulan tüm sınıflar ve arayüzler. (Not: JLS ve JVM spesifikasyonları, JVM'nin sınıfları "lazily" yüklemesi için bazı kapsamlara izin verir ve bu, bir sınıf yükleyici istisnasının ne zaman atılacağını etkileyebilir). Sebep #3 - sınıf yanlış pakette bildirilmiştir

    Bazen birisi bir kaynak kod dosyasını kaynak kod ağacında yanlış klasörü seçiyor veya package bildirimini atlıyorlar. Bunu bir IDE'de yaparsanız, IDE'nin derleyicisi size bunu hemen söyleyecektir. Benzer şekilde, iyi bir Java derleme aracı kullanıyorsanız, araç javacı sorunu tespit edecek şekilde çalıştıracaktır. Ancak, Java kodunuzu elle derlerseniz, derleyicinin sorunu fark etmeyeceği şekilde yapabilirsiniz ve sonuçta ortaya çıkan ".class" dosyası olmasını beklediğiniz yerde değildir. Hala sorunu bulamıyor musunuz?

    Kontrol edilecek pek çok şey vardır ve bir şeyleri gözden kaçırmak kolaydır. Javakomut satırına-Xdiagseçeneğini eklemeyi deneyin (java`dan sonraki ilk şey olarak). Sınıf yüklemesi hakkında çeşitli çıktılar verecektir ve bu size gerçek sorunun ne olduğuna dair ipuçları sunabilir. Ayrıca, web sitelerinden, belgelerden vb. görünmez veya ASCII olmayan karakterlerin kopyalanıp yapıştırılmasından kaynaklanan olası sorunları da göz önünde bulundurun. Ve "homoglifleri" düşünün, iki harf veya sembol aynı görünüyordu ... ama değiller'di.

    java -jar ` sözdizimi

    Çalıştırılabilir" JAR dosyaları için kullanılan alternatif sözdizimi aşağıdaki gibidir:

  java [  ... ] -jar  [ ...]

Örneğin.

  java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred

Bu durumda giriş noktası sınıfının adı (yani com.acme.example.ListUser) ve sınıf yolu JAR dosyasının MANIFEST'inde belirtilir.

IDE'ler

Tipik bir Java IDE, Java uygulamalarını IDE JVM'nin kendisinde veya bir alt JVM'de çalıştırma desteğine sahiptir. Bunlar genel olarak bu özel durumdan muaftır, çünkü IDE çalışma zamanı sınıf yolunu oluşturmak, ana sınıfı tanımlamak ve java komut satırını oluşturmak için kendi mekanizmalarını kullanır. Ancak, IDE'nin arkasından bir şeyler yaparsanız, bu istisnanın gerçekleşmesi hala mümkündür. Örneğin, daha önce Eclipse'te Java uygulamanız için bir Uygulama Başlatıcı ayarladıysanız ve daha sonra "main" sınıfını içeren JAR dosyasını dosya sisteminde farklı bir yere taşıdıysanız Eclipse'e söylemeden, Eclipse farkında olmadan JVM'yi yanlış bir sınıf yolu ile başlatacaktır. Kısacası, bir IDE'de bu sorunu yaşıyorsanız, eski IDE durumu, bozuk proje referansları veya bozuk başlatıcı yapılandırmaları gibi şeyleri kontrol edin. Bir IDE'nin kafasının karışması da mümkündür. IDE'ler birbiriyle etkileşim halinde olan birçok parçadan oluşan son derece karmaşık yazılım parçalarıdır. Bu parçaların çoğu, IDE'yi bir bütün olarak duyarlı hale getirmek için çeşitli önbellekleme stratejileri benimser. Bunlar bazen yanlış gidebilir ve olası belirtilerden biri de uygulamaları başlatırken yaşanan sorunlardır. Bunun olabileceğinden şüpheleniyorsanız, IDE'nizi yeniden başlatmak ve projeyi yeniden oluşturmak gibi şeyleri denemeye değer.

Diğer Referanslar

Yorumlar (11)

Bazen soruna neden olan şeyin ana sınıfla hiçbir ilgisi olmayabilir ve ben bunu zor yoldan öğrenmek zorunda kaldım. Taşıdığım referanslı bir kütüphaneydi ve bana şu sorunu verdi:

Ana sınıf xxx Linux bulunamadı veya yüklenemedi

O referansı sildim, tekrar ekledim ve yine sorunsuz çalıştı.

Yorumlar (5)

Önce bu komutu kullanarak yolu ayarlayın;

set path="paste the set path address"

Ardından programı yüklemeniz gerekir. Saklanan sürücüye "cd (klasör adı)" yazın ve derleyin. Örneğin, programım D sürücüsünde depolanmışsa, "D:" yazın, enter tuşuna basın ve "cd (klasör adı)" yazın.

Yorumlar (3)