167 votes

Comment résoudre l'exception ClassNotFoundException ?

J'essaie d'exécuter une application Java, mais j'obtiens cette erreur :

java.lang.ClassNotFoundException:

Après les deux-points vient l'emplacement de la classe qui manque. Cependant, je sais que cet emplacement n'existe pas puisque la classe est située ailleurs. Comment puis-je mettre à jour le chemin de cette classe ? Cela a-t-il quelque chose à voir avec le chemin de la classe ?

69voto

user2000590 Points 561

Un classpath est une liste d'emplacements à partir desquels charger les classes.

Ces "emplacements" peuvent être soit des répertoires, soit des fichiers jar.

Pour les répertoires, la JVM suivra un modèle attendu pour le chargement d'une classe. Si j'ai le répertoire C:/myproject/classes dans mon classpath, et je tente de charger une classe com.mycompany.Foo il cherchera sous le répertoire des classes un répertoire appelé com puis sous ce dernier, un répertoire appelé monentreprise et enfin, il cherchera un fichier appelé Foo.class dans ce répertoire.

Dans le second cas, pour les fichiers jar, il cherchera le fichier jar pour cette classe. Un fichier jar n'est en réalité qu'une collection zippée de répertoires comme ci-dessus. Si vous décompressez un fichier jar, vous obtiendrez un ensemble de répertoires et de fichiers de classe suivant le modèle ci-dessus.

La JVM parcourt donc un classpath du début à la fin à la recherche de la définition de la classe lorsqu'elle tente de charger la définition de la classe. Par exemple, dans le classpath :

C:/myproject/classes;C:/myproject/lib/stuff.jar;C:/myproject/lib/otherstuff.jar

La JVM va essayer de chercher dans le répertoire clases d'abord, puis dans stuff.jar et enfin dans autrechose.jar .

Lorsque vous obtenez une ClassNotFoundException, cela signifie que la JVM a parcouru l'ensemble du classpath et n'a pas trouvé la classe que vous avez tenté de référencer. La solution, comme souvent dans le monde Java, est de vérifier votre classpath.

Vous définissez un classpath sur la ligne de commande en disant java -cp et ensuite votre classpath. Dans un IDE tel qu'Eclipse, vous aurez une option de menu pour spécifier votre classpath.

47voto

Votre classpath est cassé (ce qui est une très problème courant dans le monde Java).

Selon la façon dont vous démarrez votre application, vous devez réviser l'argument pour -cp votre entrée Class-Path dans MANIFEST.MF ou la disposition de votre disque.

25voto

Ram swaroop Points 309

C'est le la meilleure solution que j'ai trouvé jusqu'à présent.

Supposons que nous ayons un paquet appelé org.mypackage contenant les classes :

  • HelloWorld (classe principale)
  • SupportClass
  • UtilClass

et les fichiers définissant ce paquet sont stockés physiquement sous le répertoire D:\myprogram (sous Windows) ou /home/user/myprogram (sous Linux).

La structure du fichier ressemblera à ceci : enter image description here

Lorsque nous invoquons Java, nous spécifions le nom de l'application à exécuter : org.mypackage.HelloWorld . Cependant, nous devons également indiquer à Java où chercher les fichiers et les répertoires définissant notre paquetage. Ainsi, pour lancer le programme, nous devons utiliser la commande suivante : enter image description here

NOTE : Vous devez exécuter ce qui précède java quelle que soit votre position actuelle. Mais ce n'est pas le cas pour javac . Pour vous pouvez même aller directement dans le répertoire où vous avez installé votre .java et exécuter directement javac ClassName.java .

12voto

Chen Ni Points 16

J'ai eu la même erreur et il m'a fallu une journée entière pour réaliser qu'il s'agissait d'un problème de conflit de dépendances :

  • J'ai importé deux bibliothèques, A y B ;
  • Les deux sites A y B dépend d'une autre bibliothèque C mais différentes versions de C . Disons que A dépend de C 1.0 y B dépend de C 2.0 ;
  • B fait usage d'une classe qui n'existe que dans C 2.0 ;
  • Cependant, A est "plus proche" dans l'arbre des dépendances, donc Maven utilise C 1.0 pour les deux A y B et ne vous en avertit même pas (c'est assez stupéfiant pour moi) ;
  • Par conséquent, lorsque B essaie d'utiliser la classe qui n'existe que dans C 2.0 , a ClassNotFoundException est lancé ;

Maintenant, la chose étrange est : si vous naviguez le code de B dans votre IDE et essayez de sauter à la classe qui existe seulement dans C 2.0 il fonctionne correctement. C 2.0 est bien installé et votre IDE le sait, mais il est simplement ignoré lors de l'exécution de l'application.

Cela m'a vraiment rendu fou...

J'ai fini par devoir ajouter C 2.0 à mon pom.xml afin qu'il puisse être choisi parmi C 1.0 .

Veuillez vous référer à ce post pour savoir comment Maven choisit la dépendance la plus proche : https://stackoverflow.com/a/63815140/7438905

Vous pouvez utiliser mvn dependency:tree pour visualiser l'arbre de dépendance.

11voto

Juned Ahsan Points 33217

Si vous connaissez le chemin de la classe ou le jar contenant la classe, ajoutez-le à votre classpath en l'exécutant. Vous pouvez utiliser le classpath comme indiqué ici :

sur Windows

java -classpath .;yourjar.jar YourMainClass

sur UNIX/Linux

java -classpath .:yourjar.jar YourMainClass

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X