Question

I have a JAVA program which connects to MySQL and performers some update tasks. I now want to export the application as a jar file with included JDBC package. I'm doing something like (pwd for all the following commands is: /home/tnp/UpdateServer_SRC/bin/):

$ echo $CLASSPATH 
.:/home/tnp/UpdateServer_SRC/bin/update/server:/home/tnp/UpdateServer_SRC/bin/update/server/jdbc.jar
$ java update.server.Main
Latest: 12177
IGNORING: 12172
IGNORING: 12173
IGNORING: 12174
IGNORING: 12175
IGNORING: 12176
IGNORING: 12177
^C

so far so goo, I'm quitting the execution as it performs them in a while loop every 30 minutes.

Now, creating the jar file:

$ jar cvf sth.jar update
added manifest
adding: update/(in = 0) (out= 0)(stored 0%)
adding: update/server/(in = 0) (out= 0)(stored 0%)
adding: update/server/ThreadNetwork.class(in = 1866) (out= 1021)(deflated 45%)
adding: update/server/HomePage.class(in = 2046) (out= 1184)(deflated 42%)
adding: update/server/jdbc.jar(in = 876733) (out= 837707)(deflated 4%)
adding: update/server/UpdateLast5.class(in = 2045) (out= 1179)(deflated 42%)
adding: update/server/Main.class(in = 742) (out= 504)(deflated 32%)
adding: update/server/Notice.class(in = 2715) (out= 1521)(deflated 43%)

Ok. Jar file created. Let's try to run it:

$ java -jar sth.jar 
no main manifest attribute, in sth.jar

Oh, the pwd is not in my current class path. Let me try again:

$ java -cp sth.jar update.server.Main
Latest: 12177
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:190)
        at update.server.UpdateLast5.run(UpdateLast5.java:18)
        at java.lang.Thread.run(Thread.java:724)
Exception in thread "Thread-0" java.lang.NullPointerException
        at update.server.UpdateLast5.run(UpdateLast5.java:40)
        at java.lang.Thread.run(Thread.java:724)

And this stacktrace is thrown. I saw on another question that:

In case of JARs, the -cp and -classpath arguments and the %CLASSPATH% environment variable are ignored.

and I'd need to modify the MANIFET.MF file manually, and recreate the jar. But the answer linked above states that the class-path should be relative to my own jar file (sth.jar) and doesn't mention what to do about bundled jar files.

How do I import JDBC in my package so that the resulting jar file would function "normally". Any help would be appreciated.

Was it helpful?

Solution

Solved the problem currently by using the following MANIFEST file:

Manifest-Version: 1.0
Created-By: 1.7.0_25 (Oracle Corporation)
Main-Class: update.server.Main
Class-Path: jdbc.jar

and putting jdbc.jar in the same directory as my sth.jar.

OTHER TIPS

Include required JARs in your generated JAR root and load them at runtime (which means you need a ClassLoader to handle this).

Most IDEs do this for you, for example in Eclipse you just tell it to "Package required libraries in JAR".

Ant can also do so as explained in this other question.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top