7

I have the following directory hierarchy :

SigarTest
 src
    SigarTest
     .java files
 bin
    SigarTest
     .class files

Here,SigarTest is a package name. The root folder is in the bin folder of the jdk. From there, im running the following command to create a jar file of my project -

./jar cfe temp.jar SigarTest.SigarMain SigarTest/bin/ tools.jar sigar.jar mongo-2.7.3.jar

where tools.jar, mongo-2.7.3.jar and sigar.jar are required and are in the same folder as root directory (bin folder of jdk). However, on running it, i get

ClassNotFoundException : SigarTest.SigarMain

What am i doing wrong ?

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
Cygnus
  • 3,222
  • 9
  • 35
  • 65

1 Answers1

5

Use the -C dir option which

Temporarily changes directories (cd dir) during execution of the jar command while processing the following inputfiles argument.

If you execute the jar command in your question and list the contents of temp.jar, you will see output similar to the following:

$ rm -rf temp.jar
$ jar cfe temp.jar SigarTest.SigarMain SigarTest/bin/ tools.jar sigar.jar mongo-2.7.3.jar
$ jar tf temp.jar
META-INF/
META-INF/MANIFEST.MF
SigarTest/bin/
SigarTest/bin/SigarTest/
SigarTest/bin/SigarTest/SigarMain.class
tools.jar
sigar.jar
mongo-2.7.3.jar
$ java -jar temp.jar
Exception in thread "main" java.lang.NoClassDefFoundError: SigarTest/SigarMain
Caused by: java.lang.ClassNotFoundException: SigarTest.SigarMain
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

Note that having SigarTest/bin in temp.jar is incorrect. Executing temp.jar throws the ClassNotFoundException since SigarMain is in package SigarTest.bin.SigarTest. Now consider the following jar command that uses the -C dir option:

$ rm -rf temp.jar
$ jar cfe temp.jar SigarTest.SigarMain -C SigarTest/bin/ . tools.jar sigar.jar mongo-2.7.3.jar
$ jar tf temp.jar
META-INF/
META-INF/MANIFEST.MF
SigarTest/
SigarTest/SigarMain.class
tools.jar
sigar.jar
mongo-2.7.3.jar
$ java -jar temp.jar

SigarMain is in the correct package and executing temp.jar does not throw a ClassNotFoundException.

creemama
  • 6,559
  • 3
  • 21
  • 26
  • Btw, when u do -C, is the directory changed for only the files following the directory name or all values that follow that name ? According to this, it should be the latter right ? – Cygnus Jun 28 '12 at 12:14
  • 1
    The documentation is a little confusing on this. From some testing, I found that it was just the one file following, which explains why in `-C SigarTest/bin/ . tools.jar`, `SigarMain.class` is taken from `SigarTest/bin/` and `tools.jar` is taken from the directory `jar` was executed in. You can also specify `-C` multiple times. – creemama Jun 28 '12 at 12:15