15 ensureNewerSourcesForZipFilesHook,
51 nixpkgs-openjdk-updater,
53 # TODO(@sternenseemann): gtk3 fails to evaluate in pkgsCross.ghcjs.buildPackages
54 # which should be fixable, this is a no-rebuild workaround for GHC.
55 headless ? lib.versionAtLeast featureVersion "21" && stdenv.targetPlatform.isGhcjs,
67 .${featureVersion} or (throw "JavaFX is not supported on OpenJDK ${featureVersion}"),
81 "8" = temurin-bin-8.__spliced.buildBuild or temurin-bin-8;
82 "11" = temurin-bin-11.__spliced.buildBuild or temurin-bin-11;
83 "17" = temurin-bin-17.__spliced.buildBuild or temurin-bin-17;
84 "21" = temurin-bin-21.__spliced.buildBuild or temurin-bin-21;
85 "23" = temurin-bin-23.__spliced.buildBuild or temurin-bin-23;
91 sourceFile = ./. + "/${featureVersion}/source.json";
92 source = nixpkgs-openjdk-updater.openjdkSource {
94 featureVersionPrefix = tagPrefix + featureVersion;
97 atLeast11 = lib.versionAtLeast featureVersion "11";
98 atLeast17 = lib.versionAtLeast featureVersion "17";
99 atLeast21 = lib.versionAtLeast featureVersion "21";
100 atLeast23 = lib.versionAtLeast featureVersion "23";
102 tagPrefix = if atLeast11 then "jdk-" else "jdk";
103 version = lib.removePrefix "refs/tags/${tagPrefix}" source.src.rev;
104 versionSplit = builtins.match (if atLeast11 then "(.+)+(.+)" else "(.+)-b(.+)") version;
105 versionBuild = lib.elemAt versionSplit 1;
107 # The JRE 8 libraries are in directories that depend on the CPU.
114 x86_64-linux = "amd64";
115 aarch64-linux = "aarch64";
116 powerpc64le-linux = "ppc64le";
118 .${stdenv.system} or (throw "Unsupported platform ${stdenv.system}");
120 jdk-bootstrap' = jdk-bootstrap.override {
121 # when building a headless jdk, also bootstrap it with a headless jdk
122 gtkSupport = !headless;
126 assert lib.assertMsg (lib.pathExists sourceFile)
127 "OpenJDK ${featureVersion} is not a supported version";
129 stdenv.mkDerivation (finalAttrs: {
130 pname = "openjdk" + lib.optionalString headless "-headless";
137 ++ lib.optionals (!atLeast11) [
141 inherit (source) src;
147 ./21/patches/fix-java-home-jdk21.patch
148 else if atLeast11 then
149 ./11/patches/fix-java-home-jdk10.patch
151 ./8/patches/fix-java-home-jdk8.patch
155 ./11/patches/read-truststore-from-env-jdk10.patch
157 ./8/patches/read-truststore-from-env-jdk8.patch
160 ++ lib.optionals (!atLeast23) [
163 ./11/patches/currency-date-range-jdk10.patch
165 ./8/patches/currency-date-range-jdk8.patch
168 ++ lib.optionals atLeast11 [
171 ./17/patches/increase-javadoc-heap-jdk13.patch
173 ./11/patches/increase-javadoc-heap.patch
176 ++ lib.optionals atLeast17 [
179 ./21/patches/ignore-LegalNoticeFilePlugin-jdk18.patch
181 ./17/patches/ignore-LegalNoticeFilePlugin-jdk17.patch
184 ++ lib.optionals (!atLeast21) [
187 ./17/patches/fix-library-path-jdk17.patch
188 else if atLeast11 then
189 ./11/patches/fix-library-path-jdk11.patch
191 ./8/patches/fix-library-path-jdk8.patch
194 ++ lib.optionals (atLeast17 && !atLeast23) [
195 # -Wformat etc. are stricter in newer gccs, per
196 # https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79677
197 # so grab the work-around from
198 # https://src.fedoraproject.org/rpms/java-openjdk/pull-request/24
200 url = "https://src.fedoraproject.org/rpms/java-openjdk/raw/06c001c7d87f2e9fe4fedeef2d993bcd5d7afa2a/f/rh1673833-remove_removal_of_wformat_during_test_compilation.patch";
201 sha256 = "082lmc30x64x583vqq00c8y0wqih3y4r0mp1c4bqq36l22qv6b6r";
204 ++ lib.optionals (featureVersion == "17") [
205 # Patch borrowed from Alpine to fix build errors with musl libc and recent gcc.
206 # This is applied anywhere to prevent patchrot.
208 url = "https://git.alpinelinux.org/aports/plain/community/openjdk17/FixNullPtrCast.patch?id=41e78a067953e0b13d062d632bae6c4f8028d91c";
209 sha256 = "sha256-LzmSew51+DyqqGyyMw2fbXeBluCiCYsS1nCjt9hX6zo=";
212 ++ lib.optionals atLeast11 [
213 # Fix build for gnumake-4.4.1:
214 # https://github.com/openjdk/jdk/pull/12992
216 name = "gnumake-4.4.1";
217 url = "https://github.com/openjdk/jdk/commit/9341d135b855cc208d48e47d30cd90aafa354c36.patch";
218 hash = "sha256-Qcm3ZmGCOYLZcskNjj7DYR85R4v07vYvvavrVOYL8vg=";
221 ++ lib.optionals (!headless && enableGtk) [
224 ./17/patches/swing-use-gtk-jdk13.patch
225 else if atLeast11 then
226 ./11/patches/swing-use-gtk-jdk10.patch
228 ./8/patches/swing-use-gtk-jdk8.patch
234 depsBuildBuild = [ buildPackages.stdenv.cc ];
240 ++ lib.optionals atLeast11 [
243 ++ lib.optionals (!atLeast11) [
245 # Certificates generated using perl in `installPhase`
252 # Probably for BUILD_CC but not sure, not in closure.
255 ++ lib.optionals atLeast21 [
256 ensureNewerSourcesForZipFilesHook
261 # TODO: Many of these should likely be in `nativeBuildInputs`.
263 # `-lmagic` in NIX_LDFLAGS
268 ++ lib.optionals (atLeast11 && !atLeast21) [
276 ++ lib.optionals atLeast11 [
285 ++ lib.optionals (!atLeast11) [
291 ++ lib.optionals atLeast11 [
304 ++ lib.optionals (!headless && enableGtk) [
305 (if atLeast11 then gtk3 else gtk2)
309 propagatedBuildInputs = lib.optionals (!atLeast11) [ setJavaClassPath ];
311 nativeInstallCheckInputs = lib.optionals atLeast23 [
315 # JDK's build system attempts to specifically detect
316 # and special-case WSL, and we don't want it to do that,
317 # so pass the correct platform names explicitly
318 ${if atLeast17 then "configurePlatforms" else null} = [
323 # https://openjdk.org/groups/build/doc/building.html
326 "--with-boot-jdk=${jdk-bootstrap'.home}"
327 # https://github.com/openjdk/jdk/blob/471f112bca715d04304cbe35c6ed63df8c7b7fee/make/autoconf/util_paths.m4#L315
328 # Ignoring value of READELF from the environment. Use command line variables instead.
329 "READELF=${stdenv.cc.targetPrefix}readelf"
330 "AR=${stdenv.cc.targetPrefix}ar"
331 "STRIP=${stdenv.cc.targetPrefix}strip"
332 "NM=${stdenv.cc.targetPrefix}nm"
333 "OBJDUMP=${stdenv.cc.targetPrefix}objdump"
334 "OBJCOPY=${stdenv.cc.targetPrefix}objcopy"
339 "--with-version-string=${version}"
340 "--with-vendor-version-string=(nix)"
342 else if atLeast11 then
343 lib.optionals atLeast17 [
344 "--with-version-build=${versionBuild}"
345 "--with-version-opt=nixos"
348 "--with-version-pre="
352 "--with-update-version=${lib.removePrefix "${featureVersion}u" (lib.elemAt versionSplit 0)}"
353 "--with-build-number=${versionBuild}"
354 "--with-milestone=fcs"
358 "--enable-unlimited-crypto"
359 "--with-native-debug-symbols=internal"
361 ++ lib.optionals (!atLeast21) (
364 "--with-freetype=system"
365 "--with-harfbuzz=system"
369 "--disable-freetype-bundling"
375 "--with-libjpeg=system"
376 "--with-giflib=system"
377 "--with-libpng=system"
384 "--with-giflib=system"
388 "--with-stdc++lib=dynamic"
390 ++ lib.optionals (featureVersion == "11") [
391 "--disable-warnings-as-errors"
393 # OpenJDK 11 cannot be built by recent versions of Clang, as far as I can tell (see
394 # https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=260319). Known to
395 # compile with LLVM 12.
396 ++ lib.optionals (atLeast11 && stdenv.cc.isClang) [
397 "--with-toolchain-type=clang"
398 # Explicitly tell Clang to compile C++ files as C++, see
399 # https://github.com/NixOS/nixpkgs/issues/150655#issuecomment-1935304859
400 "--with-extra-cxxflags=-xc++"
402 # This probably shouldn’t apply to OpenJDK 21; see
403 # b7e68243306833845cbf92e2ea1e0cf782481a51 which removed it for
404 # versions 15 through 20.
406 (featureVersion == "11" || featureVersion == "21") && stdenv.hostPlatform.isx86_64
407 ) "--with-jvm-features=zgc"
408 ++ lib.optional headless (if atLeast11 then "--enable-headless-only" else "--disable-headful")
409 ++ lib.optional (!headless && enableJavaFX) "--with-import-modules=${openjfx_jdk}";
411 buildFlags = if atLeast17 then [ "images" ] else [ "all" ];
413 separateDebugInfo = true;
415 # -j flag is explicitly rejected by the build system:
416 # Error: 'make -jN' is not supported, use 'make JOBS=N'
417 # Note: it does not make build sequential. Build system
418 # still runs in parallel.
419 enableParallelBuilding = false;
426 else if atLeast11 then
428 # `cc1plus: error: '-Wformat-security' ignored without '-Wformat' [-Werror=format-security]`
429 # when building jtreg
432 lib.concatStringsSep " " (
434 # glibc 2.24 deprecated readdir_r so we need this
435 # See https://www.mail-archive.com/openembedded-devel@lists.openembedded.org/msg49006.html
436 "-Wno-error=deprecated-declarations"
438 ++ lib.optionals stdenv.cc.isGNU [
439 # https://bugzilla.redhat.com/show_bug.cgi?id=1306558
440 # https://github.com/JetBrains/jdk8u/commit/eaa5e0711a43d64874111254d74893fa299d5716
442 "-fno-delete-null-pointer-checks"
447 # error by default in GCC 14
448 "-Wno-error=int-conversion"
449 "-Wno-error=incompatible-pointer-types"
453 NIX_LDFLAGS = lib.concatStringsSep " " (
454 lib.optionals (!headless) [
461 ++ lib.optionals (!headless && enableGtk) [
462 (if atLeast11 then "-lgtk-3" else "-lgtk-x11-2.0")
467 // lib.optionalAttrs (!atLeast11) {
468 # OpenJDK 8 Hotspot cares about the host(!) version otherwise
469 DISABLE_HOTSPOT_OS_VERSION_CHECK = "ok";
472 ${if atLeast23 then "versionCheckProgram" else null} = "${placeholder "out"}/bin/java";
474 ${if !atLeast11 then "doCheck" else null} = false; # fails with "No rule to make target 'y'."
476 doInstallCheck = atLeast23;
478 ${if atLeast17 then "postPatch" else null} = ''
480 patchShebangs --build configure
483 ${if !atLeast17 then "preConfigure" else null} =
486 substituteInPlace configure --replace /bin/bash "${bash}/bin/bash"
488 + lib.optionalString (!atLeast11) ''
489 substituteInPlace hotspot/make/linux/adlc_updater --replace /bin/sh "${stdenv.shell}"
490 substituteInPlace hotspot/make/linux/makefiles/dtrace.make --replace /usr/include/sys/sdt.h "/no-such-path"
497 mv build/*/images/${if atLeast11 then "jdk" else "j2sdk-image"} $out/lib/openjdk
499 # Remove some broken manpages.
500 rm -rf $out/lib/openjdk/man/ja*
502 # Mirror some stuff in top-level.
504 ln -s $out/lib/openjdk/include $out/include
505 ln -s $out/lib/openjdk/man $out/share/man
507 + lib.optionalString atLeast17 ''
509 # IDEs use the provided src.zip to navigate the Java codebase (https://github.com/NixOS/nixpkgs/pull/95081)
511 + lib.optionalString atLeast11 ''
512 ln -s $out/lib/openjdk/lib/src.zip $out/lib/src.zip
516 # jni.h expects jni_md.h to be in the header search path.
517 ln -s $out/include/linux/*_md.h $out/include/
519 # Remove crap from the installation.
520 rm -rf $out/lib/openjdk/demo${lib.optionalString (!atLeast11) " $out/lib/openjdk/sample"}
521 ${lib.optionalString headless (
524 rm $out/lib/openjdk/lib/{libjsound,libfontmanager}.so
528 rm $out/lib/openjdk/jre/lib/${architecture}/{libjsound,libjsoundalsa,libsplashscreen,libawt*,libfontmanager}.so
529 rm $out/lib/openjdk/jre/bin/policytool
530 rm $out/lib/openjdk/bin/{policytool,appletviewer}
534 + lib.optionalString (!atLeast11) ''
536 # Move the JRE to a separate output
537 mkdir -p $jre/lib/openjdk
538 mv $out/lib/openjdk/jre $jre/lib/openjdk/jre
539 mkdir $out/lib/openjdk/jre
540 lndir $jre/lib/openjdk/jre $out/lib/openjdk/jre
542 # Make sure cmm/*.pf are not symlinks:
543 # https://youtrack.jetbrains.com/issue/IDEA-147272
544 rm -rf $out/lib/openjdk/jre/lib/cmm
545 ln -s {$jre,$out}/lib/openjdk/jre/lib/cmm
547 # Setup fallback fonts
548 ${lib.optionalString (!headless) ''
549 mkdir -p $jre/lib/openjdk/jre/lib/fonts
550 ln -s ${liberation_ttf}/share/fonts/truetype $jre/lib/openjdk/jre/lib/fonts/fallback
553 # Remove duplicate binaries.
554 for i in $(cd $out/lib/openjdk/bin && echo *); do
555 if [ "$i" = java ]; then continue; fi
556 if cmp -s $out/lib/openjdk/bin/$i $jre/lib/openjdk/jre/bin/$i; then
557 ln -sfn $jre/lib/openjdk/jre/bin/$i $out/lib/openjdk/bin/$i
561 # Generate certificates.
563 cd $jre/lib/openjdk/jre/lib/security
565 perl ${./8/generate-cacerts.pl} $jre/lib/openjdk/jre/bin/keytool ${cacert}/etc/ssl/certs/ca-bundle.crt
570 ln -s $out/lib/openjdk/bin $out/bin
572 + lib.optionalString (!atLeast11) ''
573 ln -s $jre/lib/openjdk/jre/bin $jre/bin
574 ln -s $jre/lib/openjdk/jre $out/jre
581 # Propagate the setJavaClassPath setup hook so that any package
582 # that depends on the JDK has $CLASSPATH set up properly.
583 mkdir -p $out/nix-support
584 #TODO or printWords? cf https://github.com/NixOS/nixpkgs/pull/27427#issuecomment-317293040
585 echo -n "${setJavaClassPath}" > $out/nix-support/propagated-build-inputs
589 # Propagate the setJavaClassPath setup hook from the JRE so that
590 # any package that depends on the JRE has $CLASSPATH set up
592 mkdir -p $jre/nix-support
593 printWords ${setJavaClassPath} > $jre/nix-support/propagated-build-inputs
598 # Set JAVA_HOME automatically.
599 mkdir -p $out/nix-support
600 cat <<EOF > $out/nix-support/setup-hook
601 if [ -z "\''${JAVA_HOME-}" ]; then export JAVA_HOME=$out/lib/openjdk; fi
606 # Build the set of output library directories to rpath against
608 for output in $(getAllOutputNames); do
609 if [ "$output" = debug ]; then continue; fi
610 LIBDIRS="$(find $(eval echo \$$output) -name \*.so\* -exec dirname {} \+ | ${
611 if atLeast17 then "sort -u" else "sort | uniq"
612 } | tr '\n' ':'):$LIBDIRS"
614 # Add the local library paths to remove dependencies on the bootstrap
615 for output in $(getAllOutputNames); do
616 if [ "$output" = debug ]; then continue; fi
617 OUTPUTDIR=$(eval echo \$$output)
618 BINLIBS=$(find $OUTPUTDIR/bin/ -type f; find $OUTPUTDIR -name \*.so\*)
619 echo "$BINLIBS" | while read i; do
620 patchelf --set-rpath "$LIBDIRS:$(patchelf --print-rpath "$i")" "$i" || true
621 patchelf --shrink-rpath "$i" || true
626 # TODO: The OpenJDK 8 derivation got this wrong.
627 disallowedReferences = [
628 (if atLeast11 then jdk-bootstrap' else jdk-bootstrap)
633 home = "${finalAttrs.finalPackage}/lib/openjdk";
634 inherit jdk-bootstrap;
635 inherit (source) updateScript;
637 // (if atLeast11 then { inherit gtk3; } else { inherit gtk2; })
638 // lib.optionalAttrs (!atLeast23) {
639 inherit architecture;
643 description = "Open-source Java Development Kit";
644 homepage = "https://openjdk.java.net/";
645 license = lib.licenses.gpl2Only;
647 with lib.maintainers;
652 ++ lib.teams.java.members;
653 mainProgram = "java";
660 ++ lib.optionals atLeast11 [
665 ++ lib.optionals atLeast17 [
668 # OpenJDK 8 was broken for musl at 2024-01-17. Tracking issue:
669 # https://github.com/NixOS/nixpkgs/issues/281618
670 # error: ‘isnanf’ was not declared in this scope
671 broken = !atLeast11 && stdenv.hostPlatform.isMusl;