Saturday, July 5, 2008

Packaging j2se application in jar

Jar file is distributable unit for j2se applications. It is a zipped file but with jar extension. Jar file contains following contents:

- Java compiled classes
- manifest.mf file which contains meta info regarding jar like name of main class, jars to be added in classpath etc, version info etc. (optional)
- other jars on which classes of this jar depends (optional)

There are two types of jars:

- Library Jar
- Executable Jar

Difference between the two jars is simply a main class. If your application runs standalone and contains main class, then you put name of main class in manifest file. This makes a jar an executable jar. You can run your executable jar just by double clicking on it or through java command with switch -jar. On the other hand, library jar does not contain any main class, and it always runs as a dependency jar for other java applications.

Now lets see how we can create a library jar
If you project just contains java classes and no other jars or manifest file, then you will create jar using following command:

project-folder>jar cvf mylibrary.jar -C classes .

cvf are three switches for jar. "c" means i want to create a new jar rather than updating previous one. "v" means i want to print all log info on console. "f" means supply an output to file i.e. mylibrary.jar in this case. -C is another switch which is used to tell which folders you want to include in jar. In my case all compiled java files are under classes folder but i don't want to include classes folder itself in jar so i used "-C classes .". Dot "." here tells jar command not to include classes folder. If you omit ".", then you have to change switch -C with this "-C classes/". it will tell jar command that all compiles files are under classes folder and include classes folder itself in jar file.
if you look at the contents of created jar file using any unzipped software, you will find that it contains classes + one more folder named as "META-INF". This folder contains manifest.mf. By default jar creates manifest.mf itself if you don't provide it. If you open this manfiest.mf using any text editor, you will see it just contains following two entries:

Manifest-Version: 1.0
Created-By: 1.6.0_03 (Sun Microsystems Inc.)

Important one is "Created-By" which tells which version of java was used to package jar file. In this case it is jse 6 with update 3.
If classes depend on other jars, you have to include those jars in classpath. This can be done at the time of running a program or writing all dependencis in manifest file, so java will automatically add it to classpath. Suppose above jar "mylibrary.jar" depends on other jars named as "other1.jar" and "other2.jar". Now to include these two jars in classpath through manifest file. Create a text file with any name let dependencies.txt and add following lines:

Class-Path: other1.jar other2.jar

Keep in mind that you have to provide spaced in between the every two jar file names.

Now you can add this manifest file to already created manifest file using following command:

project-folder> jar uvfm mylibrary.jar dependencies.txt

Console output will show that Manifest.mf updated. In this command i used switch "u" instead of "c" because i want to append manifest in already created jar. I also used "m" switch, which is used when you want to provide your own manifest file. If i want to create new jars with my own manifest file, then i have to use following command:

project-folder> jar cvfm mylibrary.jar dependencies.txt -C classes .

It is the same command as used previously to create jar with exception of extra "m" switch and name of manifest file.

Procedure of creating executable jar file is the same as library jar but you have to provide one extra attribute in your manifest file with name "Main-Class", So if i have name of main class as "org.engineers.java.MyMain", then i will have to added one entry in manifest file as:

Main-Class: org.engineers.java.MyMain

No comments: