Java
Ant-based Java packages are typically built from source as follows:
stdenv.mkDerivation {
name = "...";
src = fetchurl { ... };
nativeBuildInputs = [ jdk ant ];
buildPhase = "ant";
}
Note that jdk is an alias for the OpenJDK (self-built
where available, or pre-built via Zulu). Platforms with OpenJDK not (yet) in
Nixpkgs (Aarch32, Aarch64) point to the
(unfree) oraclejdk.
JAR files that are intended to be used by other packages should be installed
in $out/share/java. JDKs have a stdenv setup hook that
add any JARs in the share/java directories of the build
inputs to the CLASSPATH environment variable. For instance, if
the package libfoo installs a JAR named
foo.jar in its share/java
directory, and another package declares the attribute
buildInputs = [ libfoo ];
nativeBuildInputs = [ jdk ];
then CLASSPATH will be set to
/nix/store/...-libfoo/share/java/foo.jar.
Private JARs should be installed in a location like
$out/share/package-name.
If your Java package provides a program, you need to generate a wrapper
script to run it using the OpenJRE. You can use
makeWrapper for this:
nativeBuildInputs = [ makeWrapper ];
installPhase =
''
mkdir -p $out/bin
makeWrapper ${jre}/bin/java $out/bin/foo \
--add-flags "-cp $out/share/java/foo.jar org.foo.Main"
'';
Note the use of jre, which is the part of the OpenJDK
package that contains the Java Runtime Environment. By using
${jre}/bin/java instead of
${jdk}/bin/java, you prevent your package from depending
on the JDK at runtime.
Note all JDKs passthru home, so if your application
requires environment variables like JAVA_HOME being set, that
can be done in a generic fashion with the --set argument
of makeWrapper:
--set JAVA_HOME ${jdk.home}
It is possible to use a different Java compiler than javac
from the OpenJDK. For instance, to use the GNU Java Compiler:
nativeBuildInputs = [ gcj ant ];
Here, Ant will automatically use gij (the GNU Java
Runtime) instead of the OpenJRE.