Java Developer Guide

Background
Before going into details of how Java is handled on Gentoo, please make sure you have read and are aware of the Gentoo Java Packaging Policies and also the Gentoo Java User Guide. This guide will not cover such, but will cover more specific details on Gentoo Java Ebuilds.

Java on Gentoo
This section will give you more insight into how Gentoo handles Java. You should be familiar with the Java User Guide before proceeding.

Virtual machines (VMs)
As discussed in the User Guide, there are several VMs available from portage.

Testing all packages to ensure they build and run with every VM is a huge undertaking, and there simply are not enough resources to guarantee every package will build and run with every VM.

We now maintain a list of "supported virtual machines" for each architecture. These are the VMs we will test the packages against before committing changes to portage. When you emerge a package, it will by default try to use the best "supported virtual machine."

Of course, Gentoo and Linux in general are about choice, so if you prefer a different VM over the "supported virtual machines", you can easily use that VM instead. However, you should also know that bugs reported with one of the non-"supported virtual machine" will get a low priority if it isn't present using a "supported virtual machine".

Configuring which VM to use
You can choose which VM to use on a per-user basis, and which VM to use for the system (ie when running things as root). Both of these are configured using java-config.

A user's current VM is represented by a symlink located at. This symlink points to the JAVA_HOME of the chosen VM. Similarly, the system VM is represented by a symlink at.

The current VM can also be changed on the fly. This can be accomplished setting the environment GENTOO_VM to contain the name of a VM that java-config knows about.

Java tools
The traditional Java tools, ie,, , , etc, are all located in. They are actually all symlinks to the script. This script will call the appropriate tool, depending on how the script is invoked, from the current VM. The contents of the GENTOO_VM variable is checked first, then the user VM, and lastly the system VM.

Build-time VM switching
As outlined in the User Guide, and mentioned briefly earlier, the VM will switch at build time to accommodate the needs of the package. The VM to use is first determined by JAVA_PKG_FORCE_VM, then , and lastly the system VM.

Bytecode compatibility
The default behavior of is to compile bytecode that will compatible with the current VM version and higher (ie forward compatible). It is possible to specify which VM to compile for to provide the best compatibility.

At build time, the DEPEND and RDEPEND variables will determine what VM to compile for based on and. Additionally, this can be controlled by the environment variables JAVA_PKG_WANT_SOURCE and JAVA_PKG_WANT_TARGET.

There is a wrapper for, , which will use the appropriate VM's , and then specify the appropriate  and. For projects that use ant, the can be translated to specify the appropriate   and.

Filesystem layout
In general, the directory policies are handled for you by the helper functions in the java-utils-2 eclass.

These functions adhere to the following path name conventions:


 * contains information about the package.
 * files created from source code are installed to
 * pre-built files not compiled by the ebuild are installed to
 * Javadoc documentation is installed to
 * Source archives are installed to
 * User-executable scripts are installed to
 * System-wide environment files are in installed to
 * User-specific environment files can be put into

Dependencies
When depending on a package, take care that you depend on a sufficiently recent version, and explicitly ensure at building time that the providing package gives you the correct interface, i.e. the correct SLOT.

General guidelines
In addition to standard Gentoo ebuild guidelines, there are a number specific for Java packages:


 * In RDEPEND, use ">=virtual/jre-[minimal-version]". If you need a JDK for normal operation, like used to, then you should use ">=virtual/jdk-[minimal-version]". The jre atom MUST have a version.
 * In DEPEND, use ">=virtual/jdk-[minimal-version]", unless the ebuild is not compiling source. The jdk atom MUST have a version.
 * For packages that use Ant to build, try to DEPEND on just when possible instead of . dev-java/ant-core is automatically added to DEPEND if you inherit java-ant-2. If the package makes use of 'optional' ant tasks, you'll need to DEPEND on dev-java/ant or add WANT_ANT_TASKS="ant-task" before inherit. The latter is of course preferred. see the Ant Guide for details.
 * For packages that are distributed as zip, you need to DEPEND on to unpack
 * Avoid using bundled files at all costs for source-based packages. Instead, they should use system installed versions with the help of our eclass functions.
 * If you only need the path to installed libraries, you can use java-pkg_getjar(s). Don't call java-config directly, because it will not be recorded as a dependency in the package env.
 * Always provide an easily understandable reason after 'die', so that end-users will provide the maintainers with sensible feedback if the build should fail.
 * Avoid cluttering up the environment by adding environment files to . Instead, store your env file in, and then have user scripts source its environment file when it launches. Otherwise, developers, who regularly override CLASSPATH , CATALINA_HOME and other environment variables, will have problems running regular apps. If you use the launcher it will also automatically source the appropriate env file.
 * Make sure you always compile with correct a source/target. This is important to ensure future and backwards compatibility. If the packages use ant, this can be done for you automatically. See java-ant-2.eclass. If not you will have to patch it to pass $(java-pkg_javac-args) to.
 * Do no install jars which contain versions in their filename, ie . Use java-pkg_newjar to rename and install versioned jars to not contain the version in their filename.

Dependencies
Gentoo Java ebuild dependencies for the most part are just like any other ebuild. There are two common dependencies that will always exist for any Java ebuild, no matter if Java is optional or not. Though if Java is optional, the dependencies would be conditional based on a USE flag, likely  USE flag. There are some packages which may require a JDK at runtime, otherwise most should have a JRE for runtime.

While it is not required, you will commonly see a dependency variable that is used in both  and. This variable name is not mandated and is usually  or   for anything that will go in both   and. This is not really Java specific but is very common in most if not all Java ebuilds.

Preparing sources
Gentoo Java ebuilds do not and should never use the normal  and   but instead use its own , unless the package has optional java support. There are some cases where you might need to use  with , but this is very rare. Within, along with doing the normal patching and other things you might need to do in order to prepare the sources. It is policy and practice to always remove any bundled class and/or jar files that came with the package sources. Which is one of the first things you do for any Java package, regardless of optional Java support or not.

There are a few ways to go about removing bundled classes and jars such as;,  ,  , and they can be used together.

Replacing Removed Bundled Jars
There are some build systems that require jars to be in certain locations. Per Gentoo Java Packaging Policy and the previous section those jars have now been removed. They need to be replaced using symlinks to system jars to let the build system proceed without further modification. This is mostly a legacy way of doing things, as most build systems will look for jars on the classpath.

Compiling
There are couple common ways to compile full Java packages on Gentoo using either eant or java-pkg-simple eclass functions and variables.

eant
eant is a Gentoo wrapper around ant. One should never invoke ant directly in an ebuild, but instead call eant. Though even calling eant is unnecessary in most packages with ant build systems, and should not be done. Instead eant function can be controlled with global variables in the ebuild. Using such one can omit the entire  section in most cases.

USE flags
If a manual or other extensive documentation is available, it should be installed using the doc USE flag. If the build system can, you should build javadocs also using the doc USE flag. If it does not, you should consider patching it to do so, and provide the patch upstream. HTML documentation should be installed using dohtml and javadocs using java-pkg_dojavadoc.

If the program provides examples, in the form of source code or some other format, and you think they may be worthwhile for some users to have, install them optionally with the examples use flag using the java-pkg_doexamples function.

If you want to go all the way, add the source USE flag that installs the complete source code as a file. Use java-pkg_dosrc for this purpose. This allows IDEs such as Eclipse and NetBeans to do complete source-level debugging. You will need to also DEPEND="source? ( app-arch/zip )" or add JAVA_PKG_IUSE="source" before inherit. Using JAVA_PKG_IUSE means that we can remove the requirement in the future and use for example jar provided by.

If your package comes with unit tests, you can enable these using the test FEATURE, in src_test. If you need extra dependencies for the testing you can pull these in with the test useflag (for example ). We will no longer use the junit use flag for this.

Typical examples
Without further ado, here are a few examples: