java library installation issues
I'd like to make some progress on standard Linux/GNU installation
standards for Java, and how GCJ fits into this.
This could lead to an updated Debian Java policy (which is
at http://people.debian.org/~bortz/Java/policy.html) and ultimately
be part of a future Linux File Hierarchy Standard.
Currently, libgcj.jar is installed in $prefix/share and libgcj.so
is in $prefix/lib. This is not compatible with the Debian policy,
which suggests jar files should be in $prefix/share/java.
First, let's just consider portable (non-Java-implementation-specific)
bytecode packages. Should these be installed as a .jar file or a
collection of .class files?
The main argument for a collection of .class files is simplicity:
* Multiple independent packages can all install in the same "Java root",
and compilers and VMs can find them by just setting the builtin
CLASSPATH to include this "Java root".
* It is fast to find the correct .class file, given it's fully-qualified
name. No need to search the through many .jar files. (Note that .jar
files contain a directory at the end, so searching a .jar file only
means reading this directory.)
The advantages for .jar files:
* The Java standard seems to be .jar files. This is what Sun uses for
both the core libraries, and for Java "extensions". You install a
.jar file in the appropriate extensions directory, and it is available
to all.
* Compressed .jar saves diskspace. They probably save time, given that
reading from a .jar would need less disk activity than reading
multiple separate class files. This is less clear, because you may
have to search the directories on many irrelevant .jar files.
* .jar files can have meta-information (such as MANIFEST).
* Many Java libraries come as .jar files. It is inconvenient to
have to unzip them before installation.
I propose the policy is should be to prefer using .jar files. When
using Gcj, the extra searching through multiple .jar files is not a
big issue, since the ,jar files are only used at compile time.
(See below.)
So where should be put the .jar files? I suggest leaving this as
/usr/share/java. However, we should add Java-implementation
sub-directories. We could also support the "repository" feature
mentioned the Policy, but without the explicit repository directory.
So to summarize: The builtin search path should be (in this order):
(1) each .jar file in /usr/share/java/$implementation
(2) each .jar file in /usr/share/java
(3) the /usr/share/java directory itself
As an example, libgcj.jar should be installed as
/usr/share/java/gcj/libgcj.jar. Something like Ant should be
installed as /usr/share/java/ant.jar.
I've left out versioning issues. If one want to support multiple
versions of the same library one could install LIBRARY-VERSION.jar,
and install a symlink from LIBRARY.jar, but having compilers and
VMs pick the right version is unclear to me.
Now on to Gcj. For a package or application to "support" Gcj,
its build procedure should build both a .jar and a pre-compiled
.so file, and install both. The .jar file should be installed
in /usr/share/java unless it depends on Gcj. If there can be
a version that is gcj-specific or -optimized, it should be in
/usr/share/java/gcj. For example, the library could be configured
to not use AWT when running on Gcj. In that case the generic
version would be installed in /usr/share/java and the AWT-less version
in /usr/share/java/gcj.
Where should .so be installed? The obvious location is /usr/lib.
However, I'm wondering whether it might be better to separate out
Java libraries in a separate directory for two reasons:
(1) reduce clutter in /usr/lib
(2) reduce risk of library name clashes.
So I would suggest /usr/lib/gcj for .so files. In that case the
gcj command should add /usr/lib/gcj to the list of directories to
search at run-time, with an ld -rpath command.
The final piece of magic I suggest: When the compiler compiles
a Java class A and emits a reference to a class B (the class
itself, a static method, or a static field of B), and B was
found in L.jar in the builtin search path, then the compiler
should check if there is a file /usr/lib/gcj/L.so. If so,
it should emit whatever magic is needed s that the linker
searches L.so (at both ld and run-time-linke times).
With this setup:
(1) All Java compilers and VMs can compile find all "installed" .jars,
without users having to fiddle with classpaths.
(2) Java applications compiled with gcj automatically find the
necessary ,so files, without the users having to explicitly list
them on the gcj command line.
--
--Per Bothner
per@bothner.com http://www.bothner.com/~per/
Reply to: