Cosa significa “Imansible trovare o caricare la class principale”?

Un problema comune ai nuovi sviluppatori Java è che i loro programmi non riescono a girare con il messaggio di errore: Could not find or load main class ...

Che cosa significa questo, che cosa lo causa e come dovresti risolverlo?

La syntax del comando java

Prima di tutto, devi capire il modo corretto di avviare un programma usando il comando java (o javaw ).

La syntax normale 1 è questa:

  java [  

dove è un’opzione della riga di comando (che inizia con un carattere “-“), è un nome di class Java completo e è un argomento di riga di comando arbitrario che viene passato all’applicazione.
1 – Esiste una seconda syntax per i file JAR “eseguibili” che descriverò in fondo.

Il nome completo (FQN) per la class è convenzionalmente scritto come nel codice sorgente Java; per esempio

  packagename.packagename2.packagename3.ClassName 

Tuttavia alcune versioni del comando java consentono di utilizzare le barre anziché i punti; per esempio

  packagename/packagename2/packagename3/ClassName 

che (confusamente) sembra un nome di percorso del file, ma non è uno. Nota che il termine nome completo è terminologia Java standard … non qualcosa che ho appena inventato per confonderti 🙂

Ecco un esempio di come dovrebbe apparire un comando java :

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

Quanto sopra farà sì che il comando java esegua le seguenti operazioni:

  1. Cerca la versione compilata della class com.acme.example.ListUsers .
  2. Carica la class
  3. Verifica che la class abbia un metodo main con firma , tipo di ritorno e modificatori forniti da public static void main(String[]) . (Nota, il nome dell’argomento metodo NON fa parte della firma.)
  4. Chiama quel metodo passandogli gli argomenti della riga di comando (“fred”, “joe”, “bert”) come String[] .

Ragioni per cui Java non riesce a trovare la class

Quando viene visualizzato il messaggio “Imansible trovare o caricare la class principale …”, significa che il primo passaggio non è riuscito. Il comando java non è stato in grado di trovare la class. E infatti, “…” nel messaggio sarà il nome di class completo che java sta cercando.

Allora perché potrebbe non essere in grado di trovare la class?

Motivo n. 1: hai commesso un errore con l’argomento classname

La prima causa probabile è che potresti aver fornito il nome di class sbagliato. (Oppure … il nome giusto della class, ma nella forma sbagliata.) Considerando l’esempio sopra, qui una varietà di modi sbagliati per specificare il nome della class:

  • Esempio n. 1: un semplice nome di class:

     java ListUser 

    Quando la class è dichiarata in un pacchetto come com.acme.example , allora devi usare il nome completo della class incluso il nome del pacchetto nel comando java ; per esempio

     java com.acme.example.ListUser 
  • Esempio n. 2: un nome file o percorso anziché un nome class:

     java ListUser.class java com/acme/example/ListUser.class 
  • Esempio n. 3: un nome di class con l’involucro errato:

     java com.acme.example.listuser 
  • Esempio n. 4: un errore di battitura

     java com.acme.example.mistuser 
  • Esempio # 5: un nome file di origine

     java ListUser.java 
  • Esempio 6: hai dimenticato completamente il nome della class

     java lots of arguments 

Motivo n. 2: il classpath dell’applicazione è stato erroneamente specificato

La seconda causa probabile è che il nome della class sia corretto, ma che il comando java non possa trovare la class. Per capire questo, è necessario comprendere il concetto di “classpath”. Questo è spiegato bene dalla documentazione di Oracle:

  • La documentazione del comando java
  • Impostazione del percorso di class .
  • The Java Tutorial – PATH e CLASSPATH

Quindi … se hai specificato correttamente il nome della class, la prossima cosa da verificare è che hai specificato correttamente il classpath:

  1. Leggi i tre documenti collegati sopra. (Sì … LEGGETE: è importante che un programmatore Java comprenda almeno le basi di come funziona il meccanismo del classpath Java).
  2. Guarda la riga di comando e / o la variabile di ambiente CLASSPATH che è in vigore quando si esegue il comando java . Verifica che i nomi delle directory e i nomi dei file JAR siano corretti.
  3. Se esistono percorsi relativi nel classpath, controllare che si risolvano correttamente … dalla directory corrente che è in vigore quando si esegue il comando java .
  4. Verificare che la class (menzionata nel messaggio di errore) possa trovarsi sul classpath effettivo .
  5. Si noti che la syntax del classpath è diversa per Windows rispetto a Linux e Mac OS. (Il separatore del classpath è ; su Windows e : sugli altri.)

Motivo n. 2a: la directory errata si trova sul classpath

Quando si inserisce una directory sul classpath, corrisponde in teoria alla radice dello spazio dei nomi qualificato. Le classi si trovano nella struttura di directory sotto quella radice, mappando il nome completo in un percorso . Ad esempio, se “/ usr / local / acme / classs” si trova sul percorso della class, quando la JVM cerca una class chiamata com.acme.example.Foon , cercherà un file “.class” con questo percorso:

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

Se avessi messo “/ usr / local / acme / classs / com / acme / example” sul classpath, la JVM non sarebbe stata in grado di trovare la class.

Motivo n. 2b: il percorso della sottodirectory non corrisponde al FQN

Se il tuo corso FQN è com.acme.example.Foon , allora la JVM cercherà “Foon.class” nella directory “com / acme / example”:

  • Se la struttura della directory non corrisponde alla denominazione del pacchetto come da schema precedente, la JVM non troverà la class.

  • Se provi a rinominare una class spostandola, fallirà anche … ma lo stacktrace di eccezione sarà diverso.

Per fare un esempio concreto, supponendo che:

  • vuoi eseguire com.acme.example.Foon class,
  • il percorso completo del file è /usr/local/acme/classs/com/acme/example/Foon.class ,
  • la tua attuale directory di lavoro è /usr/local/acme/classs/com/acme/example/ ,

poi:

 # 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/classs com.acme.example.Foon 

Gli appunti:

  • L’opzione -classpath può essere abbreviata in -cp nella maggior parte delle versioni di Java. Controllare le rispettive voci del manuale per java , javac e così via.
  • Pensa attentamente quando scegli tra percorsi assoluti e relativi in ​​classpaths. Ricorda che un percorso relativo può “rompersi” se la directory corrente cambia.

Motivo n. 2c: mancano le dipendenze dal classpath

Il classpath deve includere tutte le altre classi (non di sistema) da cui dipende l’applicazione. (Le classi di sistema si trovano automaticamente e raramente ti devi preoccupare di questo.) Perché la class principale si carichi correttamente, la JVM deve trovare:

  • la class stessa.
  • tutte le classi e le interfacce nella gerarchia della superclass (es. vedere la class Java è presente in classpath ma l’avvio non riesce con Errore: imansible trovare o caricare la class principale )
  • tutte le classi e le interfacce a cui si fa riferimento mediante dichiarazioni variabili o variabili, o chiamate al metodo o espressioni di accesso al campo.

(Nota: le specifiche JLS e JVM consentono un po ‘di spazio per una JVM per caricare le classi “pigramente”, e questo può influire quando viene lanciata un’eccezione del classloader.)

Motivo # 3: la class è stata dichiarata nel pacchetto sbagliato

Accade occasionalmente che qualcuno inserisca un file del codice sorgente nella cartella sbagliata nella loro struttura del codice sorgente, oppure ometta la dichiarazione del package . Se lo fai in un IDE, il compilatore dell’IDE ti parlerà immediatamente di questo. Allo stesso modo se si utilizza uno strumento di compilazione Java decente, lo strumento eseguirà javac in un modo che rileverà il problema. Tuttavia, se si costruisce manualmente il codice Java, è ansible farlo in modo tale che il compilatore non si accorga del problema e il file “.class” risultante non si trovi nel punto che ci si aspetta che sia.

Ancora non riesci a trovare il problema?

Ci sono molte cose da controllare, ed è facile perdere qualcosa. Prova ad aggiungere l’opzione -Xdiag alla riga di comando java (come prima cosa dopo java ). Produrrà varie cose sul caricamento delle classi, e questo potrebbe offrirti indizi su quale sia il vero problema.


La java -jar

La syntax alternativa utilizzata per i file JAR “eseguibili” è la seguente:

  java [  

per esempio

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

In questo caso il nome della class del punto di ingresso (es. com.acme.example.ListUser ) e il percorso di class sono specificati nel MANIFEST del file JAR.


IDE

Un tipico IDE Java supporta l’esecuzione di applicazioni Java nella JVM IDE stessa o in una JVM secondaria. Questi sono generalmente immuni da questa particolare eccezione, poiché l’IDE utilizza i propri meccanismi per build il percorso di class di runtime, identificare la class principale e creare la riga di comando java .

Tuttavia è ancora ansible che si verifichi questa eccezione, se si fanno cose dietro il retro dell’IDE. Ad esempio, se in Eclipse è stato precedentemente impostato un Application Launcher per l’app Java e il file JAR contenente la class “main” viene spostato in un’altra posizione nel file system senza dire ad Eclipse , Eclipse avvierà involontariamente JVM con un classpath errato.

In breve, se si verifica questo problema in un IDE, verificare la presenza di stato IDE obsoleto, riferimenti ai progetti non funzionanti o configurazioni di avvio non funzionanti.

È anche ansible che un IDE venga semplicemente confuso. Gli IDE sono pezzi di software estremamente complicati che comprendono molte parti interagenti. Molte di queste parti adottano varie strategie di memorizzazione nella cache al fine di rendere l’IDE nel suo complesso reattivo. Questi possono a volte andare storto e un ansible sintomo è un problema quando si lanciano le applicazioni. Se sospetti che ciò possa accadere, vale la pena riavviare il tuo IDE.


Altre referenze

  • Da Oracle Java Tutorials: problemi comuni (e relative soluzioni)

Se il nome del codice sorgente è HelloWorld.java, il codice compilato sarà HelloWorld.class .

Otterrai quell’errore se lo chiami usando:

 java HelloWorld.class 

Invece, usa questo:

 java HelloWorld 

Se le tue classi sono in pacchetti, devi eseguire il cd sulla directory principale ed eseguire utilizzando il nome completo della class (packageName.MainClassName).

Esempio:

Le mie lezioni sono qui:

 D:\project\com\cse\ 

Il nome completo della mia class principale è:

 com.cse.Main 

Quindi ritorna alla directory principale:

 D:\project 

Quindi emettere il comando java :

 java com.cse.Main 

Se il tuo metodo principale è nella class sotto un pacchetto, dovresti eseguirlo sulla directory gerarchica.

Supponiamo che ci sia un file di codice sorgente (Main.java):

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

Per eseguire questo codice, devi inserire Main.Class nella Main.Class del pacchetto ./com/test/Main.Java . E nella directory root usare java com.test.Main .

Quando lo stesso codice funziona su un PC, ma mostra l’errore in un altro, la soluzione migliore che abbia mai trovato è la compilazione come la seguente:

 javac HelloWorld.java java -cp . HelloWorld 

Quello che mi ha aiutato è stato specificare il classpath sulla riga di comando, ad esempio:

  1. Crea una nuova cartella, C:\temp

  2. Crea il file Temp.java in C:\temp , con la seguente class in esso:

     public class Temp { public static void main(String args[]) { System.out.println(args[0]); } } 
  3. Aprire una riga di comando nella cartella C:\temp e scrivere il seguente comando per compilare la class Temp:

     javac Temp.java 
  4. Esegui la class Java compilata, aggiungendo l’opzione -classpath per consentire a JRE di sapere dove trovare la class:

     java -classpath C:\temp Temp Hello! 

In base al messaggio di errore (“Imansible trovare o caricare la class principale”), esistono due categorie di problemi:

  1. La class principale non è stata trovata
  2. La class principale non può essere caricata (questo caso non è completamente discusso nella risposta accettata)

Imansible trovare la class principale quando c’è un errore di digitazione o una syntax errata nel nome class completo o non esiste nel classpath fornito .

La class principale non può essere caricata quando la class non può essere iniziata , in genere la class principale estende un’altra class e quella class non esiste nel classpath fornito.

Per esempio:

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

Se il cammello-molla non è incluso, questo errore verrà segnalato.

A volte ciò che potrebbe causare il problema non ha nulla a che fare con la class principale, e ho dovuto scoprirlo nel modo più difficile. Era una libreria di riferimento che ho spostato e mi ha dato:

Imansible trovare o caricare la class principale xxx Linux

Ho appena cancellato quel riferimento, l’ho aggiunto di nuovo e ha funzionato di nuovo bene.

Ho avuto un tale errore in questo caso:

 java -cp lib.jar com.mypackage.Main 

Funziona con ; per Windows e : per Unix:

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

Usa questo comando:

 java -cp . [PACKAGE.]CLASSNAME 

Esempio: se il tuo nome class è Hello.class creato da Hello.java, usa il seguente comando:

 java -cp . Hello 

Se il file Hello.java si trova nel pacchetto com.demo, utilizzare il comando seguente

 java -cp . com.demo.Hello 

Con JDK 8 molte volte accade che il file di class sia presente nella stessa cartella, ma il comando java aspetta un percorso di class e per questa ragione aggiungiamo -cp . prendere la cartella corrente come riferimento per classpath.

Prova -Xdiag .

La risposta di Steve C copre bene i casi possibili, ma a volte per determinare se la class non può essere trovata o caricata potrebbe non essere così facile. Usa java -Xdiag (da JDK 7). Questo stampa una bella traccia di stack che fornisce un suggerimento su ciò che il messaggio Could not find or load main class .

Ad esempio, può puntare ad altre classi utilizzate dalla class principale che non è stato ansible trovare e ha impedito il caricamento della class principale.

In questo caso hai:

Imansible trovare o caricare classpath di class principale

È perché stai usando “-classpath”, ma il trattino non è lo stesso trattino usato da java sul prompt dei comandi. Ho avuto questo problema di copiare e incollare da Blocco note a cmd.

Questo potrebbe aiutarti se il tuo caso è specifico del mio: da principiante mi sono imbattuto in questo problema anche quando ho provato a eseguire un programma Java.

L’ho compilato in questo modo:

 javac HelloWorld.java 

E ho provato a correre anche con la stessa estensione:

 java Helloworld.java 

Quando ho rimosso il .java e .java riscritto il comando come java HelloWorld , il programma ha funzionato perfettamente. 🙂

Nel mio caso, l’errore è apparso perché avevo fornito il nome del file sorgente al posto del nome della class.

Dobbiamo fornire il nome della class che contiene il metodo principale all’interprete.

Se utilizzi Maven per creare il file JAR, assicurati di specificare la class principale nel file pom.xml:

    maven-jar-plugin    class name us.com.test.abc.MyMainClass       

inserisci la descrizione dell'immagine qui

Posizione del file di class: C: \ test \ com \ company

Nome file: Main.class

Nome class completo : com.company.Main

Comando della riga di comando:

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

Nota che il percorso di class NON include \ com \ company

Ho trascorso una discreta quantità di tempo cercando di risolvere questo problema. Ho pensato che in qualche modo stavo impostando il mio classpath in modo errato ma il problema era che ho digitato:

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

invece di:

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

Pensavo che il significato di pienamente qualificato significasse includere il nome completo del percorso invece del nome completo del pacchetto.

Prima imposta il percorso usando questo comando;

 set path="paste the set path address" 

Quindi è necessario caricare il programma. Digita “cd (nome cartella)” nell’unità salvata e compila. Ad esempio, se il mio programma è memorizzato sull’unità D, digita “D:” premi invio e digita “cd (nome cartella)”.

Questo è un caso specifico, ma poiché sono arrivato a questa pagina cercando una soluzione e non l’ho trovata, la aggiungerò qui.

Windows (testato con 7) non accetta caratteri speciali (come á ) nei nomi di classi e pacchetti. Linux sì, però.

Ho trovato questo quando ho costruito un .jar in NetBeans e ho cercato di eseguirlo in linea di comando. Funzionava in NetBeans ma non nella riga di comando.

Quello che ha risolto il problema nel mio caso è stato:

Fare clic con il tasto destro del mouse sul progetto / class che si desidera eseguire, quindi Run As -> Run Configurations . Quindi è necessario correggere la configurazione esistente o aggiungerne una nuova nel seguente modo:

aprire la scheda Classpath , fare clic sul pulsante Advanced... quindi aggiungere la cartella bin del progetto.

Su Windows messo .; al valore di CLASSPATH all’inizio.

Il . (punto) significa “guarda nella directory corrente”. Questa è una soluzione permanente.

Inoltre puoi impostarlo “una volta” con set CLASSPATH=%CLASSPATH%;. . Questo durerà finché la finestra di cmd sarà aperta.

Tutte le risposte qui sono dirette verso gli utenti Windows che sembra. Per Mac, il separatore del classpath è:, not ; . Come errore durante l’impostazione del percorso di class ; non viene lanciato quindi questo può essere difficile da scoprire se proviene da Windows a Mac.

Ecco il comando Mac corrispondente:

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

Dove in questo esempio il pacchetto è com.test e una cartella di lib deve essere inclusa in classpath.

When running the java with the -cp option as advertised in Windows PowerShell you may get an error that looks something like:

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

In order to for PowerShell to accept the command, the arguments of the -cp option must be contained in quotes as in:

 java -cp 'someDependency.jar;.' ClassName 

Forming the command this way should allow Java process the classpath arguments correctly.

Sometimes, in some online compilers that you might have tried you will get this error if you don’t write public class [Classname] but just class [Classname] .

In Java, when you sometimes run the JVM from the command line using the java executable and are trying to start a program from a class file with public static void main (PSVM), you might run into the below error even though the classpath parameter to the JVM is accurate and the class file is present on the classpath:

 Error: main class not found or loaded 

This happens if the class file with PSVM could not be loaded. One possible reason for that is that the class may be implementing an interface or extending another class that is not on the classpath. Normally if a class is not on the classpath, the error thrown indicates as such. But, if the class in use is extended or implemented, java is unable to load the class itself.

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

I got this error after doing mvn eclipse:eclipse This messed up my .classpath file a little bit.

Had to change the lines in .classpath from

   

a

   

You really need to do this from the src folder. There you type the following command line:

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

Let’s say your class is called CommandLine.class , and the code looks like this:

 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 

Then you should cd to the src folder and the command you need to run would look like this:

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

And the output on the command line would be:

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

In my case, I got the error because I had mixed UPPER- and lower-case package names on a Windows 7 system. Changing the package names to all lower case resolved the issue. Note also that in this scenario, I got no error compiling the .java file into a .class file; it just wouldn’t run from the same (sub-sub-sub-) directory.

I also faced similar errors while testing a Java MongoDB JDBC connection. I think it’s good to summarize my final solution in short so that in the future anybody can directly look into the two commands and are good to proceed further.

Assume you are in the directory where your Java file and external dependencies (JAR files) exist.

Compile:

 javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java 
  • -cp – classpath argument; pass all the dependent JAR files one by one
  • *.java – This is the Java class file which has main method. sdsd

Run:

 java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection 
  • Please do observe the colon (Unix) / comma (Windows) after all the dependency JAR files end
  • At the end, observe the main class name without any extension (no .class or .java)

In the context of IDE development (Eclipse, NetBeans or whatever) you have to configure your project properties to have a main class, so that your IDE knows where the main class is located to be executed when you hit “Play”.

  1. Right click your project, then Properties
  2. Go to the Run category and select your Main Class
  3. Hit the Run button.

Inserisci qui la descrizione dell'immagine