MANIFEST.MF and INDEX.LIST

M

Mistake

Hello everybody,

I've just spent some hours (late hours) fighting against the classpath
in JAR archives, the MANIFEST.MF file and the INDEX.LIST file.

I just want to mention together some of the information I gathered
through internet (and tested on my own). They may be useful to someone
else. I'm not completely sure to have understood everything, though.

1. You can't launch a Java application using the "java" command, and
using both the -jar (specifies a jar file) option and the -cp
(specifies a classpath) option. They're mutually exclusive. If you use
the -jar option, then the -cp is completely ignored.

2. You can add a 'Class-Path' entry in the manifest file, MANIFEST.MF
file (see http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html). But
you have to be very cautious with it. Several rules apply in the way
you specify your class path:
- Class-Path line can't be longer than 72 chars (nice one).
- You can break a classpath line into several, but you have to make
the line separation as CR[space][space] (see
http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4295946)
- All classpath entries are relatives to the jar archive containing
the manifest.
- A single dot '.' stands for the folder where the jar archive is
placed:
- Classpaths are separated by ' ' (one space).
- The classpath line must be finished by a carriage return (CR, LF,
or CRLF).

3. If there is a INDEX.LIST besides the MANIFEST.MF, then the class
path specified in the manifest is ignored. This can happen if some of
the jar libraries included in your jar have this INDEX.LIST file. When
you build your jar, you have to break up all jar libraries, and
recompile them into one big fat jar. Some (undesirable?) INDEX.LIST may
pop out to the META-INF folder.

The last point took me some time to figure out. In my case, the culprit
was mysql-connector-java-3.1.11-bin.jar.

Regards,
Mistake
 
T

Thomas Weidenfeller

Mistake said:
1. You can't launch a Java application using the "java" command, and
using both the -jar (specifies a jar file) option and the -cp
(specifies a classpath) option. They're mutually exclusive. If you use
the -jar option, then the -cp is completely ignored.

Which is well documented, but java users typically prefer to ignore that
part of the documentation and learn it the hard way.

http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/java.html#-jar
2. You can add a 'Class-Path' entry in the manifest file, MANIFEST.MF
file (see http://java.sun.com/j2se/1.3/docs/guide/jar/jar.html).

Why are you using such an ancient Java version?
But
you have to be very cautious with it. Several rules apply in the way
you specify your class path:
- Class-Path line can't be longer than 72 chars (nice one).

Which is well documented.
http://java.sun.com/j2se/1.5.0/docs/guide/jar/jar.html
- You can break a classpath line into several, but you have to make
the line separation as CR[space][space] (see
http://bugs.sun.com/bugdatabase/view_bug.do;:WuuT?bug_id=4295946)
- All classpath entries are relatives to the jar archive containing
the manifest.
- A single dot '.' stands for the folder where the jar archive is
placed:
- Classpaths are separated by ' ' (one space).
- The classpath line must be finished by a carriage return (CR, LF,
or CRLF).

All documented. The [space][space] issue is tricky, but also documented.
It allows to break single long pathes over multiple lines without
accidentally inserting a space in the path.
3. If there is a INDEX.LIST besides the MANIFEST.MF, then the class
path specified in the manifest is ignored.

No, the manifest is initially used to create an index by the jar tool.
There is a bug in jar, which manifests itself in the way that index
entries are created with an absolute path instead of a relative one, but
that problem is easy to circumvent.
the jar libraries included in your jar have this INDEX.LIST file. When
you build your jar, you have to break up all jar libraries, and
recompile them into one big fat jar.

No. This is often claimed, but not true. The default class loader can't
load jars from a jar (which is well documented), but that does in no way
mean one has to unpack and repack all jars (with stupid tools like
FatJar). Setting the Class-Path in the main jar and deploying multiple
jars (probably via JWS) works well.

There are people who claim they have written "jar-in-jar" class loaders.
I haven't seen a working one.
Some (undesirable?) INDEX.LIST may
pop out to the META-INF folder.

Index files in secondary (other than the main jar) jars are ignored.
Please submit a bug report to sun if you have a reproducible example
demonstrating otherwise.
The last point took me some time to figure out. In my case, the culprit
was mysql-connector-java-3.1.11-bin.jar.

The culprit was likely your attempt to build a "fat" jar.

/Thomas
 
Joined
Sep 20, 2006
Messages
7
Reaction score
0
FatJar

As an experienced text editor-and-Ant-on-Linux kind of Java programmer who recently gave in to learning to be productive with Eclipse, I have to put in a good word for the FatJar Eclipse plugin. I'll be the first to agree that every Java programmer should read and understand the Jar spec, and should be able to compose a Jar and manifest that refers to other Jars, etc. However, for daily work (especially for desktop apps), give FatJar a try. Its jar-in-jar classloader works just fine, and in many cases like this, it simplifies your life as a programmer/packager/deployment admin.

In my first experience with it, my app has over a dozen utiltity jars and multiple resource files which resolve to one double-clickable executable jar. No manually mucking about in the Manifest.mf, no arcane batch scripts to set the classpath, a single file to distribute, what could be better? I previously would have written the Ant scripts to build it, and may have even written something to update the batch script or manifest. However, I have to admit that FatJar/Eclipse is faster and more reliable.

It won't always be appropriate. Sometimes you might need the libraries physically broken out. Also, it is not a magic bullet -- you still have to know what's going on. For example, I have resources not underneath the working directory, and therefore they require an explicit classpath addition. You have to remember to set that when you run the FatJar Wizard (or else launch the app with java -cp instead of java -jar). The FatJar plugin saves the settings, so you only have to do it once. Otherwise, your Eclipse project probably has references of some sort to the supporting libraries you need, and therefore FatJar knows about them, too, and includes them by default. Exclicitly exclude the projects/libraries/classes you don't want, like your unit tests. The plugin will even spit out an Ant build script equivalent if that makes you happy.

Bottom line: it works fine, took me moments to learn (more or less intuitively), and I didn't have to recall most (or any) of the Jar spec details (yes, I've read it) revisited in this thread. Automation is good.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top