Détails
Que signifie "Impossible de trouver ou de charger la classe principale" ?
Les nouveaux développeurs Java rencontrent souvent le problème suivant : leurs programmes ne s'exécutent pas et le message d'erreur suivant apparaît : Impossible de trouver ou de charger la classe principale ...
.
Que signifie ce message, quelle en est la cause et comment le résoudre ?
1270
3
La syntaxe de la commande "java `".
Tout d'abord, vous devez comprendre la manière correcte de lancer un programme en utilisant la commande
java
(oujavaw
). La syntaxe normale1 est la suivante :où
est une option de ligne de commande (commençant par un caractère "-" ;),
est un nom de classe Java entièrement qualifié, et `` est un argument de ligne de commande arbitraire qui est passé à votre application.1 - Il existe une deuxième syntaxe pour les fichiers JAR "executable"que je décrirai en bas de page. Le nom pleinement qualifié (FQN) de la classe s'écrit conventionnellement comme vous le feriez dans le code source Java ; par ex.
Cependant, certaines versions de la commande
java
vous permettent d'utiliser des barres obliques à la place des points ; par ex.qui ressemble (confusément) à un nom de fichier, mais n'en est pas un. Notez que le terme nom entièrement qualifié est une terminologie Java standard... et non quelque chose que j'ai inventé pour vous embrouiller :-) Voici un exemple de ce à quoi devrait ressembler une commande
java
:La commande
java
va faire ce qui suit :com.acme.example.ListUsers
.main
avec signature, type de retour et modificateurs donnés parpublic static void main(String[])
. (Remarque : le nom de l'argument de la méthode ne fait PAS partie de la signature).Appelez cette méthode en lui passant les arguments de la ligne de commande ("fred" ;, "joe" ;, "bert" ;) sous forme de
String[]
. Raisons pour lesquelles Java ne peut pas trouver la classeLorsque vous obtenez le message "Could not find or load main class ..." ;, 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 entièrement qualifié quejava
recherche. Alors pourquoi la commande n'est-elle pas en mesure de trouver la classe ?Raison #1 - vous avez fait une erreur avec l'argument classname
La première cause probable est que vous avez peut-être fourni le mauvais nom de classe. (Ou ... le bon nom de classe, mais sous la mauvaise forme.) En considérant l'exemple ci-dessus, voici une variété de mauvaises façons de spécifier le nom de classe :
Exemple #1 - un nom de classe simple :
Lorsque la classe est déclarée dans un paquetage tel que
com.acme.example
, alors vous devez utiliser le nom complet de la classe y compris le nom du paquetage dans la commandejava
; par ex. java com.acme.example.ListUserExemple n°2 - un nom de fichier ou un chemin d'accès plutôt qu'un nom de classe : java ListUser.class java com/acme/exemple/ListUser.class
Exemple n° 3 - un nom de classe dont la casse est incorrecte : java com.acme.example.listuser
Exemple n°4 - une faute de frappe java com.acme.example.mistuser
Exemple #5 - un nom de fichier source java ListUser.java
Exemple #6 - vous avez entièrement oublié le nom de la classe java beaucoup d'arguments Raison #2 - le classpath de l’application est mal spécifié
La deuxième cause probable est que le nom de la classe est correct, mais que la commande
java
ne trouve pas la classe. Pour comprendre cela, vous devez comprendre le concept de "classpath" ;. Ce concept est expliqué bien par la documentation Oracle :[Documentation de la commande
java
][1][Définition du chemin de classe][2].
Le tutoriel Java - [PATH et CLASSPATH][3]. Donc ... si vous avez spécifié le nom de la classe correctement, la prochaine chose à vérifier est que vous avez spécifié le classpath correctement :
java
. Vérifiez que les noms des répertoires et des fichiers JAR sont corrects.java
.Notez que la syntaxe du classpath est différente pour Windows par rapport à Linux et Mac OS. (Le séparateur de classpath est
;
sur Windows et:
sur les autres. Si vous utilisez le mauvais séparateur pour votre plate-forme, vous n'obtiendrez pas de message d'erreur explicite. Au lieu de cela, vous obtiendrez un fichier ou un répertoire inexistant sur le chemin qui sera silencieusement ignoré). Raison #2a - le mauvais répertoire est sur le classpathLorsque vous placez un répertoire sur le classpath, il correspond théoriquement à la racine de l'espace de nom qualifié. Les classes sont localisées dans la structure de répertoires sous cette racine, en faisant correspondre le nom pleinement qualifié à un nom de chemin. Ainsi, par exemple, si "/usr/local/acme/classes" ; est sur le chemin des classes, alors quand la JVM cherche une classe appelée
com.acme.example.Foon
, elle cherchera un fichier " ;.class" ; avec ce nom de chemin :Si vous aviez mis "/usr/local/acme/classes/com/acme/example" ; dans le classpath, alors la JVM ne pourrait pas trouver la classe. Raison #2b - le chemin du sous-répertoire ne correspond pas au FQN
Si le FQN de vos classes est
com.acme.example.Foon
, alors la JVM va chercher "Foon.class" ; dans le répertoire "com/acme/example" :com.acme.example.Foon
,/usr/local/acme/classes/com/acme/exemple/Foon.class
,/usr/local/acme/classes/com/acme/exemple/
, alors :Notes :
L'option
-classpath
peut être raccourcie en-cp
dans la plupart des versions de Java. Vérifiez les entrées de manuel respectives pourjava
,javac
et ainsi de suite.Réfléchissez bien lorsque vous choisissez entre les noms de chemin absolus et relatifs dans les classpaths. Rappelez-vous qu'un nom de chemin relatif peut se briser si le répertoire courant change.
Raison #2c - dépendances manquantes dans le classpath
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 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 https://stackoverflow.com/questions/42880748)
toutes les classes et interfaces auxquelles il est fait référence au moyen de déclarations de variables ou d'expressions d'appels de méthodes ou d'accès aux champs. (Remarque : les spécifications JLS et JVM laissent une certaine marge de manœuvre à une JVM pour charger des classes de manière "paresseuse", ce qui peut avoir une incidence sur le moment où une exception de classloader est levée). Raison #3 - la classe a été déclarée dans le mauvais paquetage
Il arrive parfois que quelqu'un place un fichier de code source dans le mauvais dossier dans son arborescence de code source, ou qu'il oublie la déclaration
package
. Si vous faites cela dans un IDE, le compilateur de l'IDE vous le signalera immédiatement. De même, si vous utilisez un outil de construction Java décent, l'outil exécuterajavac
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 que le fichier " ;.class" ; résultant ne soit pas à l'endroit où vous l'attendez. Vous ne trouvez toujours pas le problème ?Il y a beaucoup de choses à vérifier, et il est facile de manquer quelque chose. Essayez d'ajouter l'option
-Xdiag
à la ligne de commandejava
(comme première chose aprèsjava
). Elle affichera diverses informations sur le chargement des classes, et cela peut vous donner des indices sur la nature du problème. Pensez également aux problèmes éventuels causés par le copier-coller de caractères invisibles ou non ASCII à partir de sites Web, de documents, etc. Et n'oubliez pas les "homoglyphes", lorsque deux lettres ou symboles se ressemblent... mais ne se ressemblent pas.La syntaxe "java -jar `".
La syntaxe alternative utilisée pour les fichiers JAR "exécutables" est la suivante :
par exemple
Dans ce cas, le nom de la classe du point d'entrée (c'est-à-dire
com.acme.example.ListUser
) et le classpath sont spécifiés dans le MANIFEST du fichier JAR.IDEs
Un IDE Java classique prend en charge l'exécution d'applications Java dans la JVM de l'IDE elle-même ou dans une JVM enfant. Ces dernières sont généralement à l'abri de cette exception particulière, car l'EDI utilise ses propres mécanismes pour construire le classpath d'exécution, 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'IDE. Par exemple, si vous avez précédemment 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" ; vers un autre endroit du système de fichiers sans le dire à Eclipse, Eclipse lancera involontairement la JVM avec un classpath incorrect. En bref, si vous rencontrez ce problème dans un IDE, vérifiez des éléments tels qu'un état d'IDE périmé, des références de projet cassées ou des configurations de lanceur cassées. Il est également possible que l'environnement de développement intégré s'embrouille tout simplement. Les IDE sont des logiciels extrêmement compliqués comprenant de nombreuses parties en interaction. Beaucoup de ces parties adoptent diverses stratégies de mise en cache afin de rendre l'IDE dans son ensemble réactif. Ces stratégies peuvent parfois mal fonctionner, et l'un des symptômes possibles est un problème lors du lancement des applications. Si vous pensez que cela peut se produire, il vaut la peine d'essayer des choses comme redémarrer votre IDE et reconstruire le projet.Autres références
Parfois, ce qui peut causer le problème n'a rien à voir avec la classe principale, et j'ai dû le découvrir à la dure. C'était une bibliothèque référencée que j'ai déplacée, et cela m'a donné le :
J'ai simplement supprimé cette référence, je l'ai rajoutée et tout a fonctionné à nouveau.
Définissez d'abord le chemin en utilisant cette commande ;
Ensuite, vous devez charger le programme. Tapez "cd (nom du 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)" ;.