views:

713

answers:

5

I've looked through many of the existing threads about this error, but still no luck. I'm not even trying to package a jar or use any third-party packaging tools. I'm simply running from within Eclipse (works great) and then trying to run the exact same app from the command line, in the same location it's built to (getting this error). My goal is to be able to zip up the bin folder and send it off to be run by someone else via a command line script. Some details:

  • It's a command-line app and I'm using the commons-lang-2.4.jar for string utilities. That is the file that cannot be located (specificaly "java.lang.NoClassDefFoundError: org/apache/commons/lang/StringEscapeUtils")
  • I have that jar in my lib folder and have added it to my build path in Eclipse via right-click "Build Path -> Add to Build Path"
  • The .classpath file looks correct and contains the reference to the jar, but I assume that file is only used by Eclipse (contains this line: <classpathentry kind="lib" path="lib/commons-lang-2.4.jar"/>)
  • Could this be related to the Eclipse working directory setting? I have some internal template files that I created that are under src/templates, and the only way I can seem to get those to be seen is by setting the project working directory to AppName/src. Maybe I should be putting those somewhere else?

Let me know if any additional info would help. Surely this is something simple, but I've wasted too much time on it at this point. This is reminding me why I originally left Java back in '05 or so...

+6  A: 

Are you specifying the classpath to java on the command line?

$ java -cp lib/commons-lang-2.4.jar your.main.Class

David Tinker
+9  A: 

A NoClassDefFoundError basically means that the class was there in the classpath during compiletime, but it is missing in the classpath during runtime.

In your case, when executing using java.exe from commandline, you need to specify the classpath in the -cp or -classpath argument. Or if it is a JAR file, then you need to specify it in the class-path entry of its MANIFEST.MF file.

The value of the argument/entry can be either absolute or relative file system paths to a folder containing all .class files or to an individual .jar file. You can separate paths using a semicolon ;. When a path contains spaces, you need to wrap the particular path with doublequotes ". Example:

java -cp .;c:/path/to/file.jar;"c:/spacy path/to/classes" mypackage.MyClass

To save the effort of typing and editing the argument in commandline everytime, use a .bat file.

Edit: I should have realized that you're using an Unix based operating system. The above examples are Windows-targeted. In the case of Unix like platforms you can follow the same rules, but you need to separate the paths using a colon : and instead of an eventual batch file, use a .sh file.

java -cp .:/path/to/file.jar:"/spacy path/to/classes" mypackage.MyClass
BalusC
This got me close. I am now using this command: java -cp bin;lib/commons-lang-2.4.jar bin/AppName -- now I'm getting "lib/commons-lang-2.4.jar: Permission denied" ??
bmoeskau
@bmoeskau: That's more an operating system level restriction. Check the file permissions.
BalusC
Yeah, I know that :) What's the requirement for jars? Do they need execute permissions? Look like by default it has -rw-r--r--
bmoeskau
@bmoeskay: chmod 755 ought to be OK.
BalusC
I should have mentioned I'm on Mac (unix). The security error is because it is actually trying to execute the jar incorrectly. Unix requires : instead of ; as the path separator. This seems to work: java -cp bin:lib/commons-lang-2.4.jar AppNameI'm now hitting a different error, but I think this resolves my original issue, so I'm accepting your answer. Thanks!
bmoeskau
FYI, new error was that it could not find the path to some internal template files. Changed the code to use getResource() and now it's working great -- thanks again.
bmoeskau
@BalusCThanks for the tip, really helpful.
masato-san
@masato: you're welcome.
BalusC
A: 

Eclipse does not move any of the jars in your classpath into the bin folder of your project. You need to copy the util jar into the bin folder. If you move it to the root of the bin folder, you might be able to get away without any classpath entries but it's not the recommended solution. See @BalusC's answer for good coverage of that.

Kelly French
+2  A: 

The classpath setting you are setting in Eclispe are only for the IDE and do not affect how you application is run outside the IDE. Even if you use the Eclipse Functionality to export your application as an executable jar file there is no out of the box way to package all the jars your application depends on.

If you have packaged you application into a jar file called myapp.jar then running a command like below will run the application with the jar you depend on, if you have more than one just add them separted by ; on Windows or : on Unix:

java -jar myapp.jar -cp .;c:/pathtolibs/commons-lang-2.4.jar

If you are just running the classes directly then either run the folder containing your .class files will also need to be on the path (though I assume it already is since you are able to run the program and get errors).

Tendayi Mawushe
+1  A: 

Consider File -> Export -> Runnable jar to create a jar file which can be invoked directly with

java -jar yourProgram.jar

There are several variants depending on your needs.

Thorbjørn Ravn Andersen
I actually tried this too, but in this case I get an error (from inside my app) that my custom templates folder (under /src in Eclipse) cannot be found. Not sure how resource paths work with jars.
bmoeskau
Actually, I figured out that I need to be using getResource() to access my template files -- changed the code, tried exporting as a jar and it works great now! I might go this route, thanks for the info.
bmoeskau
If you want stuff from the classpath, use getResource or getResourceAsStream. Note that this is a required step if you want to use Java Web Start.
Thorbjørn Ravn Andersen