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 ?
Tout d'abord, vous devez comprendre la manière correcte de lancer un programme en utilisant la commande java
(ou javaw
).
La syntaxe normale1 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 entièrement qualifié, et <argument>
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.
packagename.packagename2.packagename3.ClassName
Cependant, certaines versions de la commande java
vous permettent d'utiliser des barres obliques à la place des points ; par ex.
packagename/packagename2/packagename3/ClassName
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
:
java -Xmx100m com.acme.example.ListUsers fred joe bert
La commande java
va faire ce qui suit :
com.acme.example.ListUsers
.main
avec signature, type de retour et modificateurs donnés par public static void main(String[])
. (Remarque : le nom de l'argument de la méthode ne fait PAS partie de la signature).String[]
.
Raisons pour lesquelles Java ne peut pas trouver la classejava
n'a pas pu trouver la classe. Et en effet, le " ;..." ; dans le message sera le nom de classe entièrement qualifié que java
recherche.
Alors pourquoi la commande n'est-elle pas en mesure de trouver la classe ?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 :
java ListUser
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 commande java
; par ex.
java com.acme.example.ListUser
Exemple 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
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
.;
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 :
/usr/local/acme/classes/com/acme/example/Foon.class
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 :# 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 :
L'option -classpath
peut être raccourcie en -cp
dans la plupart des versions de Java. Vérifiez les entrées de manuel respectives pour java
, javac
et ainsi de suite.
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)
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écutera 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 que le fichier " ;.class" ; résultant ne soit pas à l'endroit où vous l'attendez.
Vous ne trouvez toujours pas le problème ?-Xdiag
à la ligne de commande java
(comme première chose après java
). 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 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
com.acme.example.ListUser
) et le classpath sont spécifiés dans le MANIFEST du fichier JAR.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.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 :
Could not find or load main class xxx Linux
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 ;
set path="paste the set path address"
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)" ;.