world - public static void main java




Que signifie "Impossible de trouver ou de charger la classe principale"? (20)

Un problème courant que les nouveaux développeurs Java rencontrent est que leurs programmes échouent à s'exécuter avec le message d'erreur: Could not find or load main class ...

Qu'est-ce que cela signifie, quelles en sont les causes, et comment le réparer?


La syntaxe de la commande java <class-name>

Tout d'abord, vous devez comprendre la manière correcte de lancer un programme en utilisant la commande java (ou javaw ).

La syntaxe normale 1 est la suivante:

    java [ <option> ... ] <class-name> [<argument> ...]

<option> est une option de ligne de commande (commençant par un caractère "-"), <class-name> est un nom de classe Java complet et <argument> est un argument de ligne de commande arbitraire qui est passé à votre application.
1 - Il y a une seconde syntaxe pour les fichiers JAR "exécutables" que je décrirai en bas.

Le nom complet (FQN) de la classe est écrit de manière conventionnelle comme dans le code source Java; par exemple

    packagename.packagename2.packagename3.ClassName

Cependant, certaines versions de la commande java vous permettent d'utiliser des barres obliques à la place des points; par exemple

    packagename/packagename2/packagename3/ClassName

ce qui (déroutant) ressemble à un chemin d'accès au fichier, mais n'en est pas un. Notez que le terme nom complet est la terminologie Java standard ... pas quelque chose que je viens de faire pour vous embrouiller :-)

Voici un exemple de ce à quoi devrait ressembler une commande java :

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

Ce qui précède va provoquer la commande java pour faire ce qui suit:

  1. Recherchez la version compilée de la classe com.acme.example.ListUsers .
  2. Charge la classe.
  3. Vérifiez que la classe a une méthode main avec signature , type de retour et modificateurs donnés par public static void main(String[]) . (Notez que le nom de l'argument de la méthode ne fait PAS partie de la signature.)
  4. Appelez cette méthode en lui passant les arguments de la ligne de commande ("fred", "joe", "bert") en tant que String[] .

Raisons pour lesquelles Java ne peut pas trouver la classe

Lorsque vous obtenez le message "Impossible de trouver ou de charger la classe principale ...", cela signifie que la première étape a échoué. La commande java n'a pas pu trouver la classe. Et en effet, le "..." dans le message sera le nom de classe pleinement qualifié que java recherche.

Alors pourquoi pourrait-il être incapable de trouver la classe?

Raison # 1 - vous avez fait une erreur avec l'argument classname

La première cause probable est que vous avez fourni le mauvais nom de classe. (Ou ... le bon nom de classe, mais sous la mauvaise forme.) Considérant l'exemple ci-dessus, voici une variété de fausses façons de spécifier le nom de la classe:

  • Exemple # 1 - un nom de classe simple:

    java ListUser
    

    Lorsque la classe est déclarée dans un package tel que com.acme.example , vous devez utiliser le nom de classe complet, y compris le nom du package dans la commande java ; par exemple

    java com.acme.example.ListUser
    
  • Exemple # 2 - un nom de fichier ou un chemin d'accès plutôt qu'un nom de classe:

    java ListUser.class
    java com/acme/example/ListUser.class
    
  • Exemple # 3 - un nom de classe avec le boîtier incorrect:

    java com.acme.example.listuser
    
  • Exemple # 4 - une faute de frappe

    java com.acme.example.mistuser
    
  • Exemple # 5 - un nom de fichier source

    java ListUser.java
    
  • Exemple # 6 - vous avez complètement oublié le nom de la classe

    java lots of arguments
    

Raison # 2 - le chemin de classe de l'application est incorrectement spécifié

La deuxième cause probable est que le nom de classe est correct, mais que la commande java ne peut pas trouver la classe. Pour comprendre cela, vous devez comprendre le concept du "classpath". Ceci est bien expliqué par la documentation Oracle:

Donc ... si vous avez correctement spécifié le nom de la classe, la prochaine chose à vérifier est que vous avez correctement spécifié le chemin de classe:

  1. Lisez les trois documents liés ci-dessus. (Oui ... LISEZ-LES Il est important qu'un programmeur Java comprenne au moins les bases du fonctionnement des mécanismes de classpath Java.)
  2. Regardez la ligne de commande et / ou la variable d'environnement CLASSPATH qui est en vigueur lorsque vous exécutez la commande java . Vérifiez que les noms de répertoire et les noms de fichier JAR sont corrects.
  3. S'il existe des noms de chemins relatifs dans le chemin de classe, vérifiez qu'ils se résolvent correctement ... à partir du répertoire actuel qui est en vigueur lorsque vous exécutez la commande java .
  4. Vérifiez que la classe (mentionnée dans le message d'erreur) peut se trouver sur le chemin de classe effectif .
  5. Notez que la syntaxe classpath est différente pour Windows par rapport à Linux et Mac OS.

Raison # 2a - le mauvais répertoire est sur le chemin de classe

Lorsque vous placez un répertoire sur le chemin de classe, il correspond théoriquement à la racine de l'espace de nom qualifié. Les classes se trouvent dans la structure de répertoires située sous cette racine, en mappant le nom complet à un nom de chemin . Donc, par exemple, si "/ usr / local / acme / classes" est sur le chemin de la classe, alors quand la JVM recherche une classe appelée com.acme.example.Foon , elle cherchera un fichier ".class" avec cette chemin d'accès:

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

Si vous aviez placé "/ usr / local / acme / classes / com / acme / exemple" sur le chemin de classe, la machine virtuelle Java ne serait pas en mesure de trouver la classe.

Raison # 2b - le chemin du sous-répertoire ne correspond pas au FQN

Si vos classes FQN est com.acme.example.Foon , alors la JVM va chercher "Foon.class" dans le répertoire "com / acme / example":

  • Si la structure de votre répertoire ne correspond pas à la dénomination du paquet selon le modèle ci-dessus, la JVM ne trouvera pas votre classe.

  • Si vous tentez de renommer une classe en la déplaçant, cela échouera également ... mais la pile d'exception sera différente.

Pour donner un exemple concret, supposons que:

  • vous voulez exécuter la classe com.acme.example.Foon ,
  • le chemin complet du fichier est /usr/local/acme/classes/com/acme/example/Foon.class ,
  • votre répertoire de travail actuel est /usr/local/acme/classes/com/acme/example/ ,

puis:

# 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

Remarques:

  • L'option -classpath peut être raccourcie à -cp dans la plupart des versions Java. Vérifiez les entrées manuelles respectives pour java , javac et ainsi de suite.
  • Réfléchissez bien lorsque vous choisissez entre les chemins d'accès absolus et relatifs dans les classpaths. Rappelez-vous qu'un chemin relatif peut "casser" si le répertoire courant change.

Raison n ° 2c - dépendances manquantes dans le chemin de classe

Le classpath doit inclure toutes les autres classes (non système) dont dépend votre application. (Les classes système sont localisées automatiquement et vous avez rarement besoin de vous préoccuper de cela.) Pour que la classe principale se charge correctement, la machine virtuelle Java doit trouver:

(Remarque: les spécifications JLS et JVM permettent à une machine JVM de charger des classes "paresseusement", ce qui peut affecter le lancement d'une exception classloader.)

Raison # 3 - la classe a été déclarée dans le mauvais paquet

Il arrive parfois que quelqu'un place un fichier de code source dans le mauvais dossier de son arbre de code source, ou qu'il omette la déclaration du package . Si vous faites cela dans un IDE, le compilateur de l'IDE vous en parlera immédiatement. De même, si vous utilisez un outil de construction Java décent, l'outil lancera javac de manière à détecter le problème. Cependant, si vous construisez votre code Java à la main, vous pouvez le faire de telle sorte que le compilateur ne remarque pas le problème, et le fichier ".class" qui en résulte ne se trouve pas à l'endroit que vous attendez.

La syntaxe java -jar <jar file>

La syntaxe alternative utilisée pour les fichiers JAR "exécutables" est la suivante:

  java [ <option> ... ] -jar <jar-file-name> [<argument> ...]

par exemple

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

Dans ce cas, le nom de la classe de point d'entrée (ie com.acme.example.ListUser ) et le com.acme.example.ListUser classe sont spécifiés dans le MANIFEST du fichier JAR.

IDE

Un IDE Java typique prend en charge l'exécution d'applications Java dans la JVM IDE elle-même ou dans une JVM enfant. Ceux-ci sont généralement à l' abri de cette exception particulière, car l'EDI utilise ses propres mécanismes pour construire le chemin de classe runtime, identifier la classe principale et créer la ligne de commande java .

Cependant, il est toujours possible que cette exception se produise si vous faites des choses derrière l'EDI. Par exemple, si vous avez déjà configuré un programme de lancement d'applicatifs pour votre application Java dans Eclipse et que vous avez ensuite déplacé le fichier JAR contenant la classe "main" vers un emplacement différent du système de fichiers sans le signaler à Eclipse , Eclipse lancerait involontairement la machine virtuelle Java. avec un chemin de classe incorrect.

En résumé, si vous rencontrez ce problème dans un EDI, recherchez des éléments tels que l'état IDE périmé, des références de projet brisées ou des configurations de lanceur brisées.

Il est également possible qu'un EDI soit simplement confus. Les IDE sont des logiciels extrêmement complexes comprenant de nombreuses parties en interaction. Beaucoup de ces parties adoptent différentes stratégies de mise en cache afin de rendre l'EDI globalement réactif. Ceux-ci peuvent parfois aller mal, et un symptôme possible est des problèmes lors du lancement des applications. Si vous pensez que cela pourrait se produire, il vaut la peine de redémarrer votre IDE.

Autres références


C'est un cas particulier, mais comme je suis venu sur cette page à la recherche d'une solution et que je ne l'ai pas trouvée, je l'ajouterai ici.

Windows (testé avec 7) n'accepte pas les caractères spéciaux (comme á ) dans les noms de classe et de paquet. Linux le fait, cependant.

J'ai découvert ceci quand j'ai construit un .jar dans NetBeans et ai essayé de l'exécuter en ligne de commande. Il a fonctionné dans NetBeans mais pas dans la ligne de commande.


Ce qui m'a aidé était de spécifier le classpath sur la ligne de commande, par exemple:

  1. Créez un nouveau dossier, C:\temp

  2. Créez le fichier Temp.java dans C:\temp , avec la classe suivante:

    public class Temp {
        public static void main(String args[]) {
            System.out.println(args[0]);
        }
    }
    
  3. Ouvrez une ligne de commande dans le dossier C:\temp et écrivez la commande suivante pour compiler la classe Temp:

    javac Temp.java
    
  4. Exécutez la classe Java compilée en ajoutant l'option -classpath pour -classpath à JRE où trouver la classe:

    java -classpath C:\temp Temp Hello!
    

Cela pourrait vous aider si votre cas est spécifiquement comme le mien: en tant que débutant, j'ai également rencontré ce problème lorsque j'ai essayé d'exécuter un programme Java.

Je l'ai compilé comme ceci:

javac HelloWorld.java

Et j'ai essayé de courir aussi avec la même extension:

java Helloworld.java

Quand j'ai enlevé le .java et réécrit la commande comme java HelloWorld , le programme a fonctionné parfaitement. :)


Dans ce cas, vous avez:

Impossible de trouver ou de charger la classe principale ?

C'est parce que vous utilisez "-classpath", mais le tiret n'est pas le même tiret utilisé par java sur l'invite de commande. J'ai eu ce problème copier et coller du Notepad à cmd.


Dans mon cas, une erreur est apparue parce que j'avais fourni le nom du fichier source au lieu du nom de la classe.

Nous devons fournir le nom de classe contenant la méthode principale à l'interpréteur.


J'ai eu une telle erreur dans ce cas:

java -cp lib.jar com.mypackage.Main

Cela fonctionne avec ; pour Windows et : pour Unix:

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

J'ai passé un temps décent à essayer de résoudre ce problème. Je pensais que j'établissais d'une manière ou d'une autre mon chemin de classe incorrectement mais le problème était que j'ai tapé:

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

au lieu de:

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

Je pensais que la signification de complètement qualifié signifiait inclure le nom de chemin complet au lieu du nom de paquet complet.


Quand le même code fonctionne sur un PC, mais il montre l'erreur dans un autre, la meilleure solution que j'ai jamais trouvée compile comme suit:

javac HelloWorld.java
java -cp . HelloWorld

Selon le message d'erreur ("Impossible de trouver ou charger la classe principale"), il existe deux catégories de problèmes:

  1. La classe principale n'a pas pu être trouvée
  2. La classe principale n'a pas pu être chargée (ce cas n'est pas complètement discuté dans la réponse acceptée)

La classe principale n'a pas pu être trouvée lorsqu'il y a une faute de frappe ou une syntaxe incorrecte dans le nom de la classe entièrement qualifiée ou qu'elle n'existe pas dans le chemin de classe fourni .

La classe principale n'a pas pu être chargée lorsque la classe ne peut pas être initiée , généralement la classe principale étend une autre classe et cette classe n'existe pas dans le chemin de classe fourni.

Par exemple:

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

Si le ressort camel n'est pas inclus, cette erreur sera signalée.


Si votre méthode principale est dans la classe sous un package, vous devez l'exécuter sur le répertoire hiérarchique.

Supposons qu'il existe un fichier de code source (Main.java):

package com.test;

public class Main {

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

Pour exécuter ce code, vous devez placer Main.Class dans le package comme le répertoire ./com/test/Main.Java . Et dans le répertoire racine, utilisez java com.test.Main .


Si votre nom de code source est HelloWorld.java, votre code compilé sera HelloWorld.class .

Vous obtiendrez cette erreur si vous l'appelez en utilisant:

java HelloWorld.class

Au lieu de cela, utilisez ceci:

java HelloWorld

Sur Windows mettre .; à la valeur CLASSPATH au début.

Le . (point) signifie "regarde dans le répertoire courant". C'est une solution permanente.

Aussi, vous pouvez le définir "une fois" avec set CLASSPATH=%CLASSPATH%;. . Cela durera aussi longtemps que votre fenêtre cmd est ouverte.


Utilisez cette commande:

java -cp . [PACKAGE.]CLASSNAME

Exemple: Si votre nom de classe est Hello.class créé à partir de Hello.java, utilisez la commande ci-dessous:

java -cp . Hello

Si votre fichier Hello.java est dans le paquet com.demo, utilisez la commande ci-dessous

java -cp . com.demo.Hello

Avec JDK 8, il arrive souvent que le fichier de classe soit présent dans le même dossier, mais la commande java attend le classpath et pour cette raison nous ajoutons -cp . prendre le dossier actuel comme référence pour classpath.


All answers here are directed towards Windows users it seems. For Mac, the classpath separator is : , not ; . As an error setting the classpath using ; is not thrown then this can be a difficult to discover if coming from Windows to Mac.

Here is corresponding Mac command:

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

Where in this example the package is com.test and a lib folder is also to be included on classpath.


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

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

à

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

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/


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.


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] .


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.







main