jar installation standards
Mon Feb 25 12:51:00 GMT 2002
I think the way we install jar files should be fixed for gcc 3.1.
The first problem is the installation directory. We install directly
into $prefix/share. The proposed Debian Java policy specifies
$prefix/share/java. I tend to think that is better. (I think
using $prefix/share is a holdover from when we installed .class files
rather than .jar files.)
Second, I'd like us to define some equivalent to Sun's "extensions"
mechanism. By this I mean some way that one can install a .jar, and
have that .jar be automatically be part of the default path. This
should happen at least for the gcj compiler itself. For run-time class
loading, I think we're more interested in locating the correct .so
rather than the correct .jar, and we have at least a partial solution
for the former. (Some packages may install a .jar and not a .so,
perhaps because the installation script isn't gcj-aware, but I think
we can have people fix their scripts instead.)
There are two approaches that appeal to me:
(1) Just add every .jar in $prefix/share/java to the implied
(boot-)classpath. I.e. we treat the directory like Sun treats
its extensions directory. The advantage is simplicity for
installers, users, plus compativility with Sun's model.
The disadvantage is that one could imagine hundreds of jars
being installed, and opening and reading the directory of each of
these could be slow. On the other hand, if we only need to do the
search at compile-time, perhaps its not a big deal. Plus we can use
some heuritcs, perhaps built into gcj, to only open a jar if we
think we might need it (e.g. after searching libgcj).
One complication is dealing with symlinks and versioning. If the
dirctory contains servlet-2.3.jar, servlet-2.1.jar, servlet-2.jar,
and servlet.jar (a symlink); the compiler should pick the least
specific one, i.e. servlet.jar, and skip the others.
(2) Use package-style names, similar to what we do for .so files.
The search algorithm when searching for class foo.bar.Baz:
- Search the user classpath.
- Search libgcj.jar.
- Look for foo-bar.jar; if found search it. Otherwise, look for
foo.jar, and if found search it. The compiler should explicitly
resolve symlinks (rather than have the OS do it) in case two symlinks
(eg foo-bar1.jar and foo.bar2.jar) point to the same file.
When installing a jar file, it should be installed as
PACKAGENAME-VERSION.jar (where PACKAGENAME means the package in the
"package manager" sense, not the Java sense), and then symlinks should
be added as appropriate. For example the servlet-api package should
probably be installed as (say) servlet-2.3.jar. We should add a
javax-servlet.jar symlink. If some other jar installs classes for
(say) javax.servlet.struts, it would need to add a symlink for
javax-servlet-stuts. We probably don'e need a symlink for
This approach is quite flexible in how classes are distributed
among jar file. It does assume that there isn't more than a
single jar containing classes from any given package (though
sub-packages are no problem). Even this can be handled using
an extension, for example a fake symlink that names to jars.
For example to indicate that both foo.jar and bar.jar need to
be searched for classes in javax.foo, one could do:
ln -s 'foo.jar baz.jar' javax-foo.jar
Advantages of this approach: Easy implementation when installing
jars (just add some symlinks). Easy implementation for compilers
and other tools that need to find classes, as described above.
Fast lookup that doesn't degrade (much) when many jars are installed.
Can co-exist with multiple versions of a jar without problem,
and applications that need a specific version can just just that
jar version explictly.
The main disadvantage is that this is a new "standard", different
from Sun's. If would really help if we can get this be part of a
GNU/Linux standard for Java. When I have discussed such issues
on the debian-java list, the people there have seen getting the
wrong version of a jar as being a bigger concern than the hassle
of having to explicitly specify claspaths. I think it it
important to be able to specify exampke which version you want,
but I want things to work without having to hack classpaths.
More information about the Java