Que signifie "Ne Pouvait pas trouver ou charger la classe principale"?
un problème commun que les nouveaux développeurs Java éprouvent est que leurs programmes ne parviennent pas à exécuter avec le message d'erreur: Could not find or load main class ...
Qu'est-ce que cela signifie, qu'est-ce qui le provoque, et comment devriez-vous le réparer?
30 réponses
Le java <class-name>
syntaxe de la commande
tout d'abord, vous devez comprendre la bonne façon de lancer un programme en utilisant la commande java
(ou javaw
).
la syntaxe normale 1 est la suivante:
java [ <option> ... ] <class-name> [ <argument> ... ]
où <option>
est une option de ligne de commande (commençant par un "-" caractère), <class-name>
est un nom de classe Java pleinement qualifié, 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 conventionnellement comme vous le feriez dans le code source Java; par exemple
packagename.packagename2.packagename3.ClassName
notez que le terme nom pleinement qualifié est la terminologie Java standard. ... pas quelque chose que j'ai juste inventé pour vous confondre: -)
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 amener la commande java
à faire ce qui suit:
- recherchez la version compilée de la classe
com.acme.example.ListUsers
. - charger la classe.
- vérifier que la classe a une méthode
main
avec signature , type de retour et modificateurs donnée parpublic static void main(String[])
. (Note, le nom de l'argument de méthode est et non partie de la signature.) - appelle cette méthode en lui passant les arguments de ligne de commande ("fred"," joe"," bert") comme un
String[]
.
raisons pour lesquelles Java ne peut pas trouver la classe
quand vous obtenez le message "impossible de trouver ou charger la classe principale ...", cela signifie que la première étape n'a pas. 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
cherche.
alors pourquoi ne pourrait-il pas trouver la classe?
raison # 1 - vous avez fait une erreur avec l'argument classname
le la première cause probable est que vous avez peut-être donné le mauvais nom de classe. (Ou. .. le bon nom de classe, mais dans la mauvaise forme.) Compte tenu de l'exemple ci-dessus, voici une variété de wrong ways pour spécifier le nom de classe:
-
exemple #1 - un nom de classe simple:
java ListUser
lorsque la classe est déclarée dans un paquet tel que
com.acme.example
, alors vous devez utiliser le nom complet de la classe y compris le nom du colis dans la commandejava
; p.ex.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 - la voie de classe de la demande est incorrectement spécifiée
la deuxième cause probable est que le nom de la classe est correct, mais que la commande java
ne peut pas trouver la classe. Pour comprendre cela, vous devez comprendre le concept de "classpath". Ceci est expliqué bien par la documentation Oracle:
- Le "1519150920 de la commande" documentation
- réglage du chemin de classe .
- le tutoriel Java - chemin et classe
So ... si vous avez spécifié le nom de la classe correctement, la prochaine chose à vérifier est que vous avez spécifié le chemin de classe correctement:
- lire les trois documents liés ci-dessus. (Oui. .. Les LIRE. Il est important qu'un programmeur Java comprenne au moins les bases du fonctionnement des mécanismes Java classpath.)
- 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 des fichiers JAR sont corrects. - s'il y a des noms de chemins relatifs dans classpath, Vérifiez qu'ils se résolvent correctement ... à partir du répertoire courant qui est en vigueur lorsque vous lancez la commande
java
. - vérifier que la classe (mentionnée dans le message d'erreur) peut être située sur le chemin de classe en vigueur .
- notez que la syntaxe classpath est différent Pour Windows versus Linux et Mac OS. (Le séparateur classpath est
;
sur Windows et:
sur les autres.)
raison # 2a - le mauvais répertoire est sur le chemin de classe
lorsque vous mettez un répertoire sur classpath, il correspond théoriquement à la racine de l'espace de nom qualifié. Les Classes sont localisées dans la structure de répertoire sous cette racine, en cartographiant les nom d'un chemin d'accès . Ainsi, par exemple, si "/usr/local/acme/classes" est sur le chemin de la classe , alors lorsque la JVM recherche une classe appelée com.acme.example.Foon
, elle recherchera un ".classe "fichier avec ce chemin d'accès:
/usr/local/acme/classes/com/acme/example/Foon.class
si vous aviez mis" /usr/local/acme/classes/com/acme/example " sur le chemin de la classe, alors la JVM ne serait pas en mesure de trouver la classe.
raison # 2b - le chemin du sous-répertoire ne correspond pas au FQN
Si votre classe FQN est com.acme.example.Foon
, alors la JVM va chercher " Foon.la classe" dans le répertoire "com/acme/exemple":
-
si la structure de votre répertoire ne correspond pas au nom 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 aussi ... mais l'exception stactrace sera différent.
pour donner un exemple concret, supposons que:
- vous voulez exécuter
com.acme.example.Foon
catégorie", - 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
Notes:
- le L'option
-classpath
peut être raccourcie à-cp
dans la plupart des versions Java. Vérifiez les entrées manuelles respectives pourjava
,javac
et ainsi de suite. - réfléchissez bien lors du choix entre les noms de chemins absolus et relatifs dans classpaths. Rappelez-vous qu'un chemin relatif peut "casser" si le répertoire courant change.
raison #2C-dépendances manquantes dans le chemin de classe
le chemin de classe doit inclure toutes les classes autres (non-système) dont dépend votre application. (Les classes système sont localisées automatiquement, et vous avez rarement besoin de vous en préoccuper.) Pour que la classe principale se charge correctement, la JVM doit trouver:
- la classe elle-même.
- toutes les classes et interfaces dans la hiérarchie des superclasses (voir par exemple cette question )
- toutes les classes et interfaces auxquelles il est fait référence au moyen de déclarations variables ou variables, ou d'expressions d'appel de méthode ou d'accès aux champs.
(Note: les spécifications JLS et JVM laissent une certaine marge de manœuvre à une JVM pour charger les classes "paresseusement", et cela peut avoir un effet lorsqu'une exception classloader est lancée.)
Raison #3 - la classe a été déclarée dans le mauvais paquet
Il arrive parfois que quelqu'un met un fichier de code source dans le
le mauvais dossier dans leur arborescence de code source, ou ils laissent de côté la déclaration package
. Si vous faites cela dans un IDE, le compilateur de L'IDE vous le dira immédiatement. De même, si vous utilisez un outil de construction Java décent, l'outil exécutera javac
d'une manière qui détectera 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 résultat ".la classe" fichier n'est pas dans le lieu que vous l'attendez.
vous ne trouvez toujours pas le problème?
Il ya beaucoup de choses à vérifier, et il est facile de manquer quelque chose. Essayez d'ajouter l'option -Xdiag
à la ligne de commande java
(comme première chose après java
). Il va sortir diverses choses au sujet du chargement de classe, et cela peut vous offrir des indices sur ce que le vrai problème est.
aussi, examiner les problèmes possibles causés par copier et coller des caractères invisibles ou non-ASCII à partir de sites Web, documents et ainsi de suite. Et considérer "homoglyphs", étaient deux lettres ou Symboles regarder la même chose ... mais ils ne le sont pas.
Le java -jar <jar file>
syntaxe
la syntaxe alternative utilisée pour les fichiers JAR" exécutables "est la suivante:
java [ <option> ... ] -jar <jar-file-name> [<argument> ...]
p.ex.
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
dans ce cas, le nom du point d'entrée la classe (i.e. com.acme.example.ListUser
) et le chemin de classe sont spécifiés dans le Manifeste du fichier JAR.
IDEs
un IDE Java typique prend en charge L'exécution d'applications Java dans L'IDE JVM elle-même ou dans une JVM enfant. Ceux-ci sont généralement à l'abri de cette exception particulière, parce que L'IDE utilise ses propres mécanismes pour construire la classe runtime classpath, identifier la classe principale et créer les java
ligne de commande.
cependant, il est encore possible pour cette exception de se produire, si vous faites des choses derrière le dos de L'IDE. Par exemple, si vous avez déjà configuré un lanceur D'Application pour votre application Java dans Eclipse , et que vous avez ensuite déplacé le fichier JAR contenant la classe "main" à un endroit différent dans le système de fichiers sans dire à Eclipse , Eclipse lancerait involontairement la JVM avec un chemin de classe incorrect.
en bref, si vous obtenez ce problème dans un IDE, Vérifiez des choses comme l'état d'IDE périmé, des références de projet brisées ou des configurations de lanceur brisées.
il est également possible pour un IDE de se confondre tout simplement. Les IDE sont des logiciels extrêmement complexes comprenant de nombreuses parties en interaction. Bon nombre de ces parties adoptent diverses stratégies de mise en cache afin de rendre l'IDE globalement réactif. Cela peut parfois mal tourner, et un symptôme possible est les problèmes lors du lancement des applications. Si vous pensez que cela pourrait se produire, cela vaut la peine de redémarrer votre IDE.
Autres Références
- à Partir de l'Oracle Java Tutoriels - Problèmes Communs (et Leurs Solutions)
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
à la place, Utilisez ceci:
java HelloWorld
si vos classes sont dans des paquets, alors vous devez cd
dans le répertoire principal et exécuter en utilisant le nom complet de la classe (nom du paquet.MainClassName).
exemple:
mes cours sont ici:
D:\project\com\cse\
Le nom complet de ma classe principale est:
com.cse.Main
So I cd
retour au répertoire principal:
D:\project
puis émettre le java
commande:
java com.cse.Main
Si votre méthode principale est dans la classe sous un paquet, 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 répertoire package like ./com/test/Main.Java
. Et dans le répertoire racine utiliser java com.test.Main
.
quand le même code fonctionne sur un PC, mais qu'il montre l'erreur dans un autre, la meilleure solution que j'ai jamais trouvée est de compiler comme suit:
javac HelloWorld.java
java -cp . HelloWorld
ce qui m'a aidé était de spécifier le chemin de classe sur la ligne de commande, par exemple:
-
créer un nouveau dossier,
C:\temp
-
Créer fichier Temp.java dans
C:\temp
, avec la classe suivante:public class Temp { public static void main(String args[]) { System.out.println(args[0]); } }
-
ouvrez une ligne de commande dans le dossier
C:\temp
, et écrivez la commande suivante pour compiler la classe Temp:javac Temp.java
-
lancez la classe Java compilée, en ajoutant l'option
-classpath
pour indiquer à JRE où trouver la classe:java -classpath C:\temp Temp Hello!
, Selon le message d'erreur ("impossible de trouver ou charger la classe principale"), il y a deux catégories de problèmes:
- la classe principale ne pouvait pas être trouvé
- classe Principale ne peut pas être chargé (ce cas n'est pas abordée dans l'acceptation de réponse)
la classe principale ne peut pas être trouvé quand il y a faute de frappe la syntaxe dans le nom de classe entièrement qualifié ou n'existe pas dans le classpath .
classe principale ne peut pas être chargé lorsque la classe ne peut pas être initialisée , typiquement la classe principale étend une autre classe et cette classe n'existe pas dans la classe prévue.
par exemple:
public class YourMain extends org.apache.camel.spring.Main
si camel-spring n'est pas inclus, ce l'erreur sera signalée.
parfois, ce qui pourrait causer le problème n'a rien à voir avec la classe principale, et je devais le découvrir à la dure. C'était une bibliothèque référencée que j'ai déplacée, et elle m'a donné le:
ne pouvait pas trouver ou charger la classe principale xxx Linux
je viens de supprimer cette référence, je l'ai rajoutée, et ça a encore bien marché.
j'ai eu une erreur dans ce cas:
java -cp lib.jar com.mypackage.Main
il fonctionne avec ;
Pour Windows et :
pour Unix:
java -cp lib.jar; com.mypackage.Main
utilisez cette commande:
java -cp . [PACKAGE.]CLASSNAME
exemple: si votre nom de classe est Hello.classe créée à partir de Bonjour.java alors utilisez la commande suivante:
java -cp . Hello
si votre dossier Bonjour.java est dans le paquet com.Démo ensuite utiliser 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 classpath et pour cette raison nous ajoutons -cp .
prendre le dossier courant comme référence pour classpath.
Essayer -Xdiag .
la réponse de Steve C couvre bien les cas possibles, mais parfois pour déterminer si la classe ne pouvait pas être trouvé ou chargé pourrait ne pas être si facile. Utilisez java -Xdiag
(depuis JDK 7). Ceci imprime un joli stactrace qui fournit une indication de ce que le message Could not find or load main class
signifie.
Par exemple, il peut pointez-vous vers d'autres classes utilisées par la classe principale qui n'ont pas pu être trouvées et ont empêché la classe principale d'être chargée.
dans ce cas vous avez:
impossible de trouver ou charger la classe principale ?classepath
c'est parce que vous utilisez"- classpath", mais le tiret n'est pas le même que celui utilisé par java
sur l'invite de commande. J'ai eu ce numéro copiant et collant de Bloc-notes à 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ète.
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 supprimé le .java
et réécrit la commande comme java HelloWorld
, le programme a fonctionné parfaitement. :)
Class emplacement du fichier: C:\test\com\company
Nom De Fichier: Main.classe
nom de classe complet: com.entreprise.Main
commande en ligne:
java -classpath "C:\test" com.company.Main
noter ici que le chemin de classe n'inclut pas \com\company
si vous utilisez Maven pour construire le fichier JAR, s'il vous plaît assurez-vous de spécifier la classe principale dans le pom.fichier xml:
<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>
j'ai passé beaucoup de temps à essayer de résoudre ce problème. Je pensais que j'étais en quelque sorte réglage de mon classpath incorrect, 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 "pleinement qualifié" signifiait inclure le nom complet du sillon au lieu du nom complet du paquet.
définissez D'abord le chemin en utilisant cette commande;
set path="paste the set path address"
ensuite, vous devez charger le programme. Tapez "cd (nom de dossier)" dans le lecteur stocké et compilez-le. Par exemple, si mon programme est stocké sur le lecteur D, tapez "D:" appuyez sur Entrée et tapez " cd (nom du dossier)".
ce qui a résolu le problème dans mon cas était:
faites un clic droit sur le projet/classe que vous voulez lancer, puis Run As
- > Run Configurations
. Vous devez alors soit corriger votre configuration existante, soit en ajouter une nouvelle de la manière suivante:
ouvrez l'onglet Classpath
, cliquez sur le bouton Advanced...
puis ajoutez bin
dossier de votre projet.
C'est un cas particulier, mais puisque je suis venu à cette page à la recherche d'une solution et que je ne l'ai pas trouvé, je vais l'ajouter ici.
Windows (testé avec 7 ) n'accepte pas les caractères spéciaux (comme á
) dans les noms de classe et de paquet. Linux n'a, cependant.
je l'ai trouvé quand j'ai construit un .jar
dans NetBeans et essayé de l'exécuter en ligne de commande. Il a fonctionné dans NetBeans, mais pas en ligne de commande.
toutes les réponses ici sont dirigées vers les utilisateurs de Windows il semble. Pour Mac , le séparateur classpath est :
et non ;
. Comme une erreur de paramétrage de classpath à l'aide de ;
n'est pas lancée, cela peut être difficile à découvrir si vous venez de Windows Pour Mac.
Voici la commande Mac correspondante:
java -classpath ".:./lib/*" com.test.MyClass
où dans cet exemple le paquet est com.test
et un dossier lib
doit également être inclus classpath.
lors de l'exécution du java
avec l'option -cp
comme annoncé dans Windows PowerShell vous pouvez obtenir une erreur qui ressemble à quelque chose comme:
The term `ClassName` is not recognized as the name of a cmdlet, function, script ...
pour que PowerShell accepte la commande, les arguments de l'option -cp
doivent être contenus entre guillemets comme dans:
java -cp 'someDependency.jar;.' ClassName
la formation de la commande de cette façon devrait permettre au processus Java de traiter correctement les arguments classpath.
Parfois, dans certains compilateurs en ligne que vous pourriez avoir essayé, vous obtiendrez cette erreur si vous n'écrivez pas public class [Classname]
mais juste class [Classname]
.
D'accord, beaucoup de réponses déjà, mais personne n'a mentionné le cas où la permission de fichier peut être le coupable. Lors de l'exécution, user n'a pas accès au fichier jar ou à l'un des répertoires du chemin. Par exemple considérer:
fichier Jar dans /dir1/dir2/dir3/myjar.jar
User1 whow possède le pot peut faire:
# Running as User1
cd /dir1/dir2/dir3/
chmod +r myjar.jar
mais ça ne marche toujours pas:
# Running as User2
java -cp "/dir1/dir2/dir3:/dir1/dir2/javalibs" MyProgram
Error: Could not find or load main class MyProgram
c'est parce que l'utilisateur courant (User2) n'a pas accès à dir1, dir2, ou javalibs ou dir3. Cela peut rendre quelqu'un fou quand User1 peut voir les fichiers, et peut y accéder, mais l'erreur se produit toujours pour User2
sur Windows, mettez .;
à la valeur CLASSPATH au début.
The . (dot) signifie "regarder dans le répertoire courant". C'est une solution permanente.
vous pouvez aussi le définir" une fois "avec CLASSPATH=%CLASSPATH%;.
. Cela durera aussi longtemps que votre fenêtre cmd est ouvert.
vous avez vraiment besoin de faire cela à partir du dossier src
. Il vous tapez la ligne de commande suivante:
[name of the package].[Class Name] [arguments]
disons que votre classe s'appelle CommandLine.class
, et le code ressemble à ceci:
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]);
}
}
}
alors vous devriez cd
dans le dossier src et la commande que vous devez exécuter ressemblerait à ceci:
java com.tutorialspoint.java.CommandLine this is a command line 200 -100
Et la sortie sur la ligne de commande serait:
args[0]: this
args[1]: is
args[2]: a
args[3]: command
args[4]: line
args[5]: 200
args[6]: -100
dans mon cas, j'ai eu l'erreur parce que j'avais mélangé des noms de paquets minuscules et supérieurs sur un système Windows 7. Le fait de changer le nom du paquet en minuscules a résolu le problème. Notez aussi que dans ce scénario, je n'ai aucune erreur en compilant le .java fichier dans un .fichier de classe; il n'aurait tout simplement pas la même (sous-sous-sous-sous-répertoire.
j'ai également fait face à des erreurs similaires en testant une connexion JDBC Java MongoDB. Je pense qu'il est bon de résumer brièvement ma solution finale pour qu'à l'avenir n'importe qui puisse directement regarder dans les deux commandes et soit bon de continuer plus loin.
suppose que vous êtes dans le répertoire où votre fichier Java et les dépendances externes (fichiers JAR) existent.
compiler:
javac -cp mongo-java-driver-3.4.1.jar JavaMongoDBConnection.java
- - CP - argument classpath; passer tous les fichiers JAR dépendants un par un
- *.java - c'est le fichier de classe Java qui a la méthode principale. sdsd
Run:
java -cp mongo-java-driver-3.4.1.jar: JavaMongoDBConnection
- s'il vous Plaît respecter le côlon (Unix) / par des virgules (Windows) après que toutes les dépendances de fichiers JAR fin
- à la fin, observer le nom de la classe principale sans aucune extension (aucun. de la classe ou de .java)
j'en ai eu un bizarre.
Erreur: impossible de trouver ou de charger mypackage de classe principale.App
il s'est avéré que j'avais un pom (parent) installé dans le pom de mon projet.xml (mon pom du projet.xml pointait vers un parent pom.xml) et le chemin relatif était éteint/erroné.
ci-dessous est une partie du pom de mon projet.xml
<parent>
<groupId>myGroupId</groupId>
<artifactId>pom-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../badPathHere/pom.xml</relativePath>
</parent>
une fois que j'ai résolu le pom relativePath, l'erreur a disparu.
Aller à la figure.
en Java, lorsque vous lancez parfois JVM à partir de la ligne de commande en utilisant l'exécutable java et que vous essayez de démarrer un programme à partir d'un fichier de classe avec public static void main (PSVM), vous risquez de rencontrer l'erreur ci-dessous même si le paramètre classpath de la JVM est exact et que le fichier de classe est présent sur classpath:
Error: main class not found or loaded
cela se produit si le fichier de classe avec PSVM ne peut pas être chargé. Une raison possible à cela est que la classe peut-être implémenter une interface ou étendre une autre classe qui n'est pas sur classpath. Normalement, si une classe n'est pas sur le chemin de classe, l'erreur lancée l'indique comme telle. Mais, si la classe utilisée est étendue ou implémentée, java est incapable de charger la classe elle-même.
référence: https://www.computingnotes.net/java/error-main-class-not-found-or-loaded /