diff --git a/doc/languages-frameworks/java.section.md b/doc/languages-frameworks/java.section.md index 371bdf6323fb..0ce1442cca68 100644 --- a/doc/languages-frameworks/java.section.md +++ b/doc/languages-frameworks/java.section.md @@ -4,12 +4,31 @@ Ant-based Java packages are typically built from source as follows: ```nix stdenv.mkDerivation { - name = "..."; + pname = "..."; + version = "..."; + src = fetchurl { ... }; - nativeBuildInputs = [ jdk ant ]; + nativeBuildInputs = [ + ant + jdk + stripJavaArchivesHook # removes timestamp metadata from jar files + ]; - buildPhase = "ant"; + buildPhase = '' + runHook preBuild + ant # build the project using ant + runHook postBuild + ''; + + installPhase = '' + runHook preInstall + + # copy generated jar file(s) to an appropriate location in $out + install -Dm644 build/foo.jar $out/share/java/foo.jar + + runHook postInstall + ''; } ``` @@ -17,6 +36,10 @@ 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`. +Also note that not using `stripJavaArchivesHook` will likely cause the +generated `.jar` files to be non-deterministic, which is not optimal. +Using it, however, does not always guarantee reproducibility. + 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 diff --git a/pkgs/applications/blockchains/bisq-desktop/default.nix b/pkgs/applications/blockchains/bisq-desktop/default.nix index 8e6881f0d7e8..31c044f39c61 100644 --- a/pkgs/applications/blockchains/bisq-desktop/default.nix +++ b/pkgs/applications/blockchains/bisq-desktop/default.nix @@ -9,7 +9,7 @@ , dpkg , writeScript , bash -, strip-nondeterminism +, stripJavaArchivesHook , tor , zip , xz @@ -50,7 +50,7 @@ stdenv.mkDerivation rec { dpkg imagemagick makeWrapper - strip-nondeterminism + stripJavaArchivesHook xz zip findutils @@ -89,7 +89,6 @@ stdenv.mkDerivation rec { tar --sort=name --mtime="@$SOURCE_DATE_EPOCH" -cJf native/linux/x64/tor.tar.xz tor tor_jar_file=$(find ./opt/bisq/lib/app -name "tor-binary-linux64-*.jar") zip -r $tor_jar_file native - strip-nondeterminism ./opt/bisq/lib/app/*.jar ''; installPhase = '' diff --git a/pkgs/applications/misc/calcoo/default.nix b/pkgs/applications/misc/calcoo/default.nix index 5f90b4bb2363..462b56d50ce0 100644 --- a/pkgs/applications/misc/calcoo/default.nix +++ b/pkgs/applications/misc/calcoo/default.nix @@ -2,7 +2,7 @@ , stdenv , fetchzip , ant -, canonicalize-jars-hook +, stripJavaArchivesHook , jdk , makeWrapper }: @@ -18,7 +18,7 @@ stdenv.mkDerivation (finalAttrs: { nativeBuildInputs = [ ant - canonicalize-jars-hook + stripJavaArchivesHook jdk makeWrapper ]; diff --git a/pkgs/applications/misc/mkgmap/default.nix b/pkgs/applications/misc/mkgmap/default.nix index ee0c2043a6b4..7f97818c7452 100644 --- a/pkgs/applications/misc/mkgmap/default.nix +++ b/pkgs/applications/misc/mkgmap/default.nix @@ -6,6 +6,7 @@ , jre , ant , makeWrapper +, stripJavaArchivesHook , doCheck ? true , withExamples ? false }: @@ -30,10 +31,6 @@ stdenv.mkDerivation rec { ]; postPatch = with deps; '' - # Fix the output jar timestamps for reproducibility - substituteInPlace build.xml \ - --replace-fail ' build/classes/mkgmap-version.properties << EOF @@ -61,7 +58,7 @@ stdenv.mkDerivation rec { '') testInputs} ''; - nativeBuildInputs = [ jdk ant makeWrapper ]; + nativeBuildInputs = [ jdk ant makeWrapper stripJavaArchivesHook ]; buildPhase = '' runHook preBuild diff --git a/pkgs/applications/misc/mkgmap/splitter/default.nix b/pkgs/applications/misc/mkgmap/splitter/default.nix index 010b140e9bf9..801af789d47d 100644 --- a/pkgs/applications/misc/mkgmap/splitter/default.nix +++ b/pkgs/applications/misc/mkgmap/splitter/default.nix @@ -6,6 +6,7 @@ , jre , ant , makeWrapper +, stripJavaArchivesHook , doCheck ? true }: let @@ -30,10 +31,6 @@ stdenv.mkDerivation rec { ]; postPatch = with deps; '' - # Fix the output jar timestamps for reproducibility - substituteInPlace build.xml \ - --replace-fail ' build/classes/splitter-version.properties << EOF @@ -58,7 +55,7 @@ stdenv.mkDerivation rec { '') testInputs} ''; - nativeBuildInputs = [ jdk ant makeWrapper ]; + nativeBuildInputs = [ jdk ant makeWrapper stripJavaArchivesHook ]; buildPhase = '' runHook preBuild diff --git a/pkgs/applications/misc/pattypan/default.nix b/pkgs/applications/misc/pattypan/default.nix index aac0da8b4c40..c1f5aa84b0eb 100644 --- a/pkgs/applications/misc/pattypan/default.nix +++ b/pkgs/applications/misc/pattypan/default.nix @@ -7,7 +7,7 @@ , wrapGAppsHook , makeDesktopItem , copyDesktopItems -, canonicalize-jars-hook +, stripJavaArchivesHook }: stdenv.mkDerivation (finalAttrs: { @@ -27,7 +27,7 @@ stdenv.mkDerivation (finalAttrs: { makeWrapper wrapGAppsHook copyDesktopItems - canonicalize-jars-hook + stripJavaArchivesHook ]; dontWrapGApps = true; diff --git a/pkgs/applications/networking/remote/dayon/default.nix b/pkgs/applications/networking/remote/dayon/default.nix index a68a6eddd334..ea46ec131fbc 100644 --- a/pkgs/applications/networking/remote/dayon/default.nix +++ b/pkgs/applications/networking/remote/dayon/default.nix @@ -6,7 +6,7 @@ , jre , makeWrapper , copyDesktopItems -, canonicalize-jars-hook +, stripJavaArchivesHook }: stdenv.mkDerivation (finalAttrs: { @@ -25,7 +25,7 @@ stdenv.mkDerivation (finalAttrs: { jdk makeWrapper copyDesktopItems - canonicalize-jars-hook + stripJavaArchivesHook ]; buildPhase = '' diff --git a/pkgs/applications/office/jameica/default.nix b/pkgs/applications/office/jameica/default.nix index 683d51bf43f2..66d2a80c5555 100644 --- a/pkgs/applications/office/jameica/default.nix +++ b/pkgs/applications/office/jameica/default.nix @@ -4,6 +4,7 @@ , makeDesktopItem , makeWrapper , wrapGAppsHook +, stripJavaArchivesHook , ant , jdk , jre @@ -46,13 +47,7 @@ stdenv.mkDerivation rec { hash = "sha256-MSVSd5DyVL+dcfTDv1M99hxickPwT2Pt6QGNsu6DGZI="; }; - postPatch = '' - # Fix jar timestamps for reproducibility - substituteInPlace build/build.xml \ - --replace-fail '/dev/null - # -q|--quiet, -r|--recurse-paths - # -o|--latest-time: canonicalizes overall archive mtime - # -X|--no-extra: don't store platform-specific extra file attribute fields - @zip@ -qroX "$outer/tmp-out.jar" . 2> /dev/null - popd 2>/dev/null - rm -rf "$input-tmp" - mv "$outer/tmp-out.jar" "$input" -} - -# See also the Java specification's JAR requirements: -# https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html#Notes_on_Manifest_and_Signature_Files -canonicalizeJarManifest() { - local input='' - input="$(realpath -sm -- "$1")" - (head -n 1 "$input" && tail -n +2 "$input" | sort | grep -v '^\s*$') > "$input-tmp" - mv "$input-tmp" "$input" -} diff --git a/pkgs/build-support/setup-hooks/canonicalize-jars.sh b/pkgs/build-support/setup-hooks/canonicalize-jars.sh deleted file mode 100644 index 5137bfc94b01..000000000000 --- a/pkgs/build-support/setup-hooks/canonicalize-jars.sh +++ /dev/null @@ -1,16 +0,0 @@ -# This setup hook causes the fixup phase to repack all JAR files in a -# canonical & deterministic fashion, e.g. resetting mtimes (like with normal -# store files) and avoiding impure metadata. - -fixupOutputHooks+=('if [ -z "$dontCanonicalizeJars" -a -e "$prefix" ]; then canonicalizeJarsIn "$prefix"; fi') - -canonicalizeJarsIn() { - local dir="$1" - echo "canonicalizing jars in $dir" - dir="$(realpath -sm -- "$dir")" - while IFS= read -rd '' f; do - canonicalizeJar "$f" - done < <(find -- "$dir" -type f -name '*.jar' -print0) -} - -source @canonicalize_jar@ diff --git a/pkgs/build-support/setup-hooks/strip-java-archives.sh b/pkgs/build-support/setup-hooks/strip-java-archives.sh new file mode 100644 index 000000000000..22322468f76d --- /dev/null +++ b/pkgs/build-support/setup-hooks/strip-java-archives.sh @@ -0,0 +1,16 @@ +# This setup hook makes the fixup phase to repack all java archives in a +# deterministic fashion. The most important change being done is the resetting +# of the modification times of the archive entries + +fixupOutputHooks+=('stripJavaArchivesIn $prefix') + +stripJavaArchivesIn() { + local dir="$1" + echo "stripping java archives in $dir" + find $dir -type f -regextype posix-egrep -regex ".*\.(jar|war|hpi|apk)$" -print0 | + while IFS= read -rd '' f; do + echo "stripping java archive $f" + strip-nondeterminism --type jar "$f" + done +} + diff --git a/pkgs/by-name/jo/jogl/package.nix b/pkgs/by-name/jo/jogl/package.nix index 3919ee1e0e0f..5157fe679771 100644 --- a/pkgs/by-name/jo/jogl/package.nix +++ b/pkgs/by-name/jo/jogl/package.nix @@ -5,6 +5,7 @@ , jdk11 , git , xmlstarlet +, stripJavaArchivesHook , xcbuild , udev , xorg @@ -42,13 +43,6 @@ stdenv.mkDerivation { substituteInPlace gluegen/src/java/com/jogamp/common/util/IOUtil.java \ --replace-fail '#!/bin/true' '#!${coreutils}/bin/true' '' - # set timestamp of files in jar to a fixed point in time - + '' - xmlstarlet ed --inplace \ - --append //jar --type attr -n modificationtime --value 1980-01-01T00:00Z \ - gluegen/make/{build.xml,gluegen-cpptasks-base.xml} \ - jogl/make/{build.xml,build-nativewindow.xml,build-jogl.xml} - '' # prevent looking for native libraries in /usr/lib + '' substituteInPlace jogl/make/build-*.xml \ @@ -72,6 +66,7 @@ stdenv.mkDerivation { jdk11 git xmlstarlet + stripJavaArchivesHook ] ++ lib.optionals stdenv.isDarwin [ xcbuild ]; diff --git a/pkgs/development/compilers/abcl/default.nix b/pkgs/development/compilers/abcl/default.nix index e36d8975e26b..317d0d92266d 100644 --- a/pkgs/development/compilers/abcl/default.nix +++ b/pkgs/development/compilers/abcl/default.nix @@ -6,7 +6,7 @@ , jdk , jre , makeWrapper -, canonicalize-jars-hook +, stripJavaArchivesHook }: let @@ -30,7 +30,7 @@ stdenv.mkDerivation (finalAttrs: { jdk fakeHostname makeWrapper - canonicalize-jars-hook + stripJavaArchivesHook ]; buildPhase = '' diff --git a/pkgs/development/compilers/jasmin/default.nix b/pkgs/development/compilers/jasmin/default.nix index db58f48b97bb..685e6aa9537e 100644 --- a/pkgs/development/compilers/jasmin/default.nix +++ b/pkgs/development/compilers/jasmin/default.nix @@ -5,7 +5,7 @@ , ant , jdk8 , makeWrapper -, canonicalize-jars-hook +, stripJavaArchivesHook , callPackage }: @@ -27,7 +27,7 @@ in stdenv.mkDerivation (finalAttrs: { ant jdk makeWrapper - canonicalize-jars-hook + stripJavaArchivesHook ]; buildPhase = '' diff --git a/pkgs/development/libraries/freetts/default.nix b/pkgs/development/libraries/freetts/default.nix index 698a7f6a28ac..ec948f1fdccc 100644 --- a/pkgs/development/libraries/freetts/default.nix +++ b/pkgs/development/libraries/freetts/default.nix @@ -4,6 +4,7 @@ , ant , jdk8 , sharutils +, stripJavaArchivesHook }: stdenv.mkDerivation (finalAttrs: { @@ -20,16 +21,11 @@ stdenv.mkDerivation (finalAttrs: { ant jdk8 sharutils + stripJavaArchivesHook ]; sourceRoot = "${finalAttrs.src.name}/freetts-${finalAttrs.version}"; - postPatch = '' - # Fix jar timestamps for reproducibility - substituteInPlace build.xml demo.xml \ - --replace-fail '