NoClassDefFoundError en essayant d'exécuter mon pot avec java.exe -jar...quel est le problème?
J'ai une application que je suis en train d'envelopper dans un pot pour faciliter le déploiement. L'application compile et fonctionne très bien (dans une fenêtre cmd Windows) lors de l'exécuter comme un ensemble de classes accessible depuis le CLASSPATH. Mais quand je bocal de mes classes et d'essayer de le faire fonctionner avec la version 1.6 de java dans la même fenêtre cmd, je commence à être des exceptions:
C:\dev\myapp\src\common\datagen>C:/apps/jdk1.6.0_07/bin/java.exe -classpath C:\myapp\libs\commons -logging-1.1.jar -server -jar DataGen.jar
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory
at com.example.myapp.fomc.common.datagen.DataGenerationTest.<clinit>(Unknown Source)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.LogFactory
at java.net.URLClassLoader$1.run(URLClassLoader.java:200)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
... 1 more
La chose drôle est, la délinquance LogFactory semble être en commons-logging-1.1.jar qui est dans le chemin de classe spécifiée. Le fichier jar (yep, c'est vraiment là):
C:\dev\myapp\src\common\datagen>dir C:\myapp\libs\commons-logging-1.1.jar
Volume in drive C is Local Disk
Volume Serial Number is ECCD-A6A7
Directory of C:\myapp\libs
12/11/2007 11:46 AM 52,915 commons-logging-1.1.jar
1 File(s) 52,915 bytes
0 Dir(s) 10,956,947,456 bytes free
Le contenu de la commons-logging-1.1.jar fichier:
C:\dev\myapp\src\common\datagen>jar -tf C:\myapp\libs\commons-logging-1.1.jar
META-INF/
META-INF/MANIFEST.MF
org/
org/apache/
org/apache/commons/
org/apache/commons/logging/
org/apache/commons/logging/impl/
META-INF/LICENSE.txt
META-INF/NOTICE.txt
org/apache/commons/logging/Log.class
org/apache/commons/logging/LogConfigurationException.class
org/apache/commons/logging/LogFactory$1.class
org/apache/commons/logging/LogFactory$2.class
org/apache/commons/logging/LogFactory$3.class
org/apache/commons/logging/LogFactory$4.class
org/apache/commons/logging/LogFactory$5.class
org/apache/commons/logging/LogFactory.class
... (more classes in commons-logging-1.1 ...)
Yep, commons-logging a la LogFactory classe. Et enfin, le contenu de mon pot de manifeste:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 10.0-b23 (Sun Microsystems Inc.)
Main-Class: com.example.myapp.fomc.common.datagen.DataGenerationTest
Class-Path: commons-logging-1.1.jar commons-lang.jar antlr.jar toplink
.jar GroboTestingJUnit-1.2.1-core.jar junit.jar
Ce qui a déconcerté les moi, et tous les collègues que j'ai buggé pendant plus d'un jour à l'autre. Juste pour choisir les réponses, du moins pour le moment, solutions tierces, ce sont probablement en raison de restrictions de licence et les politiques de l'entreprise (par exemple: outils pour créer des fichiers exe ou l'emballage jusqu'pots). Le but ultime est de créer un jar qui peuvent être copiés à partir de mon de développement de la zone de Windows pour un serveur Linux (avec tout dépendant des pots) et utilisé pour remplir une base de données (donc les chemins de classe peut-vent être différentes entre le développement et le déploiement d'environnements). Des indices à ce mystère serait grandement apprécié!
Vous devez vous connecter pour publier un commentaire.
Le -jar option est mutuellement exclusive des -classpath. Voir une vieille description ici
Un rapide et sale hack est pour ajouter votre classpath pour le bootstrap classpath:
Cependant, comme @Dan dit à juste titre, la bonne solution est de s'assurer vos Pots Manifeste contient le chemin de tous les Pots dont il a besoin.
Vous pouvez omettre le
-jar
option et lancer le fichier jar comme ceci:java -cp MyJar.jar;C:\externalJars\* mainpackage.MyMainClass
-classpath
et-jar
mais vous êtes clairement fait qu'il.C'est le problème qui est survenu,
si le fichier JAR a été chargé de "C:\java\apps\appli.jar" et votre fichier de manifeste a la Class-Path: référence "lib/other.jar", le chargeur de classes sont en "C:\java\apps\lib\" pour "other.jar". Il ne regarde pas le fichier JAR entrée "lib/other.jar".
Solution:-
[ MODIFIER = 3e option génère un dossier en plus du pot, 2ème option ("Package de bibliothèques requises en JAR généré") peut également être utilisé comme vous avez du pot. ]
ouvrez le terminal,donner le bon chemin vers votre bocal et l'exécuter à l'aide de cette commande java-jar abc.jar
Maintenant ce qui va arriver, c'est le chargeur de classe va le chercher dans le dossier approprié pour le référencés POTS depuis maintenant ils sont présents dans le même dossier qui contient votre application JAR..Il n'y a pas de "java.lang.NoClassDefFoundError" exception levée maintenant.
Cela a fonctionné pour moi... j'Espère que ça marche pour vous aussi!!!
si vous utilisez des bibliothèques externes dans votre programme et que vous essayez d'emballer tous ensemble dans un fichier jar, il n'est pas simple, en raison de classpath questions etc.
Je préfère utiliser OneJar pour cette question.
j'ai eu le même problème avec mon pot
la solution
Cela a fonctionné pour moi 🙂
J'ai trouvé quand je suis à l'aide d'un manifeste de ce que la liste des pots pour le classpath besoin d'avoir un espace après le classement de chaque pot par exemple "required_lib/sun/pop3.jar required_lib/sun/smtp.jar ". Même si c'est le dernier de la liste.