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


1370

Yeni Java geliştiricilerinin deneyimlediği yaygın bir sorun, programlarının hata mesajıyla çalışamamasıdır: Could not find or load main class ...

Bu ne anlama geliyor, neden oluyor ve nasıl düzeltmelisiniz?


37
Lütfen bunun yeni Java kullanıcıları için genel bir referans Soru ve Cevap olması amaçlanan bir "kendi kendine cevap" sorusu olduğunu unutmayın. Bunu yeterince kapsayan mevcut bir Soru-Cevap bulamadım (IMO).
Stephen C

Yanıtlar:


1230

java <class-name>komut sözdizimi

Her şeyden önce, java(veya javaw) komutunu kullanarak bir programı başlatmanın doğru yolunu anlamanız gerekir .

Normal sözdizimi 1 şudur:

    java [ <options> ] <class-name> [<arg> ...]

burada <option>komut satırı seçeneği ("-" karakteriyle başlayarak), <class-name>tam nitelikli bir Java sınıfı adıdır ve <arg>uygulamanıza aktarılan rastgele bir komut satırı bağımsız değişkenidir.


1 - Bu cevabın sonuna yaklaşan başka sözdizimleri de var.

Sınıfın tam adı (FQN) geleneksel olarak Java kaynak kodunda olduğu gibi yazılır; Örneğin

    packagename.packagename2.packagename3.ClassName

Ancak javakomutun bazı sürümleri nokta yerine eğik çizgi kullanmanıza izin verir; Örneğin

    packagename/packagename2/packagename3/ClassName

(kafa karıştırıcı olarak) bir dosya yol adı gibi görünür, ancak bir dosya adı gibi görünmez. Tam nitelikli ad teriminin standart Java terminolojisi olduğunu unutmayın ... sizi şaşırtmak için yaptığım bir şey değil :-)

İşte bir javakomutun nasıl görünmesi gerektiğine dair bir örnek :

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

Yukarıdaki javakomutun aşağıdakileri yapmasına neden olacaktır:

  1. com.acme.example.ListUsersSınıfın derlenmiş sürümünü arayın .
  2. Sınıfı yükleyin.
  3. Sınıf sahip olup olmadığını kontrol mainyöntemi ile imza , dönüş türü ve değiştiriciler tarafından verilen public static void main(String[]). (Yöntem bağımsız değişkeninin adı imzanın bir parçası DEĞİLDİR .)
  4. Komut satırı bağımsız değişkenlerini ("fred", "joe", "bert") geçirerek bu yöntemi a String[].

Java'nın sınıfı bulamamasının nedenleri

"Ana sınıf bulunamadı veya yüklenemedi ..." iletisini aldığınızda, bu ilk adımın başarısız olduğu anlamına gelir. javaKomut sınıfını bulmak mümkün değildi. Gerçekten de "..." mesajında olacak tam nitelikli sınıf adıjava aramaktadır.

Öyleyse neden sınıfı bulamıyor?

Sebep # 1 - Classname bağımsız değişkeniyle hata yaptınız

İlk olası neden yanlış sınıf adını vermiş olabilirsiniz. (Veya ... doğru sınıf adı, ancak yanlış biçimde) Yukarıdaki örnek göz önüne alındığında , sınıf adını belirtmenin çeşitli yanlış yolları aşağıda verilmiştir:

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

    java ListUser

    Sınıf aşağıdaki gibi bir pakette bildirildiğinde , komutta paket adı da dahil olmak üzerecom.acme.example tam sınıf adını kullanmalısınız ; Örneğinjava

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

    java ListUser.class
    java com/acme/example/ListUser.class
  • Örnek 3 - kasa yanlış olan 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 11 veya üstü hariç; aşağıya bakın)

    java ListUser.java
  • Örnek 6 - sınıf adını tamamen unuttun

    java lots of arguments

Sebep # 2 - Uygulamanın sınıf yolu yanlış belirtildi

İkinci olası neden, sınıf adının doğru olması, ancak javakomutun sınıfı bulamamasıdır. Bunu anlamak için, "sınıf yolu" kavramını anlamanız gerekir. Bu, Oracle belgeleriyle iyi açıklanmıştır :

Yani ... sınıf adını doğru bir şekilde belirttiyseniz, kontrol edilmesi gereken bir sonraki şey sınıf yolunu doğru bir şekilde belirttiğinizdir:

  1. Yukarıda bağlantılı üç belgeyi okuyun. (Evet ... OKUYUN! Bir Java programcısının en azından Java sınıf yolu mekanizmalarının nasıl çalıştığının temellerini anlaması önemlidir .)
  2. Komut satırına ve / veya javakomutu ç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ı denetleyin.
  3. Varsa nispi onlar çalıştırdığınızda yürürlükte olduğu geçerli dizinden ... düzgün biçimde çözümlenmesini sınıf yolunda yol adlarını, onay javakomutu.
  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 arasında farklı olduğunu unutmayın . (Sınıf yolu ayırıcısı ;Windows ve :diğerleri üzerindedir. Platformunuz için yanlış ayırıcı kullanırsanız, açık bir hata iletisi almazsınız. Bunun yerine, yol üzerinde sessizce yoksayılacak varolmayan bir dosya veya dizin alırsınız .)

Sebep # 2a - Sınıf yolunda yanlış dizin var

Sınıf yoluna bir dizin koyduğunuzda, bu dizin zaman zaman nitelikli ad alanının köküne karşılık gelir. Sınıflar , tam nitelikli adın bir yol adıyla eşleştirilmesiyle, bu kökün altındaki dizin yapısında bulunur . Örneğin, "/ usr / local / acme / classes" sınıf yolundaysa, JVM adlı bir sınıfı aradığında com.acme.example.Foon, 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ı.

Sebep # 2b - alt dizin yolu FQN ile eşleşmiyor

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

  • Dizin yapınız yukarıdaki desene göre paket adlandırma ile eşleşmiyorsa, JVM sınıfınızı bulamaz.

  • Bir sınıfı taşıyarak yeniden adlandırmayı denerseniz , bu da başarısız olur ... ancak istisna stacktrace farklı olacaktır. Böyle bir şey söylemekle yükümlüdür:

    Caused by: java.lang.NoClassDefFoundError: <path> (wrong name: <name>)

    çü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:

  • com.acme.example.Foonders vermek istiyorsunuz ,
  • tam dosya yolu /usr/local/acme/classes/com/acme/example/Foon.class,
  • mevcut çalışma dizininiz /usr/local/acme/classes/com/acme/example/,

sonra:

# 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:

  • Bu -classpathseçenek -cpçoğu Java sürümünde kısaltılabilir . İçin ilgili manuel girişler kontrol java, javacvb.
  • Sınıf yollarındaki mutlak ve göreceli yol adları arasında seçim yaparken dikkatlice düşünün. Geçerli dizin değişirse, göreli bir yol adının "bozulabileceğini" unutmayın.

Neden # 2c - sınıfyolundan eksik bağımlılıklar

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

(Not: JLS ve JVM spesifikasyonları, JVM'nin "tembel" sınıfları yüklemesi için bir kapsam sağlar ve bu, bir sınıf yükleyici istisnası atıldığında etkilenebilir.)

Sebep # 3 - Sınıf yanlış pakette beyan edildi

Bazen birisi kaynak kod dosyasını kaynak kod ağacındaki yanlış klasöre koyar veya packagebildirimi dışarıda bırakır . Bunu bir IDE'de yaparsanız, IDE'nin derleyicisi size derhal bunu anlatacaktır. Benzer şekilde, iyi bir Java derleme aracı kullanırsanız, araç javacsorunu algılayacak şekilde çalışır . Ancak, Java kodunuzu el ile oluşturursanız, derleyici sorunu fark etmeyecek şekilde yapabilirsiniz ve sonuçta ortaya çıkan ".class" dosyası olmasını beklediğiniz yerde olmaz.

Hala sorunu bulamıyor musunuz?

Kontrol edilecek çok şey var ve bir şeyi kaçırmak kolaydır. -XdiagSeçeneği javakomut satırına eklemeyi deneyin (sonraki ilk şey olarak java). Sınıf yükleme ile ilgili çeşitli şeyler çıkarır ve bu size gerçek sorunun ne olduğu hakkında ipuçları verebilir.

Ayrıca, görünmez veya ASCII olmayan karakterleri web sitelerinden, belgelerden vb. Kopyalayıp yapıştırmadan kaynaklanan olası sorunları da göz önünde bulundurun. Ve "homoglifler" diyelim, iki harf ya da sembol aynı görünüyormuş ... ama değil.

Son olarak, yanlış imzaları olan bir JAR dosyasından başlatmaya çalışırsanız görünüşe göre bu sorunla karşılaşabilirsiniz (META-INF/*.SF).


İçin alternatif sözdizimleri java

Java programlarını başlatmak için üç alternatif sözdizimi vardır java command.

1) "Yürütülebilir" JAR dosyasını başlatmak için kullanılan sözdizimi aşağıdaki gibidir:

  java [ <options> ] -jar <jar-file-name> [<arg> ...]

Örneğin

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

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.

2) Bir modülden (Java 9 ve üstü) bir uygulama başlatmak için sözdizimi aşağıdaki gibidir:

  java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]

Giriş noktası sınıfının adı ya <module>kendisi tarafından tanımlanır ya da isteğe bağlı olarak verilir <mainclass>.

3) Java 11'den itibaren, tek bir kaynak kod dosyasını derleyip çalıştırabilir ve aşağıdaki sözdizimiyle çalıştırabilirsiniz:

  java [ <options> ] <sourcefile> [<arg> ...]

burada (tipik olarak) ".java" sonekine sahip bir dosyadır.

Daha fazla ayrıntı için, lütfen javakullandığınız Java sürümü komutunun resmi belgelerine bakın .


IDE

Tipik bir Java IDE, Java uygulamalarının IDE JVM'nin kendisinde veya alt JVM'de çalıştırılması için desteğe sahiptir. Bunlar genellikle bu özel istisnadan etkilenmez, çünkü IDE çalışma zamanı sınıfyolunu oluşturmak, ana sınıfı tanımlamak ve javakomut satırını oluşturmak için kendi mekanizmalarını kullanır .

Bununla birlikte, IDE'nin arkasından bir şeyler yaparsanız, bu istisnanın gerçekleşmesi hala mümkündür. Örneğin, Eclipse'de Java uygulamanız için daha önce bir Uygulama Başlatıcı oluşturduysanız ve daha sonra "ana" sınıfı içeren JAR dosyasını Eclipse'e söylemeden dosya sisteminde farklı bir yere taşıdıysanız , Eclipse istemeden JVM'yi başlatır yanlış bir sınıfyoluyla.

Kısacası, bu sorunu bir IDE'de alırsanız, eski IDE durumu, bozuk proje referansları veya bozuk başlatıcı yapılandırmaları gibi şeyleri kontrol edin.

Bir IDE'nin basitçe karıştırılması da mümkündür. IDE'ler birbiriyle etkileşen birçok parça içeren oldukça karmaşık yazılım parçalarıdır. Bu parçaların birçoğu IDE'yi bir bütün olarak duyarlı hale getirmek için çeşitli önbellek stratejileri benimser. Bunlar bazen yanlış olabilir ve olası bir belirti, uygulamaları başlatırken karşılaşılan sorunlardır. Bunun olabileceğinden şüpheleniyorsanız, IDE'nizi yeniden başlatmak, projeyi yeniden oluşturmak vb. Gibi diğer şeyleri denemeye değer.


Diğer referanslar


43
Üçüncü taraf bir kütüphane ile bir Sınıf çalıştırmak çalışırken bu sorun vardı. Java'yı şöyle çağırdım java -cp ../third-party-library.jar com.my.package.MyClass:; Bu işe yaramaz, bunun yerine yerel yolu sınıf yoluna da eklemek gerekir (bununla ayrılarak :: java -cp ../third-party-library.jar:. com.my.package.MyClassşu şekilde çalışması gerekir
lanoxx

23
Yıllarca süren java programlamasından sonra hala bu sayfaya ulaşmayı başardım. Benim için sorun, sınıf yolu sözdiziminin işletim sistemine bağımlı olmasıydı . Windows'da programlama konusunda yeniyim ve hiçbir fikrim yoktu.
keyser

5
Ek notlar, 2. nokta beni kurtar! Bunun javaiçe aktarılan bir sınıf bulamadığını değil, çalıştırmaya çalıştığınız ana sınıfı söylemediğini görmek üzücü . Bunun yanıltıcı olmasına rağmen, bunun bir nedeni olduğundan eminim. javaSınıfımın tam olarak nerede olduğunu bildim, ancak ithal edilen sınıflardan birini bulamadı. Bunu söylemek yerine, ana sınıfımı bulamamaktan yakındı. Gerçekten sinir bozucu.
MSX

Eclipse'de bu problemi iki kez yaşadım. İlk kez main () imzası yanlıştı. İkinci kez bir .jar adını değiştirdim ve yeni olanı oluşturma yoluna eklesem de, Eclipse eskisini bulamadı, bu yüzden proje bu hatayla derlenmedi. .Jar dosyasını Proje> Özellikler> Java Derleme Yolu> Kitaplıklar'dan kaldırmak zorunda kaldım.
GregT

Üçüncü kez karşılaştım. Programı bir Windows 10 toplu iş dosyasından çalıştırıyorum ve .jar adını bir değişkene ("-cp% jarname%; lib *" olarak adlandırılır) koydum. Yanlışlıkla jar adının sonuna fazladan bir boşluk koydum ve bu hataya neden oldu. Hat hilesi :)
GregT

239

Kaynak kod adınız HelloWorld.java ise, derlenmiş kodunuz olacaktır HelloWorld.class.

Şunu kullanarak ararsanız bu hatayı alırsınız:

java HelloWorld.class

Bunun yerine şunu kullanın:

java HelloWorld

3
Sorun, bu çözümün yalnızca JAR dosya bağımlılığı olmayan varsayılan pakette bildirilen Java sınıfları için çalışmasıdır. (Ve o zaman bile, her zaman değil.) Çoğu Java programı o kadar basit değildir.
Stephen C

1
Stephen'ın dediği gibi, bu sadece "varsayılan paket" ile çalışır - yani dosyanın üst kısmında paket bildirimi yoktur . Bazı kodların hızlı bir test için, yaptım: javac TestCode.javaardındanjava TestCode
Birisi

Bu benim için işe yaramadı. Hala "Ana sınıf HelloWorld bulunamadı veya yüklenemedi" diyor
Jim

java -jar HelloWorld.jar da bir seçenektir
BMaximus

12
Yapmam gerekiyordujava -classpath . HelloWorld
Chris Prince

136

Dersleriniz ambalajlarda ise o zaman gerek cdprojenizin kök dizinine ve sınıf (packageName.MainClassName) tam nitelikli adını kullanarak çalıştırın.

Misal:

Derslerim burada:

D:\project\com\cse\

Ana sınıfımın tam adı:

com.cse.Main

Bu yüzden cdkök proje dizinine geri dönüyorum:

D:\project

Sonra javakomutu verin:

java com.cse.Main

Bu cevap, acemi java programcılarını ortak bir hatanın neden olduğu hayal kırıklığından kurtarmak için, java sınıfyolu hakkında daha ayrıntılı bilgi için kabul edilen cevabı okumanızı tavsiye ederim.


2
Bu cevap bir sürü varsayım yapar. Ve bunu başarmanın başka yolları da var. Yukarıdaki tavsiyeyi körü körüne takip etmek yerine, insanların Cevabımdaki Java sınıf yolunun nasıl çalıştığını açıklayan bağlantıları okumaya zaman ayırmalarını tavsiye ederim. Yaptıklarınızı ANLAMAK daha iyidir ...
Stephen C

2
Bu cevap tam olarak gerekli varsayımları yapar :) .class dosyasının dizininde bulunan ve java.exe çalışmıyor. Yukarıda cd-ed ve çalıştı komut satırında paket adı ile koştu.
Nick Constantine

61

Ana sınıfı ve ana yöntemi a öğesinde tanımlarsanızpackage , sınıfın ( packageName.MainClassName) tam adını kullanarak hiyerarşik dizin üzerinde çalıştırmalısınız .

Bir kaynak kodu dosyası olduğunu varsayın (Main.java):

package com.test;

public class Main {

    public static void main(String[] args) {
        System.out.println("salam 2nya\n");
    }
}

Bu kodu çalıştırmak Main.Classiçin pakete dizin gibi yerleştirmelisiniz ./com/test/Main.Java. Ve kök dizinde kullanın java com.test.Main.


1
Cevabımın "Ek Notlar # 1" e bakınız. Bu sorunun daha iyi bir açıklaması için.
Stephen C

14
@StephenC Evet, cevabınız daha eksiksiz (ve elbette +1), ancak bu özel cevapta "paket" kelimesi vardı, bu da ihtiyacım olanı hızlı bir şekilde bulmamı sağladı. Ve işe yaradı. +1 Razavi. StephenC, Java'da yeni olduğum için ihtiyacım olan basit paket örneğinden yoksun.
kmort

5
Bu benim sorunumdu. Tonlarca Java belgesinde dolaşıyorum ve bu somut örnek ihtiyacım olan şey
John

1
Evet, somut örnek güzel, bu mükemmel çalıştı. Eminim ana cevap çok kapsamlı, ama orman için ağacı görmek zordu. Hoş bir @Razavi
Pixel

1
Kabul edilen cevap yerine bu kısa ve faydalı cevabı seviyorum!
Spara

46

Aynı kod bir bilgisayarda çalıştığında, ancak başka bir bilgisayarda hatayı gösterdiğinde, şimdiye kadar bulduğum en iyi çözüm aşağıdaki gibi derleniyor:

javac HelloWorld.java
java -cp . HelloWorld

2
Bu iyi bir öneri değil. Ayarlanmamış olan veya "." İle tutarlı bir değere sahip olan CLASSPATH ortam değişkenine bağlısınız. Evet, birçok durumda çalışır, ancak diğerlerinde olmaz.
Stephen C

Kesinlikle javac -classpath . HelloWorld.javaişe yarardı! Ve bu sizin durumunuzda daha iyi bir çözümdür.
Stephen C

2
İlk satır olarak 'package com.some.address' varsa - bu işe yaramaz. 'Paket adresi' yazmanız gerekecek ..
Joe

1
@Joe - Bu kesmek (paketi yorumlamak) işe yarayacak (bazı durumlarda) ama kötü bir fikir. Daha iyi bir fikir, soruna neyin neden olduğunu öğrenmek / anlamak ve doğru çözümü uygulamaktır.
Stephen C

36

Bana yardımcı olan, komut satırında sınıf yolunu belirtmekti, örneğin:

  1. Yeni bir klasör oluşturun, C:\temp

  2. İçinde C:\tempaşağıdaki sınıfla Temp.java dosyası oluşturun :

    public class Temp {
        public static void main(String args[]) {
            System.out.println(args[0]);
        }
    }
  3. Klasörde bir komut satırı açın C:\tempve Temp sınıfını derlemek için aşağıdaki komutu yazın:

    javac Temp.java
  4. Derlenmiş Java sınıfını çalıştırın ve JRE'nin sınıfı -classpathnerede bulacağını bildirme seçeneğini ekleyin:

    java -classpath C:\temp Temp Hello!

3
Ubuntu'da da yolu belirtmek zorunda kaldım. Neden Geçerli Çalışma Dizini'ni varsayılan olarak kullanamayacağını anlamıyorum. Java'nın Klavye üreticileri tarafından desteklendiğine inanıyorum !!
gitti

1
@gone - "." varsayılan olarak $ PATH değerinde değildir, bu bir güvenlik tuzağı olmasıdır. seas.upenn.edu/cets/answers/dot-path.html
Stephen C

Bunun için çok teşekkürler ...... java neden ortam değişkenleri ayarladıktan sonra sınıf yolunu bulmak mümkün değildi emin olmasa bile.
akash89

@ akash89 - en olası nedenleri: 1) javaEğer sınıf yolu ayarı değildi ortamda ayarlanmamış -classpath veya -jar) veya 2) kullanılan çünkü ($ CLASSPATH'e bakmıyordu yürürlükte bağlamında javaoldu Çalıştırmak; Örneğin, setenv komutlarını sağ kabuğa eklediğiniz dosyayı "kaynaklamadığınız" için.
Stephen C

Hala hata aldım: Ana sınıf bulunamadı veya yüklenemedi Temp herkes yardımcı olabilir!
Yıldız

27

Hata mesajına göre ("Ana sınıf bulunamadı veya yüklenemedi"), iki sorun kategorisi vardır:

  1. Ana sınıf bulunamadı
  2. Ana sınıf yüklenemedi (bu vaka kabul edilen cevapta tam olarak tartışılmıyor)

Ana sınıfı edilemeyen bulundu varken yazım hatası ya da yanlış sözdizimi tam nitelikli sınıf adında veya sağlanan sınıf yolunda yok .

Ana sınıfı edilemeyen yüklü olduğunda sınıfı başlatılamaz tipik olarak ana sınıfı başka bir sınıfı uzanır ve bir sınıfı sağlanmıştır sınıf yolunda mevcut değildir.

Örneğin:

public class YourMain extends org.apache.camel.spring.Main

Deve yayı dahil edilmezse, bu hata rapor edilir.


"Temelde" başka kategoriler de var. Ve eksik süper sınıf problemi çok sıradışı bir subcase. (O kadar sıradışı ki, bu sitede sorulan sorularda hiç görmedim.)
Stephen C

İKİ vardır çünkü hata "Ana sınıf BULUNAMADI veya YÜKLENEMEDİ". Başka kategoriler varsa, lütfen bana bildirin. Onu gördüm, bu yüzden sadece burada paylaşmak istiyorum belki başka birine ihtiyacınız olacak.
Xiao Peng - ZenUML.com

1
Ben "Bu özel hata önlemek için ana sınıfı başlatmak için gereken tüm sınıfları dahil etmek gerekir" gibi bir şey için revize olurdu. Seni ikna etmeye çalışmıyorum. Bu sadece görmek istediğim bir yol. Cevabı burada sadece bir şekilde bu şekilde okumak isteyebilecek insanlar için bıraktım. Bu tartışmayı daha fazla genişletmeyelim :) İfademi "kabul edilen cevapta tam olarak tartışılmadı" olarak değiştirdim ve umarım daha iyi hissedersin.
Xiao Peng - ZenUML.com

5
Bu bilgi çok önemlidir ve açık bir sözü hak etmektedir (bahsettiğimiz tek cevap budur extends). Sadece ana sınıfı başarısız olduğunda o zor yoldan öğrendim yük o olamazdı başka uzanır, çünkü bulundu , java bulunamadı fiili hangi sınıf bildirmez (aksine NoClassDefFoundError). Yani evet oluyor ve bunu bilmediğinizde saçınızı çeken bir durum var.
Hugues M.

1
Bu durumda tam olarak hangi bağımlılık sınıfının yüklenemediğini anlamanın bir yolu var mı?
Carlos A. Ibarra

16

Bu durumda böyle bir hata vardı:

java -cp lib.jar com.mypackage.Main

;Windows ve :Unix için çalışır :

java -cp lib.jar; com.mypackage.Main

Evet. Bunun nedeni büyük olasılıkla MainJAR dosyasında olmamasıdır. sınıf yoluna dahil edilen geçerli dizinle -cp lib.jar;aynı anlama gelir -cp lib.jar;..
Stephen C

Sonunda unix sorunu giderildi .. teşekkürler (ile çalışır :)
Vicky

16

-Xdiag'ı deneyin .

Steve C'nin cevabı olası vakaları iyi bir şekilde kapsar, ancak bazen sınıfın bulunamadığını veya yüklenemediğini belirlemek o kadar kolay olmayabilir. java -Xdiag(JDK 7'den beri) kullanın . Bu, mesaj Could not find or load main classmesajının ne anlama geldiğine dair bir ipucu veren güzel bir yığın izi yazdırır .

Örneğin, sizi ana sınıf tarafından kullanılan ve bulunamayan ve ana sınıfın yüklenmesini engelleyen diğer sınıflara yönlendirebilir.


16

Bu komutu kullanın:

java -cp . [PACKAGE.]CLASSNAME

Örnek: Sınıf adınız Hello.java'dan oluşturulan Hello.class ise, aşağıdaki komutu kullanın:

java -cp . Hello

Hello.java dosyanız com.demo paketinin içindeyse aşağıdaki komutu kullanın

java -cp . com.demo.Hello

JDK 8 ile birçok kez sınıf dosyası aynı klasörde bulunur, ancak javakomut sınıfyolunu bekler ve bu nedenle -cp .geçerli klasörü sınıf yolu için referans olarak almayı ekleriz .


Bu sadece basit durumlarda işe yarar. Daha karmaşık vakalar daha karmaşık bir sınıfyolu gerektirir.
Stephen C

Ve >> gerçekten << basit durumlar -cp .için gereksizdir, çünkü $CLASSPATHayarlanmamışsa .varsayılan sınıfyoludur.
Stephen C

Hayır Stephen, Windows varsayılan sınıf yolunda birçok kez çalışmaz. Üç farklı makinede denedim, siz de deneyebilirsiniz.
shaILU

Bunun nedeni muhtemelen% CLASSPATH% ortam değişkenini bir yerde ayarlamış olmanızdır. Bunu yaparsanız, varsayılan sınıf yolunu kullanmıyorsunuzdur. ( echo %CLASSPATH%Çıktı nedir?) Ve hayır, kontrol edemiyorum çünkü Windows bilgisayarım yok.
Stephen C

2
Komut satırından basit bir program çalıştırmaya çalıştığımda bu benim için çalıştı
SnuKies

15

Bazen soruna neden olan şeyin ana sınıfla bir ilgisi yoktur ve bunu zor yoldan bulmak zorunda kaldım. Taşındığım referanslı bir kütüphaneydi ve bana şunları verdi:

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

Bu referansı yeni sildim, tekrar ekledim ve tekrar işe yaradı.


1
Sorun, IDE'nizde projenizdeki bozuk bir "referans" nedeniyle yanlış bir sınıfyoluna sahip olmanız gibi görünüyor. Cevabımı kapsayacak şekilde cevabımı güncelleyeceğim.
Stephen C

@StephenC ve EduardoDennis, Burada da bir kavanoz eksikti, bu kavanoz ana sınıfın örneklenmeye bağlı olduğu bir arayüz içeriyordu. Bu nedenle, hata mesajı çok geniş. Sınıf dosyası bulunamazsa ve "eksik (bağımlılıklar)" yüklenemediğinde "bulamadım" demeliyim, eksik başka bir şey varsa ancak dosyanın kendisi değil, bu yüzden çok geniş olan hata iletisi yalnızca odaklanırsanız yanıltıcıdır. "Bul" kısmında :(
Kova Gücü

@AquariusPower - Wht sınıfının eksik olduğu "neden" istisnası için "yığın izlemesi" nedeniyle ek bir "olmalıydı. Java geliştiricilerine, 20 yıldan fazla bir süredir söyleyen bir hata mesajını değiştirmelerini önermek isterseniz ... çekinmeyin. (Hata mesajının doğru olduğunu düşünüyorum. Sorun, >> siz << yanlış fıkra daralmıştı.)
Stephen C

@StephenC demek istediğim, ana sınıf dosyası varsa ya da mevcut değilse, kesinlikle bilgilere erişebilirler, bu yüzden neden bu dosyanın eksik olduğunu söyleyen daha iyi bir hata mesajı göstermiyorsunuz. Öte yandan, "Dosya bulundu, ancak yüklenemedi" diyebilirlerdi, yarım gün araştırmak ve anlamak için şeyleri test etmek yerine derhal bağımlılıklara odaklanırdık. Demek istediğim :). 20 yılı aşkın bir süredir sınırlı bir şekilde yapabilirler, ancak geliştirebilirler ve eleştirimiz ve şikâyetlerimizle bunun gerçekleşmesi için buradayız! : D
Kova Gücü

Lütfen ne anlama geldiğini anlayın >> I <<. 3 yaşındaki soru-cevap üzerine bazı belirsiz yorumlarda şikayet etmek hiçbir şey başaramayacak. Şikayetleriniz konusunda bilinçli davranabilecek insanlar bunu fark etmeyecektir. Yapıcı bir şey yapmak istiyorsanız, bir yama gönderin. (Şansınızı değerlendirmiyorum, ama sadece bunun hakkında sızlandığınızdan daha büyük olacaklar.)
Stephen C

10

Bu örnekte:

Ana sınıf bulunamadı veya yüklenemedi mi?

Çünkü "-classpath" kullanıyorsunuz, ancak çizgi javakomut isteminde kullanılan aynı çizgi değil . Kopyalama ve Not Defteri'nden cmd yapıştırma bu sorunu vardı .


2
Vaov! Bu tamamen tuhaf bir sebep! (Ama gerçek bir metin editörü yerine Not Defteri'ni kullanmak için size doğru :-))
Stephen C

10

Aynı sorunu vardı ve sonunda hatamı buldum :) Derleme için bu komutu kullandım ve doğru çalıştı:

javac -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode.java

Ama bu komut benim için çalışmadı (ana sınıfı bulamadım veya yükleyemedim qrcode):

java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar" qrcode

Sonunda sınıf yolunun sonuna ':' karakterini ekledim ve problem çözüldü:

java -cp "/home/omidmohebbi/AAAATest/jars/core-1.7.jar:/home/omidmohebbi/AAAATest/jars/javase-1.7.jar:/home/omidmohebbi/AAAATest/jars/qrgen-1.2.jar:" qrcode

7

Benim durumumda, sınıf adı yerine kaynak dosya adını sağladığım için hata oluştu.

Tercümana ana yöntemi içeren sınıf adını vermemiz gerekir.


Evet. Sınıf adını belirtmek için yanlış yolların örnek 2'sine bakın !!
Stephen C

7

Durumunuz benimki gibi ise bu size yardımcı olabilir: Yeni başlayanlar olarak bir Java programını çalıştırmaya çalıştığımda da bu problemle karşılaştım.

Ben şöyle derledim:

javac HelloWorld.java

Ve aynı uzantıyla da çalışmayı denedim:

java Helloworld.java

.javaKomutu kaldırdığımda ve komutu yeniden yazdığımda java HelloWorld, program mükemmel bir şekilde çalıştı. :)


2
Bunun nedeni, .java dosyanızın derlenmiş sürümünü yürütüyorsunuz. Aslında .class dosyasını yürütüyor
Jason V

Kayıt için, bu
Stephen C

6

Buradaki tüm yanıtlar, görünüşe göre Windows kullanıcılarına yöneliktir. Mac için, sınıf yolu ayırıcısı :değildir ;. Hata olarak sınıf yolunu ayarlarken; , Windows'tan Mac'e geliyorsa bunu bulmak zor olabilir.

İşte karşılık gelen Mac komutu:

java -classpath ".:./lib/*" com.test.MyClass

Bu örnekte paket com.testve libsınıf yoluna bir klasör de dahil edilecektir.


2
Linux'ta Mac'te olduğu gibi.
Alex78191

Neden /*gerekli?
Alex78191

Bir joker karakter sözdizimidir. (Zorunlu değildir. İsterseniz JAR'ları açıkça listeleyebilirsiniz.)
Stephen C

6

resim açıklamasını buraya girin

Sınıf dosyası konumu: C: \ test \ com \ company

Dosya Adı: Main.class

Tam nitelikli sınıf adı: com.company.Main

Komut satırı komutu:

java  -classpath "C:\test" com.company.Main

Burada sınıf yolunun \ com \ company içermediğini unutmayın


6

Bu sorunu çözmeye çalışmak için iyi bir zaman geçirdim. Bir şekilde benim sınıf yolu yanlış ayarlanmış olduğunu düşündüm ama sorun ben yazdım oldu:

java -cp C:/java/MyClasses C:/java/MyClasses/utilities/myapp/Cool  

onun yerine:

java -cp C:/java/MyClasses utilities/myapp/Cool   

Tam olarak nitelenmenin anlamının, tam paket adı yerine tam yol adını içermesi gerektiğini düşündüm.


Bu karışıklığı gidermeye çalışmak için cevabımı güncelledim.
Stephen C

2
Bunların hiçbiri doğru değil. Sınıf utilities.myapp.Cool, varsa paket adı olarak veya varsa adı verilmelidir .
user207421

5

Önce bu komutu kullanarak yolu ayarlayın;

set path="paste the set path address"

O zaman 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 ve enter tuşuna basın ve "cd (klasör adı)" yazın.


4
Bu yardımcı olmuyor. Bu Soru, sıradan yürütülebilir dosyalarla değil, Java programlarıyla ilgilidir. Java, PATH'yi hiçbir şey bulmak için kullanmaz ve "cd" yardımcı olursa, karardan ziyade şansla.
Stephen C

if "cd" helps then it by luck rather than by judgement. Java, .varsayılan olarak sınıf yolunun bir parçası olarak geçerli dizini kullandığından, bu (inanıyorum) yanlıştır .
GKFX

2
@GKFX - Demek istediğim bu. Varsayılan sınıf yolunu (veya üzerinde "." Bulunan bir sınıf yolunu) kullandığınızı bilmiyorsanız, "cd" nin bir etkisi olmaz. Bu çözüm yargılardan ziyade şansla (yani "." Sınıf yolunda olduğunu tahmin ederek / umarak) işe yarar (yani "." Sınıf yolunda olduğunu kontrol ederek). Ayrıca varsayılan hakkında yanlış. Java "" kullanır. varsayılan olarak sınıfyolunun bir parçası olarak değil, varsayılan olarak sınıf yolunun bir parçası olarak değil.
Stephen C

5

Benim durumumda sorunu ne düzeltti:

Çalıştırmak istediğiniz projeye / sınıfa sağ tıklayın, ardından Run As-> Run Configurations. Ardından, mevcut yapılandırmanızı düzeltmeli veya aşağıdaki şekilde yenisini eklemelisiniz:

Classpathsekmeyi açın, Advanced...düğmeyi tıklayın ve ardından projenizin binklasörünü ekleyin .


5

JAR dosyasını oluşturmak için Maven kullanıyorsanız , lütfen pom.xml dosyasında ana sınıfı belirttiğinizden emin olun:

<build>
    <plugins>
        <plugin>
            <artifactId>maven-jar-plugin</artifactId>
            <configuration>
                <archive>
                    <manifest>
                        <mainClass>class name us.com.test.abc.MyMainClass</mainClass>
                    </manifest>
                </archive>
            </configuration>
        </plugin>
    </plugins>
</build>

4

Bu özel bir durum, ancak bu sayfaya bir çözüm arayan ve bulamadığım için buraya ekleyeceğim.

Windows (7 ile test edilmiştir á) sınıf ve paket adlarında özel karakterleri (örneğin ) kabul etmez . Linux da öyle.

Ben .jarNetBeans bir inşa ve komut satırında çalıştırmaya çalışırken bunu öğrendim . NetBeans'te çalıştırıldı, ancak komut satırında değil.


4

Windows'ta .;başlangıçta CLASSPATH değerine koyun .

. (nokta) "geçerli dizine bak" anlamına gelir. Bu kalıcı bir çözümdür.

Ayrıca set ile "bir kez" ayarlayabilirsiniz CLASSPATH=%CLASSPATH%;.. Bu, cmd pencereniz açık olduğu sürece devam eder.


1
Bu tavsiye yardımcı olabilir veya olmayabilir. Geçerli dizindeki sınıfları içeren sınıf ağacının yardımcı olması yardımcı olacaktır. Olmazsa olmaz. Aslında bunu yapmazdım. Bunun yerine, kullanıcının "sağ" dizinde olup olmadığına bakılmaksızın çalışan bir satırlık sarmalayıcı komut dosyası oluşturdum.
Stephen C

4

Bunu gerçekten srcklasörden yapmanız gerekir . Orada aşağıdaki komut satırını yazıyorsunuz:

[name of the package].[Class Name] [arguments]

Diyelim ki sınıfınız çağrıldı CommandLine.classve kod şöyle görünüyor:

package com.tutorialspoint.java;

    /**
     * Created by mda21185 on 15-6-2016.
     */

    public class CommandLine {
        public static void main(String args[]){
            for(int i=0; i<args.length; i++){
                System.out.println("args[" + i + "]: " + args[i]);
            }
        }
    }

Sonra cdsrc klasörüne gitmelisiniz ve çalıştırmanız gereken komut şöyle görünecektir:

java com.tutorialspoint.java.CommandLine this is a command line 200 -100

Ve komut satırındaki çıktı:

args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100

2
Bir sınıf "CommandLine.class" olarak adlandırılamaz. Bu bir Java sözdizimi hatası olacaktır. (Yani derlenmiş sınıfı içeren dosyaya "CommandLine.class" denir ...). Diğer bir sorun, "kaynak dizine cd" yönergesinin yalnızca kodu >> kaynak dizin ağacına derlediğinizde çalışmasıdır. Son olarak, derlemeniz "-cp" bağımsız değişkeni kullandıysa, çalıştırdığınızda eşdeğer olması gerekir.
Stephen C

Projemde kökte src klasörü ve bin klasörü var. Benim için çalışan komuta cdgirmek zorunda kaldım . Yani bahşiş için teşekkürler! srcjava ../bin com.blah.blah.MyClass
tamj0rd2

3

Java'da, java yürütülebilir dosyasını kullanarak bazen JVM'yi komut satırından çalıştırdığınızda ve genel statik void main (PSVM) olan bir sınıf dosyasından bir program başlatmaya çalıştığınızda, classpath parametresi JVM doğrudur ve sınıf dosyası sınıfyolunda bulunur:

Error: main class not found or loaded

PSVM olan sınıf dosyası yüklenemediğinde bu olur. Bunun olası bir nedeni, sınıfın bir arabirim uygulamak veya sınıfyolunda olmayan başka bir sınıfı genişletmesi olabilir. Normalde bir sınıf sınıfyolunda değilse, atılan hata bu şekilde gösterilir. Ancak, kullanılan sınıf genişletilir veya uygulanırsa, java sınıfın kendisini yükleyemez.

Referans: https://www.computingnotes.net/java/error-main-class-not-found-or-loaded/


1
Kabul edilen cevabı okudun mu? Cevabınız yeni bir şey ekliyor mu?
Stephen C

1
@StephenC Listenizde "Neden" kategorilerine ve puanlarına bakarak bir neden bulmaya çalıştım. "Reason # 1" ve "Reason # 2" başlığında eşleme noktasını bulamadım (sınıf yolunun kendisinde bir sorun olmadığından emin olduğumdan) benim durumuma yakın görünmedi. Ben deneyler yaparak nedeni buldum ve benim durumumda "ana sınıf bulunamadı" hatası gösterildi çünkü arabirim uygulama sınıf yolunda değildi şaşırdı. Tabii ki "yazıda açıklanan her şeyi okumak gerekir" diyebilirsiniz ama bana öyle geliyor ki neden listeniz geliştirilebilir.
17'de sakızlar

3

Windows PowerShell'de reklamı javayapılan -cpseçenekle çalışırken, aşağıdakine benzer bir hata alabilirsiniz:

The term `ClassName` is not recognized as the name of a cmdlet, function, script ...

PowerShell'in komutu kabul edebilmesi için, -cpseçeneğin bağımsız değişkenleri aşağıdaki gibi tırnak içine alınmalıdır:

java -cp 'someDependency.jar;.' ClassName

Komutun bu şekilde oluşturulması, Java'nın sınıf yolu bağımsız değişkenlerini doğru şekilde işlemesine izin vermelidir.


3

Java MongoDB JDBC bağlantısını test ederken de benzer hatalarla karşılaştım. Bence nihai çözümümü kısaca özetlemek iyi olacak, böylece gelecekte herkes iki komuta doğrudan bakabilir ve daha ileriye gidebilir.

Java dosyanızın ve harici bağımlılıkların (JAR dosyaları) bulunduğu dizinde olduğunuzu varsayın.

Derleme:

javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
  • -cp - sınıfyolu argümanı; tüm bağımlı JAR dosyalarını tek tek geçirin
  • * .java - Bu, ana yöntemi olan Java sınıfı dosyasıdır. sdsd

Çalıştırmak:

java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
  • Lütfen tüm bağımlılık JAR dosyaları sona erdikten sonra iki nokta üst üste (Unix) / virgül (Windows) gözlemleyin
  • Sonunda, ana sınıf adını herhangi bir uzantı olmadan gözlemleyin (.class veya .java yok)

Bu, 1) JavaMongoDBConnectionhiçbir paketi olmadığını ve 2) dizini değiştirmediğinizi varsayar . Az söylemek gerekirse kırılgandır. Ve sorunları açıklamamak, yeni başlayanların çalışmadığı durumlarda bu yaklaşımı denemelerine yol açacaktır . Kısacası, "voodoo programlama teknikleri" ni teşvik eder: en.wikipedia.org/wiki/Voodoo_programming
Stephen C

3

Pekala, zaten birçok cevap var, ancak kimse dosya izinlerinin suçlu olabileceği durumundan bahsetmedi.

Çalıştırırken, kullanıcının JAR dosyasına veya yolun dizinlerinden birine erişimi olmayabilir. Örneğin:

Jar dosyası /dir1/dir2/dir3/myjar.jar

JAR dosyasının sahibi olan Kullanıcı1 şunları yapabilir:

# Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar

Ama yine de çalışmıyor:

# Running as User2
java -cp "/dir1/dir2/dir3:/dir1/dir2/javalibs" MyProgram
Error: Could not find or load main class MyProgram

Bunun nedeni, çalışan kullanıcının (Kullanıcı2) dir1, dir2 veya javalibs veya dir3'e erişimi olmamasıdır. Kullanıcı1 dosyaları görebildiğinde ve dosyalara erişebildiğinde birisini delebilir, ancak kullanıcı2 için hala hata oluşur.


2

Ben yaptıktan sonra bu hatayı aldım Bu mvn eclipse:eclipse benim .classpathdosya biraz berbat .

Satırları değiştirmek zorunda kaldı .classpathdan

<classpathentry kind="src" path="src/main/java" including="**/*.java"/>
<classpathentry kind="src" path="src/main/resources" excluding="**/*.java"/>

için

<classpathentry kind="src" path="src/main/java" output="target/classes" />
<classpathentry kind="src" path="src/main/resources" excluding="**"  output="target/classes" />

2

Bu sorunu burada belirtilen çözümlerle çözemedim (belirtilen cevap şüphesiz konseptlerimi temizlemiş olsa da). Bu sorunla iki kez karşılaştım ve her seferinde farklı çözümler denedim (Eclipse IDE'de).

  • İlk olarak, projemin mainfarklı sınıflarında birden çok yöntemle karşılaştım. Bu yüzden mainyöntemi sonraki sınıflardan silmiştim .
  • İkincisi, aşağıdaki çözümü denedim:
    1. Ana proje dizinime sağ tıklayın.
    2. Kaynağa gidin ve temizleyin ve varsayılan ayarlara ve Son'a sadık kalın. Bazı arka plan görevlerinden sonra ana proje dizininize yönlendirileceksiniz.
    3. Ondan sonra projemi kapattım, yeniden açtım ve patladım, sonunda sorunumu çözdüm.

1
mainYöntemleri silmek sorunu çözmez. Birden fazla giriş noktası olan bir uygulamada teknik olarak yanlış bir şey yoktur.
Stephen C
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.