简体   繁体   中英

Java Jar and Classpath problems

I've got a weird problem that I can't understand... I have a simple HelloWorld jar that I built in Eclipse which has the Apache Loggings jar on it's classpath. I've written a script to run the jar:

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

The directory structure here is a main directory with the HelloWorld.jar and a lib subdirectory holding the commons-logging-1.1.1.jar .

Running this script works fine. However, when I place the HelloWorld.jar into the lib directory (ie to contain all the JARs in one place), and executing java -jar lib/HelloWorld.jar , I get:

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

error. Why?!?!?!?!

I'm asking this because I've used the JarBundler on OSX to create an Application bundle for the HelloWorld app and placed a modified script in the MacOS directory whereas all the libs are placed in the Resources/Java directory. Modified version of the script is:

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

and I'm getting the same error as above I'd really appreciate any help understanding why I can't do this and/or how to fix it?

Classpath doesn't work with wildcards. Every jar has to be specified explicitly, either as part of the CLASSPATH variable or in the manifest of another jar that is included in the classpath.

Also, IIRC java -jar ignores all the third party jars that are present in the classpath. Why not do this instead?

java -cp yourJar:logJars <mainClass>

尝试将commons-logging-1.1.1.jar直接添加到CLASSPATH中

Java will not work with lib/* but the shell may be expanding it for you. Double check this. Put a line like this after export:

echo $CLASSPATH

Also, I would recommend putting it in the MANIFEST file as already mentioned.

EDIT: Is it a permission problem? If you run the app as root/admin or put the file somewhere else and use a fully-qualified path does it work?

Use the MANIFEST file (META-INF folder) to deal with Classpath entries. Use relative paths for the libraries.

For further info, take a look here .

Basically, for the case with commons-logging inside a lib folder:

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

And for both jars in the same folder:

Class-Path: commons-logging-1.1.1.jar

Thanks to everyone for their help in figuring this out. Basically, a manifest file was being created and bundled into the jar without my knowledge so any $CLASSPATH or -cp flags were being ignored. In my Eclipse project, I had my classpath set to $(projectRoot)/lib which coincidentally the same directory structure as my dist directory. However, when they were bundled into one directory by OSX's JarBundler, the directory was no long present, hence the classpath errors!

I tried removing the Class-Path attribute from the MANIFEST.MF that Eclispe created but the command line $CLASSPATH and/or -cp entries still don't seem to make a difference... Does the existence of a manifest file negate all command line classpath entries?

have you set log4j.jar into your class. i think you didnt added log4j.jar of to its class path.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM