2011-10-13 4 views
1

J'ai un problème étrange que je ne peux pas comprendre ... J'ai un simple pot HelloWorld que j'ai construit dans Eclipse qui a le pot Apache Loggings sur son classpath. J'ai écrit un script pour exécuter le pot:Problèmes Java Jar et Classpath

#!/bin/sh 
export CLASSPATH=lib/*:$CLASSPATH 
java -jar HelloWorld.jar 

La structure du répertoire est ici un répertoire principal avec le HelloWorld.jar et un sous-répertoire lib tenant le commons-logging-1.1.1.jar.

L'exécution de ce script fonctionne correctement. Cependant, quand je place le HelloWorld.jar dans le répertoire lib (par exemple pour contenir tous les fichiers JAR dans un endroit), et l'exécution java -jar lib/HelloWorld.jar, je reçois:

Exception in thread "AWT-EventQueue-0" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory 
erreur

. Pourquoi?!?!?!?! Je demande cela parce que j'ai utilisé le JarBundler sur OSX pour créer un ensemble d'applications pour l'application HelloWorld et placé un script modifié dans le répertoire MacOS alors que toutes les bibliothèques sont placées dans le répertoire Resources/Java. version modifiée du script est:

#!/bin/sh 
RESOURCE_DIR=$(cd "../Resources"; pwd) 
export CLASSPATH=$RESOURCE_DIR/Java/*:$CLASSPATH 
java -jar $RESOURCE_DIR/Java/HelloWorld.jar 

et je reçois la même erreur que ci-dessus, je vous en serais reconnaissant toute aide pour comprendre pourquoi je ne peux pas le faire et/ou comment y remédier?

Répondre

6

Classpath ne fonctionne pas avec les caractères génériques. Chaque fichier jar doit être spécifié explicitement, soit dans le cadre de la variable CLASSPATH, soit dans le manifeste d'un autre fichier jar inclus dans le classpath. En outre, IIRC java -jar ignore tous les fichiers JAR tiers présents dans le chemin de classe. Pourquoi ne pas le faire à la place?

java -cp yourJar:logJars <mainClass> 
1

Utilisez le fichier MANIFEST (dossier META-INF) pour gérer les entrées Classpath. Utilisez des chemins relatifs pour les bibliothèques. Pour plus d'informations, jetez un oeil à here.

En fait, pour le cas commons-logging dans un dossier lib:

Class-Path: lib/commons-logging-1.1.1.jar 

Et pour les deux pots dans le même dossier:

Class-Path: commons-logging-1.1.1.jar 
0

Avez-vous mis log4j.jar dans votre classe . Je pense que vous n'avez pas ajouté log4j.jar à son chemin de classe.

+0

dans votre classpath * –

2

Essayez d'ajouter les commons-logging-1.1.1.jar au CLASSPATH directement

+0

J'ai essayé cela, (voir mon commentaire à @Sarel Botha) mais cela n'a toujours pas fonctionné. –

+0

Oui, je suppose que c'est le -jar qui cause ça ... Je pense que la solution @Jagat devrait fonctionner. – yoprogramo

2

Java ne fonctionnera pas avec lib/* mais la coque peut être pour vous en expansion. Double vérifier cela. Mettez une ligne comme celui-ci après l'exportation:

echo $CLASSPATH 

Aussi, je recommande de le mettre dans le fichier manifest comme déjà mentionné.

EDIT: Est-ce un problème de permission? Si vous exécutez l'application en tant que root/admin ou si vous placez le fichier ailleurs et que vous utilisez un chemin qualifié complet, cela fonctionne-t-il?

+0

le 'echo $ CLASSPATH' donne' /Users/sonogenics/Documents/workspace/HelloWorld/lib/commons-logging-1.1.1.jar: 'c'est ce que je m'attend à ce que ce soit mais je reçois toujours l'erreur. .. –

+0

L'exécution du script en tant que sudo ne résout toujours pas les problèmes. Je deviens fou! Mais merci pour l'entrée! –

+0

Je pense que Jagat a la bonne réponse. Quand vous utilisez -jar je sais qu'il ignore -classpath. Il ignore probablement $ CLASSPATH aussi. –

1

Merci à tous pour votre aide à comprendre cela. Fondamentalement, un fichier manifeste a été créé et empaqueté dans le pot sans que je le sache, donc tous les drapeaux $CLASSPATH ou -cp ont été ignorés. Dans mon projet Eclipse, mon chemin de classe a été défini sur $(projectRoot)/lib, qui correspond par coïncidence à la même structure de répertoire que mon répertoire dist. Cependant, quand ils étaient regroupés dans un répertoire par JarBundler d'OSX, le répertoire n'était plus présent, d'où les erreurs classpath!

J'ai essayé de retirer la ne semblent pas l'attribut Class-Path du MANIFEST.MF que Eclispe créé, mais la ligne de commande $CLASSPATH et/ou -cp entrées encore faire une différence ... Est-ce que l'existence d'un Négation de fichier manifeste toutes les lignes de commande classpath entrées?

+0

Je ne suis pas une bonne pratique pour poser des questions à l'intérieur des questions. S'il vous plaît, à partir de maintenant, poser de nouvelles questions ou mettre à jour votre question avec des informations pertinentes. En ce qui concerne votre réponse, 'java -jar' ignorera les paramètres de chemin de classe externes (cela n'a rien à voir avec la présence de MANIFEST Class-path). Vous pouvez utiliser la solution @jagat '-cp' pour gérer le classpath vous-même ... Mais, je ne peux pas insister sur le fait qu'il n'y a pas de raison de réinventer le bien, il suffit de définir correctement votre classpath dans votre fichier MANIFEST ou de le faire pour toi. [Tâche Ant] (http://informagen.com/JarBundler/). –

+0

Juste pour être plus précis, je parle des options 'jarfileset' et' jarfileset'. N'utilisez pas les options 'extraclasspath' * pour inclure la consignation des journaux. –