Debian Java Packaging

Current way

/usr/bin/java is a alternative, but is mostly not used in packaging, as it tends to be unreliable it can be anything.... Most package have something like this

|test -n JAVA_HOME && JAVA="${JAVA_HOME}/bin/java"

There are some virtual packages, but all they guarantee are that the underlying command is there, not that is able to run a package.

Packages install their JARs in /usr/share/java, once versioned and once without symlink. JNI libraries so are going to /usr/lib/jni and all JVMs are required to include that dir in the library path.

The current Debian Java policy can be found at

Proposed Debian Java policy

Goals are, that Java package work out of the box, without requiring environment variables which is actually forbidden by Debian Policy or additional configuration.

Therefore the virtual package should be replaced by concrete dependencies on each 'known working' JVM. To make choosing a JVM from that pool easier, 'findjava' is introduced to find a installed one from that pool. It has features server-mode, etc to choose the JVM based on features and user preference. It also introduces a way to overwrite the pool and so test a different JVM or use a JVM outside of the packaging system.

The interface between JVM and findjava is a java config file, which describes the JVM and which is placed in /usr/share/java-config/ and named after the package.

JVMs are still required to include /usr/lib/jni in their library search path.

Another goal is to make CLASSPATH issues as robust and easy as possible. Therfore java-config was introduce, which outputs a classpath compatible list of jars for a given list of package names. Dependecies are taken in account, as well as 'contributed' classpath entries for plugin systems.

This way one information is needed to setup the packages and the corresponding classpath. As it is on package level, the package manager should ensure that all dependencies are satisfied. dh_java is a tool that translates the information for the 'Depends:' line in debian/control and the java-config file that is used at runtime. It also builds the list of included jars.

Different version of one library/app should be installable:

Unversioned jar files are not needed anymore. As you depend on one package name, the jar file is either clear package, which use symlink to place the jars in different directories or taken from the java-config interface.

At buildtime, ant should be used and therefore the interface is names 'ant-environment'. It defines JAVA_HOME and a BOOTCLASSPATH and a build.compiler and if required the jars that are needed by this build comiler. The only requirement is that ant can handle it. Again, the descripton of that environment is handled via a java-config file. The goal is to make one 'cdbs' Common Debian Build System makefile snippit, which would only take the names of the ant environments and the rest will be made automatically.

One drawback of this proposal is that it is not perfect. There is currently no way to handle JVM requirements of libraries, so for example when libA is used by appB and libA was currently able to work with a certain JVM, but stops doing that, appB still will take that JVM if is installed. This is especially harmful in a plugin environment plugin stops working with the JVM, but app never knows. I have no idea how that could be handled.

Requirements for a common build system:

You can find my proposal and the source for all mentioned tools at (Dead link)

On debian system you can install the package from <pre> deb -> install new-java-policy </pre> (Dead link)

A text version of the new policy is available in the wishlist bugreport: