jar : Java Glossary

*0-9ABCDEFGHIJKLMNOPQRSTUVWXYZ (all)

jarjar
Java classes forming an application, Applet, or weblet can be bundled up into something that looks very much like a ZIP file. JavaBeans are also packaged in JAR files. In Java version 1.1 or later compression is turned on by default and in earlier versions it was always off. It is faster to download a group of classes as a single JAR file since HTTP (Hypertext Transfer Protocol) has high overhead to set up a connection for each file transferred. The tools Jar.exe and jarsigner.exe come bundled with the JDK (Java Development Kit).
Jar vs Zip Manifest Class-Path:
Tips on Using Jar Files Writing To Jars
Building Jar Files Gotchas
Which Classes to Include Sealing
Executing Jar Files Nesting
Making Jar Files Double Clickable jar.exe
The Manifest Signing
Manifest Gotchas Jars On Mac
Continuation Learning More
Main-Class Links

Jar vs Zip

A JAR file differs from a standard ZIP in that:

Tips on Using Jar Files

Building Jar Files

You can use GenJar, Ant, Gradle or Maven. You can create or read jar files with the java.util.zip classes, or with Oracle’s Jar.exe. utility. In theory, you could also use WinZip version 6.3 or later to view or delete files. Unfortunately WinZip there are several problems in using WinZip to create jar files or to add files to them. I have written the WinZip people several times asking for some simple extensions to make WinZip suitable for dealing with jar files, but each time they have refused.

If you are using packages, for jar.exe you must be in the root directory when using jar.exe to ensure your package names get properly included because the names you give jar.exe on the command line are the names it will blindly use for your packages inside the created jar file. You don’t want any names like J:\com\mindprod\mypackage.MyClass.class or \com\mindprod\mypackage.MyClass.class or MyClass.class (unless you have no packages). You want names like com\mindprod\mypackage\MyClass.class which translates to com.mindprod.mypackage.MyClass.class on the command line. They have to make sense both as filenames and as fully qualified package/class names.

If you are not using packages, you must be in the directory where the class files are when you build your jar. That way the filename MyClass.class will be the same as the classname MyClass.class.

Here in how you build a jar file from class files:

See Main-Class for details on how to create the main.mft file. See jar.exe for another explanation of how to use it. You create a main.mft file to help generate an /META-INF/MANIFEST.MF member. You don’t create the /META-INF/MANIFEST.MF directly.

Starting in Java version 1.5, you can super-compress jar files using pack200.exe. This will optionally remove debug information and compress the jar as a whole.

Which Classes to Include

Here are some strategies to decide which classes to include in your jar file:

  1. GenJar. This is fully automatic. GenJar chases dependencies and dependencies of dependencies to find all the classes. It has two disadvanatages.
    1. It can include classes that might in theory be used, but in practice would never be used.
    2. GenJar often fails without explanation. There is nothing you can do to make it work.
  2. Jet. Create a jar of some of the classes needed. Jet will tell you the classes you left out. The problem with this method is Jet is quite expensive. This too will include some classes referenced but never actually used.
  3. Build and Prune. Build a jar with every class in it that might remotely be used. Use the java.exe -verbose:class to display each class as it is loaded. Exercise all the features of the program. Build a new jar with just the classes that got loaded.
  4. Use Gradle or Maven. It is up to you to decide which packages each package needs. Gradle or Maven will then include every single class. This adds many classes not needed.
  5. Trial and Error. This technique is very slow. Build a jar with the classes you think are needed. Run the jar. It will abort when it tries to load a class not included. Rebuild that jar with that class included. Repeat.

Someone should write a utility that prunes a Jar file of classes never referenced, and produces a list of classes referenced but not present. This could be used as a final polishing stage in any jar-building technique.

Executing Jar Files

One of the most useful associations to set up is to make *.jar files executable with java.exe (see below for details how). Then you can just type the name of the jar on the command line to start it executing. After you have built the Main-Class entry and set up an association of the *.jar extension to C:\Program Files\java\jre1.8.0_131\bin\java.exe, all you need to do to run the jar is:

converter.jar
or
java.exe -jar converter.jar
Watch out. Java install sets the association back to javaw.exe, no console! If you get unhandled Exceptions, you will never find out about the errors, stack dumps or any other error messages!

To run the jar in an Applet, see Applet for some sample HTML (Hypertext Markup Language) or see

on doing it.

Making Jar Files Double Clickable

In XP, W2003, Vista, W2008, W7-32, W7-64, W8-32, W8-64, W2012, W10-32 and W10-64 you can use the method shown below:.

  1. Download Johann Löfflmann’s Jarfix.exe.
  2. Run

    jarfix.exe

    if you want to hook up your 32-bit JRE or

    jarfix.exe /64

    if you want to hook up your 64-bit JRE. It says on does not work on W10-32 and W10-64, but it does.

  3. This will invoke C:\Program Files\java\jre1.8.0_131\bin\javaw.exe when you run someapp.jar or double click the someapp.jar file.
  4. This is Oracle’s official way of doing things — throw away all the console output. I find this idiotic. You want the output. You want the error messages. You want to invoke C:\Program Files\java\jre1.8.0_131\bin\java.exe instead.
  5. To fix the problem, invoke regedit.exe at a run-as-administrator prompt.
  6. Look for:

    [HKEY_CLASSES_ROOT\jarfile\shell\open\command]
    "C:\Program Files\Java\jre1.8.0_131\bin\javaw.exe" -jar "%1" %*

    and change it to:

    [HKEY_CLASSES_ROOT\jarfile\shell\open\command]
    "C:\Program Files\Java\jre1.8.0_131\bin\java.exe" -jar "%1" %*
  7. Alternatively, you might configure a custom jarfix.ini file that uses java.exe in place of javaw.exe with the /c option.
  8. You also need a config file if your JRE is not on C: or if you have multiple JREs. The loeffliman.net website gives instructions on composing an ini file. You can also use REGEDIT to patch the generated registry entry manually under run-as-administrator.

There are lots of other methods people have recommended, but this is the only one I found that works.

The associations for *.jar and *.jnlp are fragile. They mysteriously change to obsolete versions, or javaw.exe version without a console or even unrelated programs like Winzip.exe. Using the java.exe -jar myjar.jar syntax in your bat/btm files rather is more robust than myjar.jar. It works even when the associations are corrupted.

The Manifest

The manifest is a member file inside a JAR file describing the contents of the JAR archive. It always has the name /META-INF/MANIFEST.MF. A Oracle signed version is more complex in that it also contains a hash for each member put here by jarsigner.
Manifest-Version: 1.0
Created-By: 1.4.0 (Sun Microsystems Inc.)
Main-Class: com.mindprod.bio.Biorhythms
Name: com/mindprod/bio/Biorhythms.class
SHA1-Digest: ueEw1mJ4aOXT9vmosR0nM/eUt6Y=
Name: com/mindprod/bio/SelectableDate.class
SHA1-Digest: 8HylCo90The8D1mBuYEEOFQDUsY=
The specification document is very loose about the format of a manifest file. Here are the rules I have gleaned from experimentation:

It might be wise to review the /META-INF/MANIFEST.MF member generated by examining the JAR file with WinZip. Unfortunately WinZip there are several problems in using WinZip to create jar files or to add files to them.

Starting with Java 7 update 51, you need two extra lines in the manifest:

Application-Name: XXXXX
Permissions: sandbox
Permissions: all-permissions

Sandbox means standard Applet security. full-permissions means full desktop permission.

Manifest Gotchas

Main-Class

Starting with Java version 1.2, a jar may made be executable by designating one class in it as the official class to start when the jar as a whole is executed, e.g. double clicked or executed on the command
java.exe -jar biorhythms.jar
The key is an attribute line in the meta-inf/manifest.inf manifest member of the form:
Main-Class: com.mindprod.bio.Biorhythms
Of course, the class selected must have a public static main method. You can use the jar -m option to add that text to your manifest from a main.mft file containing text like this:
Main-Class: com.mindprod.bio.Biorhythms
Watch out for extraneous lead/trailing spaces or extraneous trailing .class. You must have a trailing linefeed or the main.mft file.

You can also specify the classpath, but you cannot specify command line parameters or system properties in the manifest.

Manifest Class-Path:

In Java version 1.3 or later there is an analogous manifest entry to let you control the classpath. It is used to specify optional jars that will be downloaded only if needed. Normally you would also place a Jar-index of these files in your main jar to help the loader decide which ones need to be loaded.
If you have multiple secondary jars, you must specify them in the manifest Class-Path entry of the master jar. It won’t do you any good to specify them in the SET CLASSPATH environment parameter or on the java.exe -classpath parameter.
Class-Path: myplace/myjar.jar myplace/other.jar jardir/
Note how the elements are separated by space, not semicolon or colon as on the command line.
The elements might be absolute or relative URL s, but I have not done experiments or found any documentation that describes what they are relative to. I presume the main jar. It could be the code base of the root jar file. It could be the CWD (Current Working Directory). If you figure it out, please let me know.

According to Oracle’s JWS (Java Web Start) FAQ (Frequently Asked Questions), in  Java version 1.5, Java Web Start still does not support Class-Path. There was a report that up until Java version 1.5, java.exe too ignored this entry, however, there is another report it has always worked fine. Class-Path is tricky to use, possibly leading to the erroneous report. Note the list is space-separated, not semicolon-separated as in the SET CLASSPATH=C:\;. Note also that only relative directories and jar names are permitted using / not \. They are relative to the containing jar. You cannot use C:\. Note also that directory names need to terminate (but not begin) with a /. This is because Class-Path has to be platform-independent.

Note that jars always ignore the SET classpath and even the command line classpath. These other two classpaths are in no way merged with the manifest Class-Path.

If you use -jar on the java.exe command line, java.exe will quietly ignore the set environment classpath and any -classpath or -cp command line options. What are you to do if you have additional jars to include?

  1. Copy them to the ext directory
  2. Mention them in the Class-Path: manifest entry. If you mention them in the manifest, you must specify the jars in relative URL form e.g. myplace/myjar.jar and you must separate them by spaces, not the usual Windows semicolons or Linux colons. You may only use relative URL s, so drive letters are not permitted. The jar Class-Path will also be used for Applets.
  3. In JDK version 1.4.2+ Mention these jars in a manifest extension list and they will be downloaded if needed, e. g.
    Extension-List: activation mail
    activation-Extension-Name: javax.activation
    activation-Implementation-URL: http://abc.com/activation.jar
    mail-Extension-Name: javax.mail
    mail-Implementation-URL: http://abc.com/mail.jar
  4. When Java goes searching for classes, it recursively searches the tree of jars mentioned in the various Class-Path entries in the already included jars. So you could create a dummy jar whose sole purpose was to provide a list of other jars to search.

Writing To Jars

To write or update the Jar file, normally you use the jar.exe utility. Since jars are just zip files with extra members, you can also use ZIP utilities such as PKZIP and WinZip.

You can also read and write the jar files from Java with the ZipEntry, ZipException, ZipFile, ZipInputStream and ZipOutputStream classes. While a jar is in use, some OS (Operating System) ’s may lock it, so don’t count on being able to update jars on the fly when you are executing classes from them.

Gotchas

It is easy to forget to include everything you need to make a jar totally self contained. Sometimes jar will work on your machine because all the classes are otherwise available. However, they won’t work on your client’s machine. This is such a hassle I have written an entire separate essay on dependencies, how to make sure you include everything you need in your jar — your classes, all the classes they use and all the classes they in turn use.

You have a similar problem with packing zip files of classes and source.

When you recompile, naturally this does not magically update all the jars in the world. Similarly when you build a jar, jar.exe will happily include out of date class files that really should have been recompiled. Make sure everything, including classes from other packages have been freshly compiled before building your jar. Here is my plan for preparing a distribution jar:

  1. Delete all class files in all vaguely related packages to ensure all are recompiled with official -targets and that all class files match the current source.
  2. Recompile the class you are planning to distribute. That will force a recompile of classes it uses in other packages. By looking all over for class files you will see what the dependencies are.
  3. Recompile and rejar the other packages to incorporate any of the distributed classes.
  4. When you are debugging, it is often nice not to use jars. Then, so long as a class is on the classpath it will be found. You don’t have to keep careful track of the classes you use to put in the jar until your program is stable.

Sealing

A package within a jar file can be optionally sealed, which means that all classes defined in that package must be archived in the same jar file. You might want to seal a package to prevent tampering, or to prevent accidental use of classes outside the original set.

To seal a package, you need to add a Name header for the package to your manifest, followed by a Sealed header, like this:

Name: com/mindprod/myPackage/
Sealed: true

Nesting

The member files in a zip file can be accessed individually, just like the files in a jar file (a species of zip file). However, when one zip is contained within another zip, you can only access the contained zip file itself, not its individual members. You would need to expand it to disk somewhere before accessing its members.

There are three approaches to the problem:

  1. Put all members in the same jar/zip.
  2. Use several individual jar files and arrange to have them on the path.
  3. Use a JWS installer class to unpack a nested jar into individual jars.

Jars on the Mac

You create jars on the Mac with the Jar Bundler, (not jar.exe). It creates and includes an XML (extensible Markup Language) file called Info.plist that behaves something like a JNLP (Java Network Launching Protocol) file does for a Java Web Start App.

Learning More

Oracle’s Javadoc on JarFile class : available:
Oracle’s Javadoc on JarEntry class : available:
Oracle’s Javadoc on JarInputStream class : available:
Oracle’s Javadoc on JarOutputStream class : available:
Oracle’s Javadoc on Pack200 class : available:

This page is posted
on the web at:

http://mindprod.com/jgloss/jar.html

Optional Replicator mirror
of mindprod.com
on local hard disk J:

J:\mindprod\jgloss\jar.html
Canadian Mind Products
Please the feedback from other visitors, or your own feedback about the site.
Contact Roedy. Please feel free to link to this page without explicit permission.

IP:[65.110.21.43]
Your face IP:[44.222.149.13]
You are visitor number