From d4efa08b536d7dc500c2df45d7efa8087ca19557 Mon Sep 17 00:00:00 2001 From: Arnout Engelen Date: Sat, 19 Sep 2020 13:30:09 +0200 Subject: openjdk: add derivation to generate bespoke minimal JRE's Co-Authored-By: Robert Hensing --- doc/languages-frameworks/java.xml | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'doc/languages-frameworks/java.xml') diff --git a/doc/languages-frameworks/java.xml b/doc/languages-frameworks/java.xml index bf0fc488392..881d492b5bf 100644 --- a/doc/languages-frameworks/java.xml +++ b/doc/languages-frameworks/java.xml @@ -32,7 +32,7 @@ nativeBuildInputs = [ jdk ]; - 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: + If your Java package provides a program, you need to generate a wrapper script to run it using a JRE. You can use makeWrapper for this: nativeBuildInputs = [ makeWrapper ]; @@ -43,7 +43,21 @@ installPhase = --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. +Since the introduction of the Java Platform Module System in Java 9, Java distributions typically no longer ship with a general-purpose JRE: instead, they allow generating a JRE with only the modules required for your application(s). Because we can't predict what modules will be needed on a general-purpose system, the default jre package is the full JDK. When building a minimal system/image, you can override the modules parameter on jre_minimal to build a JRE with only the modules relevant for you: + +let + my_jre = pkgs.jre_minimal.override { + modules = [ + # The modules used by 'something' and 'other' combined: + "java.base" + "java.logging" + ]; + }; + something = (pkgs.something.override { jre = my_jre; }); + other = (pkgs.other.override { jre = my_jre; }); +in + ... + -- cgit 1.4.1 From 762e414d6af73e3b68afd40179d605e62e24d494 Mon Sep 17 00:00:00 2001 From: Jörg Thalheim Date: Sat, 28 Nov 2020 15:14:45 +0100 Subject: doc/java: convert to markdown --- doc/languages-frameworks/index.xml | 2 +- doc/languages-frameworks/java.section.md | 91 ++++++++++++++++++++++++++++++++ doc/languages-frameworks/java.xml | 77 --------------------------- 3 files changed, 92 insertions(+), 78 deletions(-) create mode 100644 doc/languages-frameworks/java.section.md delete mode 100644 doc/languages-frameworks/java.xml (limited to 'doc/languages-frameworks/java.xml') diff --git a/doc/languages-frameworks/index.xml b/doc/languages-frameworks/index.xml index 7da3321cb36..09f8695f41e 100644 --- a/doc/languages-frameworks/index.xml +++ b/doc/languages-frameworks/index.xml @@ -17,7 +17,7 @@ - + diff --git a/doc/languages-frameworks/java.section.md b/doc/languages-frameworks/java.section.md new file mode 100644 index 00000000000..77919d43f74 --- /dev/null +++ b/doc/languages-frameworks/java.section.md @@ -0,0 +1,91 @@ +# Java {#sec-language-java} + +Ant-based Java packages are typically built from source as follows: + +```nix +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 + +```nix +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 a JRE. You can use `makeWrapper` for this: + +```nix +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" +''; +``` + +Since the introduction of the Java Platform Module System in Java 9, +Java distributions typically no longer ship with a general-purpose JRE: +instead, they allow generating a JRE with only the modules required for +your application(s). Because we can't predict what modules will be +needed on a general-purpose system, the default jre package is the full +JDK. When building a minimal system/image, you can override the +`modules` parameter on `jre_minimal` to build a JRE with only the +modules relevant for you: + +```nix +let + my_jre = pkgs.jre_minimal.override { + modules = [ + # The modules used by 'something' and 'other' combined: + "java.base" + "java.logging" + ]; + }; + something = (pkgs.something.override { jre = my_jre; }); + other = (pkgs.other.override { jre = my_jre; }); +in + ... +``` + +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`: + +```bash +--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: + +```nix +nativeBuildInputs = [ gcj ant ]; +``` + +Here, Ant will automatically use `gij` (the GNU Java Runtime) instead of +the OpenJRE. diff --git a/doc/languages-frameworks/java.xml b/doc/languages-frameworks/java.xml deleted file mode 100644 index 881d492b5bf..00000000000 --- a/doc/languages-frameworks/java.xml +++ /dev/null @@ -1,77 +0,0 @@ -
- 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 a JRE. 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" - ''; - -Since the introduction of the Java Platform Module System in Java 9, Java distributions typically no longer ship with a general-purpose JRE: instead, they allow generating a JRE with only the modules required for your application(s). Because we can't predict what modules will be needed on a general-purpose system, the default jre package is the full JDK. When building a minimal system/image, you can override the modules parameter on jre_minimal to build a JRE with only the modules relevant for you: - -let - my_jre = pkgs.jre_minimal.override { - modules = [ - # The modules used by 'something' and 'other' combined: - "java.base" - "java.logging" - ]; - }; - something = (pkgs.something.override { jre = my_jre; }); - other = (pkgs.other.override { jre = my_jre; }); -in - ... - - - - - 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. - -
-- cgit 1.4.1