Draft Page for the Debian-Java Coordination

FOSDEM 2006

Please do not edit this page unless you are wbaer, mandi or avdyk, thanks. We will send those proposal as java-common bug reports.

Policy changes summary

java libraries

  1. java libraries MUST be built with debug symbols on (do we do this for applications)
  2. java libraries MUST not depend on any runtime (effectivly we drop the runtime dependency)
  3. java libraries can go into main if they are buildable with free runtime

Rational behind this changes:

  1. Debug symbols are needed to track down problems in bug reports. Contrary to c++ turning debug on by default in java does not blow the libraries much in size.
  2. The dependency of a library on a specific runtime is just wrong. The question whether a certain runtime is needed only depends on the features of a library used. So it the right approach to drop runtime dependencies and make them only mandatory for programs where it is clear which parts of the used libraries are used and which runtime is really needed to run the program (and the used libraries parts) successfully.
  3. The criteria for moving to main is the ability to build with free runtimes. Running with free runtimes depends on the used parts. See above. So if effectivily a library is buildable with free runtime but fails to run one certain class/feature it still can go to main. This is to allow programs into main which depend on this library but do not use this specific feature and therefore run flawless with free runtimes. So we move the runtime dependencies to the programs.

gcj native

This adds a new paragraph to the policy for general rules if a library / program is compiled to native with the gcj BC API.

  1. Packager that wants to build package native MUST ask on debian-java@lists.debian.org and we MUST reach to a concensus.

  2. Packages that want to compile to native MUST Build-Depends on gcj-4.1. This package contains the excutable called aot-compile.
  3. Natively compiled jars MUST be put into the directory /usr/lib/gcj-4.1.
  4. Each debian package providing natively compiled jars MUST provide the according classmap file generated by aot-compile in /usr/share/gcj-4.1/classmap.d.
  5. Each debian package providing natively compiled jars MUST call update-gcj-classmaps in the postinst and postrm script (if update-gcj-classmaps exists).
  6. Debian packages SHOULD only be compiled to native on a selected set of architecturs

Note: Some of the infrastructure mentioned here does not exist yet in Debian unstable.

Rational:

  1. Building everything to native does not make sense at all. It must be discussed first which programs/libraries are making sense in the spirit of faster executions ...
  2. Building with older gcj versions creates incompatible native java libraries as the BC changed between 4.0 and 4.1.
  3. Its good to have a common directory layout on different platforms. Other distributions use this directory already and its conform to the FHS.
  4. We need a common directory for all classmap files to be able to merge them all when update-gcj-classmaps is run. This command merges them all into one master classmap db file.
  5. To be able to update the master classmap db all debian packages containing native java libraries the command update-gcj-classmaps to make sure the it is consistent.
  6. It doesn't really make sense to compile to native on all architectures supported by Debian. As the native libraries are quiet big and need to a long time to be build it only makes sense to provide them on "fast" architectures.

javadoc

This adds a new paragraph to the policy for general rules if javadoc is build for a library.

  1. Javadoc for libraries SHOULD be build.
  2. Generation must include and link against the dependend package classpath-doc and the other library documentation packages on the search path.
  3. If it's built, it MUST be in /usr/share/doc/<package>/api (or another directory, we must reach a concensus on this).

  4. It MUST be registered with doc-base,
  5. The -doc package MUST depend on classpath-doc and other library - doc packages. For small packages, where the javadoc is not in an own package, the other documentation packages may only be recommended.

Rational:

  1. We do not want to force javadoc generation but only encourage to do so.
  2. Javadoc is only usefull if it is linked and generated against used classes so one can hop between the api.
  3. To achive the above the javadoc must be put in a specified directory.
  4. To provide best possible integration with the documentation system.
  5. Without a dependency on the documentation packages links in the api doc would produce a file not found. However for small libraries without outsplitted documentation we cannot enforce the dependency on a 20 meg classpath-doc package.

arch deps java libs

For certain cases, there is some Java code that depends on the architecture. Then the location of the jars MUST be /usr/lib/java. Very few java packages goes to this category, before doing this, the packager MUST ask on debian-java@lists.debian.org and reach a concensus. This is for example the case for Eclipse SWT which stores native pointer in java types and uses int for that on 32 bit archs and long for 64 bit archs.

junit tests

This adds a new paragraph to the policy for general rules for enabling junit testsuites.

  1. JUnit tests SHOULD be enabled.
  2. Failing tests MUST not lead to a failing build.

Rational:

  1. We encourage to enable unit tests. However the enabling of unit tests sometimes is impractical (e.g. if it would depend on another binary testpackag) so we don't want to enforce it.
  2. Unit test may be wrong or a single test may fall do to mysterious reasons or real regressions.

Java virtual machines

This adds a new paragraph to the policy for a rules for java virtual machines.

  1. A runtime MUST use /usr/share/java/ext if they provide classloader extention.
  2. A runtime MAY search in futher other directories.

Rational:

  1. 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.
  2. Beside that runtimes are free to search other maybe runtime specific directories.

virtual packages

This describes the rework of the current virtual packages for java situation which has shown to be complete unusable nowadays.

  1. We drop all the current virtual packages for java (java*-runtime, java*-compiler, java-virtual-machine)
  2. We create virtual packages to different between non-free java platforms and GNU classpath based platforms. Further we differentiate between pure runtime environments and development environments. This leads to the following new virtual packages:
    • Free
      • JRE: classpath-jre
      • JDK: classpath-jdk
    • Non-Free
      • JRE: java-jre
      • JDK: java-jdk
  3. A package which depends on a particular non-free jre/jdk must depend exactly on this package and not on a virtual runtime e.g. j2re1.5-sun

Rational:

  1. The current differentiation based on Java and Java2 platform model from the past is completely unusable today. There are even no runtimes anymore packageable which would only provide the Java(1) model. java1-runtime and java2-runtime therefore is used since long to differentiate between free and non-free runtimes. We effectivly turn this practice into policy and give the virtual packages descriptive names. Futhermore the old java-compiler virtual package is today useless are far more tools needed for development exist. As a creation of a virtual package for each tools is overkill and all tools are almost always bundeled togethe in development packages this policy change does create such -jdk development virtual packages to represent every dev tool in java.
  2. See above.
  3. To not complicate the virtual package situation with respect to in certain time steps appearing new non-free runtimes we don't support virtual packages for specific versions of non-free runtime packages. As GNU classpath based runtimes are always on the same level in Debian there is no problem with them at all. We recognize that debian is about free software and we want to move java programs to the free runtimes (and believe its possible). So if currently or in the future a program needs a specific bleeding edge non-free runtime it has to depend on this package explicitly with the particular version and MUST NOT depend on a virtual package.

Best practice

This adds a new paragraph to the recommendations for packagers:

  1. Packages SHOULD build with java-gcj-compat-dev if possible.

Rational:

  1. java-gcj-compat-dev provides a complete free development environment based on gcj. As its based on gcj it is a stable environment for building with a good upstream trying to avoid any regressions in the fast moving free java target. Also if it is later decided to buid a native library for a specific package the build dependencies can stay the same. However Debian is about freedom and therefore we cannot and don't want to force a specific java build environment to the packagers - however we are encouraging them. Another point is that gcj is somewhat behind the other GNU classpath runtimes and some packages need newer class libraries to build than available in java-gcj-compat-dev.

Policy draft

Chapter 1: Background

unchanged

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.2: Java compilers

Removed - Reason: This is from the early day where compiler was something special. Know there are a lot of tools standard and would everyone would need there own virtual packages. Also current runtimes have the tools included in their packages so that a differentiation between runtime and development in the virtual machine virtual packages makes more sense.

Chapter 2.3: Java programs

Programs must have executable(s) in /usr/bin and be executable. They can be Java classes (using binfmt_misc) or wrappers. 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).

If they have their own auxiliary classes, they must be 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 the needed runtime/development environment (java-jre, java-jdk, classpath-jre, classpath-jdk). If a program needs a special version of a non-free runtime it MUST depend on this particular non-free jre(s) (e.g. j2re1.5) and MUST NOT depend on a virtual package.

There is no naming rules for programs, they are ordinary programs, from the user point of view.

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 debian-java@lists.debian.org and reach a concensus.

Java libraries MUST be built with debug symbols on and MUST NOT depend on any runtime.


later

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 debian-java@lists.debian.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 2.5: Main, contrib or non-free

About politics: packaging Java stuff changes nothing to the rules Debian uses to find if a program is free or not. Since there are not many free Java tools, keep in mind the following:

Chapter 3: Issues to be discussed

Cleaned up, added webapps packaging topic (wbaer)

Chapter 4. Advices to Java packagers


CategoryJava

Java/Draft (last edited 2009-03-16 03:31:23 by localhost)