How-to java jars and MANIFEST.MF

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 ?)

on Windows:
java -cp tmmerge.jar;myCustomLibPath1\*;myCustomLibPath2\*;myCustomLibPath3\* marot.francois.MyMainClass arg1 arg2

on Linux:
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 *:
on Windows:
java -cp ./myApp.jar;myCustomLibPath1\sctm.jar;myCustomLibPath2\ant.jar;myCustomLibPath2\ant-launcher.jar;myCustomLibPath3\scdata.jar marot.francois.MyMainClass arg1 arg2

on Linux:
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:

Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: 1.6.0_02-b06 (Sun Microsystems Inc.)
Main-Class: marot.francois.MyMainClass
Product-Name:  myApp
Package-Title: marot.francois
Package-Version: 1.00.00
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.

About these ads

17 thoughts on “How-to java jars and MANIFEST.MF

  1. [...] Some thoughts about things Computing, IT, society… « How-to java jars and MANIFEST.MF [...]

  2. Thank you very much for the valuable inputs…
    I am facing an issue.. I am using a junit library and built a test library testXXX.jar now this has a number of dependent jars say XXX.jar etc but how do i ask the testXXX.jar to use XXX.jar and execute the test library?

  3. Swathi, I don’t really understand your problem there… Why can’t you use for testXXX.jar the same process used for your application’s main jar ?

  4. Actually i have one jar xxxlib.jar . Now from command line i ll be executing the jar yyylib.jar(inside that i have one property file prop.properties) which inturn use the xxxlib.jar. Now my problem is when i try to access the prop.properties while executing the yyylib.jar from cmd prompt i am not able to read the property file inside the yyylib.jar. I want to know how i can read this property file which is actually inside the jar?

  5. If I understand, you try to access the *.properties file in xxxlib.jar from yyylib.jar… I never faced such a problem. Perhaps you could add a utility class in xxxlib.jar that would provide such an access through public methos ? Otherwise, try to find information on how to read files in jar files.

  6. Actually thats my doubt i am unable to read the property file inside the xxxlib.jar.

  7. [...] http://blog.arkabo.com/?p=46 – bookmarked by 3 members originally found by crooger on 2008-12-30 How-to java jars and MANIFEST.MF http://fraaargh.wordpress.com/2008/07/13/how-to-java-jars-and-manifestmf/ – bookmarked by 3 [...]

  8. I liked the post. Useful. Thanks. -MD

  9. Hi,

    Thanks for your great article, it was very useful. How about packing the classpath jars into the jar, in order to have a unique executable file containing my program and the libraries?

    I’m trying to do so, but the manifest seems to refer only to outside the jar.

    any clue?

    Thanks,
    Giulio

  10. Glulio thanks for your comment.
    To my knowlege, you can’t pack jars inside another jar… Too bad !
    But I think there exist programms that can unpack jars and repack them inside your own jar. Or at least help you make this process. But the drawback is you can’t update easily the libraries you use: it becomes harder than simply copying the new version in you “lib” folder… So my advice would be to stick to the usual way: having a lib folder referenced from the classpath and accept it ;)

  11. Hi Francois,

    Thanks for your answer. That’s exactly what I thought, until I found a jar package containing the packed jars and working fine. This left me kinda disconcerned. That’s why I asked.

    Checking better I found that the JAR contains ALSO the unpacked .class files from the library jars.

    Tricks…. this is not too elegant… but it works.

    I’ll write an article about this on my site.

    ciao ciao,

    G

  12. @Giulio could you post a link to your article here once you have wrote it ? It could help all the people who look for information about jars, classpatch and manifest ;)
    By the way, as the jar files are nothing more than zip files, maybe the original jars were included but not used in the jar you’re talking about. Did you try to delete the included jars from the containing jar and see if the programm still works ? I would tend to think so as I think the .class are used and not the included jars themselves.

  13. Indeed, your guess is right, only the uncompressed jars are used… it’s basically the same thing as having a bigger sourcecode, which reimplements the classes that come from the library jar files.

    The difference is that generally the jars come already compiled in .class files, while our class files come from source code rather than precompiled software.

    I think that we would need to decorate the classloader in order to make it work with the jars in the same ways J2EE works with the WAR and EAR files.

    To load classes from a compressed package it’s actually a prerogative of j2ee.

    Tschuss,
    Giulio

  14. Hi Again,

    the matter looked like splittable into many articles, so I generated the first of the serie:

    http://www.wikijava.org/wiki/Packing_library_packages_into_a_jar_file

    Please don’t hesitate correcting it (it’s a wiki) if I wasn’t correct in anything.

    Pa pa,
    Giulio

  15. Follow up to Giulio: a way to package many jar files into a single one is to use the “Maven Shade plugin” ( http://maven.apache.org/plugins/maven-shade-plugin/ )… and obviously Maven as a build tool ;)

  16. Hi I have a Jar file X.jar which has a lib folder and contains three other jar files. I placed the X.jar in server and tried to execute but its throwing error failed to read manifest file. my manifest file is blank.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s