1# Java {#sec-language-java} 2 3Ant-based Java packages are typically built from source as follows: 4 5```nix 6stdenv.mkDerivation { 7 name = "..."; 8 src = fetchurl { ... }; 9 10 nativeBuildInputs = [ jdk ant ]; 11 12 buildPhase = "ant"; 13} 14``` 15 16Note that `jdk` is an alias for the OpenJDK (self-built where available, 17or pre-built via Zulu). Platforms with OpenJDK not (yet) in Nixpkgs 18(`Aarch32`, `Aarch64`) point to the (unfree) `oraclejdk`. 19 20JAR files that are intended to be used by other packages should be 21installed in `$out/share/java`. JDKs have a stdenv setup hook that add 22any JARs in the `share/java` directories of the build inputs to the 23`CLASSPATH` environment variable. For instance, if the package `libfoo` 24installs a JAR named `foo.jar` in its `share/java` directory, and 25another package declares the attribute 26 27```nix 28buildInputs = [ libfoo ]; 29nativeBuildInputs = [ jdk ]; 30``` 31 32then `CLASSPATH` will be set to 33`/nix/store/...-libfoo/share/java/foo.jar`. 34 35Private JARs should be installed in a location like 36`$out/share/package-name`. 37 38If your Java package provides a program, you need to generate a wrapper 39script to run it using a JRE. You can use `makeWrapper` for this: 40 41```nix 42nativeBuildInputs = [ makeWrapper ]; 43 44installPhase = '' 45 mkdir -p $out/bin 46 makeWrapper ${jre}/bin/java $out/bin/foo \ 47 --add-flags "-cp $out/share/java/foo.jar org.foo.Main" 48''; 49``` 50 51Since the introduction of the Java Platform Module System in Java 9, 52Java distributions typically no longer ship with a general-purpose JRE: 53instead, they allow generating a JRE with only the modules required for 54your application(s). Because we can't predict what modules will be 55needed on a general-purpose system, the default jre package is the full 56JDK. When building a minimal system/image, you can override the 57`modules` parameter on `jre_minimal` to build a JRE with only the 58modules relevant for you: 59 60```nix 61let 62 my_jre = pkgs.jre_minimal.override { 63 modules = [ 64 # The modules used by 'something' and 'other' combined: 65 "java.base" 66 "java.logging" 67 ]; 68 }; 69 something = (pkgs.something.override { jre = my_jre; }); 70 other = (pkgs.other.override { jre = my_jre; }); 71in 72 ... 73``` 74 75You can also specify what JDK your JRE should be based on, for example 76selecting a 'headless' build to avoid including a link to GTK+: 77 78```nix 79my_jre = pkgs.jre_minimal.override { 80 jdk = jdk11_headless; 81}; 82``` 83 84Note all JDKs passthru `home`, so if your application requires 85environment variables like `JAVA_HOME` being set, that can be done in a 86generic fashion with the `--set` argument of `makeWrapper`: 87 88```bash 89--set JAVA_HOME ${jdk.home} 90``` 91 92It is possible to use a different Java compiler than `javac` from the 93OpenJDK. For instance, to use the GNU Java Compiler: 94 95```nix 96nativeBuildInputs = [ gcj ant ]; 97``` 98 99Here, Ant will automatically use `gij` (the GNU Java Runtime) instead of 100the OpenJRE.