Draft Page for the Debian-Java Coordination
Policy changes summary
Java virtual machines
This adds a new paragraph to the policy for a rules for java virtual machines.
- A runtime MUST use /usr/share/java/ext if they provide classloader extention.
- A runtime MAY search in futher other directories.
- To enable the use of virtual machine extension libraries for all runtimes installed in Debian (which support extension directories) one directory where these libraries are symlinked into is needed.
- Beside that runtimes are free to search other maybe runtime specific directories.
Chapter 2: Policy
Virtual packages are created: java-jre, java-jdk and classpath-jre, classpath-jdk (to be decided).
All Java code must be shipped as Java bytecode (*.class files, packaged in a *.jar archive) and with "Architecture: all".
Packages written in Java are separated in two categories: programs and libraries. Programs are intended to be run by end-users. Libraries are intended to help programs to run and to be used by developers.
Both are shipped as Java bytecode (*.class files, packaged in a *.jar archive) and with an "Architecture: all" since Java bytecode is supposed to be portable. It may additionally be shipped as BC (binary compatible) compiled machine code, as produced by the GNU Compiler for Java, in a separate architecture-specific package.
Chapter 2.1: Virtual Machines
Java virtual machines MUST depend on java-common. GNU classpath derived virtual machine MUST provide classpath-jre and if they provide development tools (replacements for javac, javadoc, rmic etc) also provide classpath-jdk. Non-free JDKs MUST provide java-jre (if they are a runtime) and java-sdk (if they also provide development tools).
They should use /etc/alternatives for the name 'java' if they are command-line compatible with the Sun's java program. The same should be done for every other compatible tool included in the runtime (e.g. rmiregistry) or development (e.g. javadoc) package.
They should have a CLASSPATH predefined which include the needed runtime environment.
Some Java classes implement their routines using a "native" language (such as C). This native code is compiled and stored in dynamic libraries (such as JNI modules) that are loaded at runtime. If a virtual machine supports native code, it must include the directory /usr/lib/jni in its search path for these dynamic libraries.
Every runtime MUST use /usr/share/java/ext if they provide an extension classloader to look for extension libraries, but MAY look into additional directories.
Chapter 2.4: Java libraries
Libraries are not separated between developers (-dev) and users versions, since this is meaningless in Java.
Java libraries packages must be named libXXX[version]-java (without the brackets), where the version part is optional and should only contain the necessary part. The version part should only be used to avoid naming collisions. The XXX part is the actual package name used in the text below.
Their classes must be in jar archive(s) in the directory /usr/share/java, with the name packagename[-extraname]-fullversion.jar. The extraname is optional and used internally within the package to separate the different jars provided by the package. The fullversion is the version of that jar file. In some cases that is not the same as the package version.
Some package must also provide a symbolic link from packagename-extraname.jar to the most compatible version of the available packagename-extraname-version.jar files.
All jar files must have a well-documented CLASSPATH, so that developers should know what to add to their wrappers.
Some Java libraries rely on code written in a "native" language, such as JNI (Java Native Interface) code. This native code is compiled into separate dynamic libraries which are loaded by the Java virtual machine at runtime. If a Java library relies on native code, the dynamic libraries containing this compiled native code should be installed into the directory /usr/lib/jni. These dynamic libraries should be shipped in a separate architecture-specific package named libXXX[version]-jni. The package containing the Java bytecode (generally libXXX[version]-java) MUST depend on this package. (I here changed should into a MUST - wbaer) (I (avdyk) am open to discussion about this, but if you need the library for development, you don't need the jni part that's why I'd kept the SHOULD and I wouldn't change it to a MUST).
There may be situations, such as with very small packages, where it is better to bundle the Java code and the native code together into a single package. Such packages should be architecture-specific and follow the usual libXXX[version]-java naming convention. The jar files be placed into /usr/share/java.
For certain cases, there is some Java code that depends on the architecture (currently only the SWT libraries). Architecture dependend jars MUST be placed in /usr/lib/java. Very few java packages belong to this category. Before uploading an architecture dependend package a packager MUST ask on email@example.com and reach a concensus.
Java libraries MUST be built with debug symbols on and MUST NOT depend on any runtime.
Javadoc SHOULD be build for java libraries. If Javadoc is generated it MUST be build against and linked to the classpath documentation (classpath-doc) and all its dependend java libraries. The resulting documentation MUST be placed in /usr/share/doc/<package>/api (name to be decided) and MUST be registered with doc-base. The javadoc package (libXXX[version]-java-doc) MUST depend on classpath-doc and other doc packages from the dependend java libraries. Small java library packages, where the documentation is not sepearted in an own package, MUST only recommend the document packages.
JUnit tests SHOULD be enabled but MUST not lead to a failing build if failures/errors occur.
There is the possibility to build a binary compatible (BC) native package of a java library. As this is not usefull to do for every package and every architecture supported by Debian a packager MUST ask on firstname.lastname@example.org first and we MUST reach to a concensus.
Native libraries need to be compiled with the default GCJ version and put into /usr/lib/gcj-$version. This can be done by using aot-compile helper script. To make these native libraries accessible to GCJ you need to create a classmap db for these libraries in /usr/share/gcj-$version/classmap.d/. To make it easy for GCJ to access these classmaps they are all merged into one master db file located in /var/lib/gcj-$version/classmap.db. This is done by calling update-gcj-classmaps in the postinst and postrm scripts if the script is installed.
For packages using debhelper there is a debhelper script called dh_nativejava which compiles the jar files included in the package to native, creates the classmap file for them and adds the needed calls to update-gcj-classmaps to the postinst and postrm scripts.
Currently the default version of GCJ in Debian is 4.1.
Chapter 3: Issues to be discussed
Cleaned up, added webapps packaging topic (wbaer)
- The following points are discussions about the policy, either because they have to be studied more, or are controversial.
- All jars must have a good CLASSPATH documentation, but how should it be documented. The best solution is probably in some computer parsable format to make it even easier for the developer. It should exist some tool to parse this. How should it work? Should the tool also be used to create the necessary symbolic links needed by servlets under tomcat?
- How to check for a good enough jvm, and to select a proper one to use. Are /etc/alternatives not good enough?
- Java Webapps packaging policy/recommendations
Chapter 4. Advices to Java packagers
- Warning: These are just advices, they are not part of the policy.
- Be sure to manage all dependencies by hand in debian/control. Debian development tools cannot find them automatically like they do with C programs and libraries.
- You can suppress many calls in debian/rules which are meaningless for Java, like dh_strip and dh_shlibdeps.
- Source package handling is painful, since most Java upstream programs come with .class files and dependend libraries. Packages going into main must be cleaned so there is no binary stuff without source in the package.
- Java properties files are probably better under /etc and flagged as configuration files (this will be integrated in the policy, one day).
- Java packages SHOULD be build with java-gcj-compat-dev if possible (unless missing features).