I've recently become a DD and would like to help with Java packaging in
Debian. In particular, I am available to sponsor Java packages (I know from
experience that sponsors are hard to find) and I would like to help with the
Java policy and Java packaging tools in Debian.
The Java sub-policy is quite old and there are a number of changes proposed
both on the wiki and in the BTS[2,3,4,5,6]. Is there any progress in
adopting any of those suggestions?
From my experience of packaging a few Java programs and
libraries[8,9,10] I have a number of suggestions which I would like to
see adopted. Some of these are mentioned in the previous proposed
changes and some of which aren't.
- As #395372, Java policy should not restrict executables to /usr/bin, but
to anywhere which policy would normally allow (I would probably put
salliere in /usr/games/)
- #227594 suggests removing the section about binfmt_misc and class files.
I agree with this; using binfmt_misc for class files is a bad idea.
Only trivial applications are single class files with no classpath.
However, I think that executable jars with binfmt_misc are sensible.
To that end I have written and uploaded jarwrapper which registers
with binfmt_misc and will run executable jars. I also have two packages
which use it to execute their main classes. In order to do this it does
- check it's a jar through zip magic and presence of a manifest
- if $JAVA is set, use that otherwise use whatever is `java' in $PATH
- set LD_LIBRARY_PATH and -Djava.library.path to /usr/lib/jni
- run with -jar $JAR.
We may want to change it to only use a specific VM rather than depending
on alternatives, I have not yet decided which is best.
This works when the jar file has no dependencies outside the system
library, or when the jar manifest contains a Class-Path: element.
These are loaded recursively, so see my next point.
I propose that Java policy 2.3 is changed to the following:
Programs must have executable(s) in a location complient with the FHS
2.3 (See Policy 9.1.1). These must either be a wrapper script or a
symlink to an executable jar under /usr/share/java in which case they
must depend on jarwrapper and have a Main-Class attribute in the jar
Manifest. In any case, they must run without specific environment
variables (see Policy 10.9), for instance CLASSPATH. They must respect
the Policy rules for executables (for instance a manual page per
executable, see Policy 13.1).
All Java bytecode for programs must be provided in a jar file in
/usr/share/java. The name of the jar should follow the same naming
conventions as for libraries.
Programs must depend on java-virtual-machine and the needed runtime
environment (java1-runtime and/or java2-runtime).
There is no naming rules for programs, they are ordinary programs,
from the user point of view.
For this to happen there are a number of changes. Lintian needs to be
updated to recognise executable jars. For the other change see my
- Policy should mandate that all jars include the Class-Path: attribute in
their Manifest files. Reasoning:
- At the moment all programs need to know recursively all the jars
which they will use. This introduces unnecessary transitions when a
library changes it's dependencies, more work for packagers writing
wrappers scripts, and long classpath lines in them.
- Tricks such as the executable jars proposed above cannot work
without them and would stop many people having to write wrapper
scripts. In fact, -jar doesn't work at all without a Class-Path
attribute as -cp is ignored, so we can't make use of the Main-Class
- It would allow automated dependency creation tools in the same vein
as dh_shlibdeps rather than writing them by hand. (see below)
I propose that Java policy 2.4 have:
All jar files must have a well-documented CLASSPATH, so that
developers should know what to add to their wrappers.
All jar files must have a Manifest containing a Class-Path attribute
listing the jars on which they depend.
and the same added to section 2.3.
- As per #448286, either we should use section libs for all libraries (not
devel) or a new section java should be created (preferred). In etch there
are 154 binary packages with a name ending in -java, most or all of which
would be candidates for this new section. Unstable matches 338 binary
packages containing -java and 172 source packages. Policy should be
updated to match this.
- #363165 mentions the version number in jar names. The parallel with C
libraries is .so name. When compiling the symlink is use and at runtime
the versioned symbol is used. This seems like something which could be
adopted by Java; packaging tools should be able to set the Class-Path
attribute to whichever version the symlink is currently pointing to.
This is, of course, only useful if a change in version number indicates an
incompatible version and you can have multiple versions installed at once.
I already have done one transition (fortunately no packaged rdeps then)
which would have benefitted from being able to do this. I think this would
be a good direction to go it, but obviously is a big change in policy and
requires some discussion.
- Developer tools. Some tools were proposed on the mailing list . There
are definitely a number of developer tools which we should mention in
policy and have available.
- I wrote a program for calculating dependencies automatically
which I have already mentioned on this list. The current version of
it works by using the Class-Path in the Manifest of each jar. This
depends on a package using that attribute to be useful (but see my
previous point), but if they do then it will correctly determine the
Depends: for each binary package. It can also be extended to add a
dependency on jarwrapper if the package contains executable jars.
- If we do something with versioned symbols as above a tool would
be needed for creating Class-Path attributes.
- Possibly a Java version of pkg-config might be useful for finding
jar paths in an automatic way
I'm sure there are some other useful tools which I'm happy to help with
writing if people think of them.
I hop this will lead to some interesting discussions and some useful improvements to the way Java works in Debian.
Matthew Johnson wrote:
> - #363165 mentions the version number in jar names. The parallel with C
> libraries is .so name.
No, our version numbers are very different - they are upstream release
numbers, whereas sonames are ABI versions.
> When compiling the symlink is use and at
> runtime the versioned symbol is used.
> could be adopted by Java; packaging tools should be able to set the
> Class-Path attribute to whichever version the symlink is currently
> pointing to.
I think this would be very nice, _if_ we could solve it for ABI versioning.
If we did this using the upstream version numbers, we would be creating
hard dependencies on specific versions, which would be a disaster.
(The current situation is of course also really dangerous - we just package
any version and hope it will be compatible for all dependent packages
forever. When something breaks we notice that a library needs to be
updated, so we update it and hope the update doesn't break more stuff...)
> This is, of course, only useful if a change in version number
> indicates an incompatible version and you can have multiple versions
> installed at once.
We can only have multiple upstream versions in the archive if there are ABI
changes and both are needed.
To UNSUBSCRIBE, email to debian-java-REQUEST@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact firstname.lastname@example.org