La java <class-name>
syntaxe de commande
Tout d'abord, vous devez comprendre la bonne façon de lancer un programme à l'aide de la commande java
(ou javaw
).
La syntaxe normale 1 est la suivante:
java [ <options> ] <class-name> [<arg> ...]
où <option>
est une option de ligne de commande (commençant par un caractère "-"), <class-name>
est un nom de classe Java complet et <arg>
est un argument de ligne de commande arbitraire qui est transmis à votre application.
1 - Il existe d'autres syntaxes qui sont décrites vers la fin de cette réponse.
Le nom complet (FQN) de la classe est conventionnellement écrit comme vous le feriez dans le code source Java; par exemple
packagename.packagename2.packagename3.ClassName
Cependant, certaines versions de la java
commande vous permettent d'utiliser des barres obliques au lieu de points; par exemple
packagename/packagename2/packagename3/ClassName
qui (confusément) ressemble à un chemin de fichier, mais n'en est pas un. Notez que le terme nom complet est une terminologie Java standard ... pas quelque chose que j'ai inventé pour vous confondre :-)
Voici un exemple de ce à quoi java
devrait ressembler une commande:
java -Xmx100m com.acme.example.ListUsers fred joe bert
Ce qui précède va amener la java
commande à effectuer les opérations suivantes:
- Recherchez la version compilée de la
com.acme.example.ListUsers
classe.
- Chargez la classe.
- Vérifiez que la classe possède une
main
méthode avec signature , type de retour et modificateurs donnés par public static void main(String[])
. (Remarque: le nom de l'argument de méthode NE fait PAS partie de la signature.)
- Appelez cette méthode en lui passant les arguments de ligne de commande ("fred", "joe", "bert") sous la forme d'un
String[]
.
Raisons pour lesquelles Java ne trouve pas 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 java
commande n'a pas pu trouver la classe. Et en effet, le « ... » dans le message sera le nom complet de la classe qui java
est à la recherche.
Alors pourquoi ne pourrait-il pas trouver la classe?
Raison n ° 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.) Compte tenu de 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 package tel que com.acme.example
, vous devez utiliser le nom de classe complet, y compris le nom du package dans la java
commande; 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 (sauf pour Java 11 ou version ultérieure; voir ci-dessous)
java ListUser.java
Exemple # 6 - vous avez complètement oublié le nom de la classe
java lots of arguments
Raison n ° 2 - le chemin de classe de l'application n'est pas spécifié correctement
La deuxième cause probable est que le nom de classe est correct, mais que la java
commande ne peut pas trouver la classe. Pour comprendre cela, vous devez comprendre le concept de "chemin de classe". 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:
- 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 chemin de classe Java.)
- Regardez la ligne de commande et / ou la variable d'environnement CLASSPATH qui est en vigueur lorsque vous exécutez la
java
commande. Vérifiez que les noms de répertoire et les noms de fichier JAR sont corrects.
- S'il y a des chemins d'accès relatifs dans le chemin de classe, vérifiez qu'ils se résolvent correctement ... à partir du répertoire en cours qui est en vigueur lorsque vous exécutez la
java
commande.
- Vérifiez que la classe (mentionnée dans le message d'erreur) peut se trouver sur le chemin de classe effectif .
- Notez que la syntaxe du chemin de classe est différente pour Windows par rapport à Linux et Mac OS. (Le séparateur de chemin de classe 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 n ° 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 noms qualifié. Les classes sont situées dans la structure de répertoires sous cette racine, en mappant le nom complet à un nom de chemin . Ainsi, par exemple, si "/ usr / local / acme / classes" se trouve sur le chemin d'accès aux classes, alors lorsque la machine virtuelle Java recherche une classe appelée com.acme.example.Foon
, elle recherche un fichier ".class" avec ce nom de chemin:
/usr/local/acme/classes/com/acme/example/Foon.class
Si vous aviez mis "/ usr / local / acme / classes / com / acme / example" sur le chemin de classe, la JVM ne pourrait pas trouver la classe.
Raison n ° 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.class" dans le répertoire "com / acme / example":
Si la structure de votre répertoire ne correspond pas au nom du package selon le modèle ci-dessus, la JVM ne trouvera pas votre classe.
Si vous essayez de renommer une classe en la déplaçant, cela échouera également ... mais le stacktrace d'exception sera différent. Il est susceptible de dire quelque chose comme ceci:
Caused by: java.lang.NoClassDefFoundError: <path> (wrong name: <name>)
car le FQN dans le fichier de classe ne correspond pas à ce que le chargeur de classe s'attend à trouver.
Pour donner un exemple concret, en supposant que:
- vous voulez exécuter la
com.acme.example.Foon
classe,
- le chemin de fichier complet 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'
-classpath
option peut être raccourcie -cp
dans la plupart des versions Java. Vérifiez les entrées manuelles respectives pour java
, javac
etc.
- Réfléchissez bien lorsque vous choisissez entre les chemins absolus et relatifs dans les chemins de classe. N'oubliez pas qu'un chemin d'accès relatif peut "casser" si le répertoire en cours change.
Raison n ° 2c - dépendances manquantes dans le chemin de classe
Le chemin de classe 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:
(Remarque: les spécifications JLS et JVM permettent à une JVM de charger les classes "paresseusement", ce qui peut affecter le déclenchement d'une exception de chargeur de classe.)
Raison n ° 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 arborescence de code source, ou laisse de côté la package
déclaration. Si vous faites cela dans un IDE, le compilateur de l'IDE vous en informera immédiatement. De même, si vous utilisez un outil de génération Java décent, l'outil s'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 manière que le compilateur ne remarque pas le problème et que le fichier ".class" résultant ne se trouve pas à l'endroit que vous attendez.
Vous ne trouvez toujours pas le problème?
Il y a beaucoup de choses à vérifier et il est facile de rater quelque chose. Essayez d'ajouter l' -Xdiag
option à la java
ligne de commande (comme première chose après java
). Il affichera diverses choses sur le chargement des classes, et cela peut vous donner des indices sur le vrai problème.
Tenez également compte des problèmes possibles causés par la copie et le collage de caractères invisibles ou non ASCII à partir de sites Web, de documents, etc. Et considérez les "homoglyphes", si deux lettres ou symboles se ressemblent ... mais ne le sont pas.
Enfin, vous pouvez apparemment rencontrer ce problème si vous essayez de lancer à partir d'un fichier JAR avec des signatures incorrectes (META-INF/*.SF)
.
Syntaxes alternatives pour java
Il existe trois syntaxes alternatives pour le lancement de programmes Java à l'aide de java command
.
1) La syntaxe utilisée pour lancer un fichier JAR "exécutable" est la suivante:
java [ <options> ] -jar <jar-file-name> [<arg> ...]
par exemple
java -Xmx100m -jar /usr/local/acme-example/listuser.jar fred
Le nom de la classe de point d'entrée (c'est-à-dire com.acme.example.ListUser
) et le chemin de classe sont spécifiés dans le MANIFEST du fichier JAR.
2) La syntaxe de lancement d'une application à partir d'un module (Java 9 et versions ultérieures) est la suivante:
java [ <options> ] --module <module>[/<mainclass>] [<arg> ...]
Le nom de la classe de point d'entrée est soit défini par <module>
lui - même, soit donné par l'option <mainclass>
.
3) À partir de Java 11, vous pouvez compiler et exécuter un seul fichier de code source et l'exécuter avec la syntaxe suivante:
java [ <options> ] <sourcefile> [<arg> ...]
où est (généralement) un fichier avec le suffixe ".java".
Pour plus de détails, veuillez vous référer à la documentation officielle de la java
commande de la version Java que vous utilisez.
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. Celles-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 d'exécution, identifier la classe principale et créer la java
ligne de commande.
Cependant, il est toujours possible que cette exception se produise, si vous faites des choses derrière le dos de l'EDI. 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 "principale" vers un autre endroit du système de fichiers sans en informer Eclipse , Eclipse lancerait involontairement la JVM avec un chemin de classe incorrect.
En bref, si vous rencontrez ce problème dans un IDE, recherchez des éléments tels que l'état IDE périmé, les références de projet cassées ou les configurations de lanceur cassées.
Il est également possible pour un IDE de se confondre simplement. Les IDE sont des logiciels extrêmement compliqués comprenant de nombreuses parties en interaction. Beaucoup de ces parties adoptent différentes stratégies de mise en cache afin de rendre l'IDE dans son ensemble réactif. Ceux-ci peuvent parfois mal tourner, et un des symptômes possibles est le problème lors du lancement des applications. Si vous pensez que cela pourrait se produire, cela vaut la peine d'essayer d'autres choses comme le redémarrage de votre IDE, la reconstruction du projet, etc.
Autres références