Here’s a brief “how-to” for remembering what is possible with a jar file, how to use it, launch its main class and define where the other jars (the libraries used) are stored. I could not find anywhere on the net a good explanation of all this, so decided to write my own.
So imagine you have your own jar file named myApp.jar which main class (the one with the “main” method) is marot.francois.MyMainClass which needs to receive 2 arguments: arg1 and arg2 (passed in String args).
1- Without using any MANIFEST.MF fil
If you don’t have a MANIFEST.MF file in your jar, or if you want to set some specific places where Java should look for the libraries used by myApp.jar, then you should use the following command. Beware, the use of the star is only available since Java 6 (or is it Java 5 ?)
java -cp tmmerge.jar;myCustomLibPath1\*;myCustomLibPath2\*;myCustomLibPath3\* marot.francois.MyMainClass arg1 arg2
java -cp tmmerge.jar:myCustomLibPath1\*:myCustomLibPath2\*:myCustomLibPath3\* marot.francois.MyMainClass arg1 arg2
Same as previous one but with all the libraries’ jars listed instead of using *:
java -cp ./myApp.jar;myCustomLibPath1\sctm.jar;myCustomLibPath2\ant.jar;myCustomLibPath2\ant-launcher.jar;myCustomLibPath3\scdata.jar marot.francois.MyMainClass arg1 arg2
java -cp ./myApp.jar:myCustomLibPath1\sctm.jar:myCustomLibPath2\ant.jar:myCustomLibPath2\ant-launcher.jar:myCustomLibPath3\scdata.jar marot.francois.MyMainClass arg1 arg2
At first, I thought such a command line was overriding the classpath in MANIFEST.MF, if any. But that is not the case, the MANIFEST.MF is just bypassed.
2- Using a MANIFEST.MF file in the jar
Launch myApp using the jar files listed in myApp.jar’s own manifest
java -jar myApp.jar arg1 arg2
The content of the META-INF\MANIFEST.MF file must be:
Ant-Version: Apache Ant 1.7.0
Created-By: 1.6.0_02-b06 (Sun Microsystems Inc.)
Package-Vendor: Elsys Design Avisto
Class-Path: myCustomLibPath2/ant-launcher.jar myCustomLibPath2/ant.jar myCustomLibPath3/scdata.jar myCustomLibPath1/sctm.jar
In a next post, I’ll show you how to use ANT to automatically generate the content listed here. And more specifically the list of libraries which would be error prone to write by hand.
By the way, I think it’s good to point to something important: in the “Class-Path”line of the manifest, you CAN’T use a star as you could do when specifying the classpath on the command line.
Also be aware that the space is the jars path delimiters as opposed to the “;” (windows) or “:” (Linux) on the command line. This last remark is very very error prone…
3- What I would like to be able to do (but it seems like Java doesn’t handle this case)
Warning: the exemple given hereafter does not work. I spent a lot of time trying to find some explanation of the reasons why, but was not able to find.
So the problem seems to be that you can’t override the default classpath specified in the jar’s manifest if you use the -cp switch at the same time. So the basic rule of thumb is:
“in java, do not use both switches -jar and -cp at the same time”: it does not work (at least up to Java 6).
I thought it would be cool to be able to run a jar but defining another place where it can find its dependancies. In case you want the users of your app to be able to use a shared folder containing the lib jars but don’t want him to have to know the main class’ name.
Here’s the command line I desperatly tryed to run:
REM java -cp myCustomLibPath1\*;myCustomLibPath2\*;myCustomLibPath3\* -jar myApp.jar arg1 arg2
Nevertheless, the same goal can be reached (successfuly) by using method 1. Only that the user needs to know the main class.