diff --git a/.github/actions/build-jtreg/action.yml b/.github/actions/build-jtreg/action.yml index 0ba9937fb452..d00b297c1600 100644 --- a/.github/actions/build-jtreg/action.yml +++ b/.github/actions/build-jtreg/action.yml @@ -37,13 +37,13 @@ runs: - name: 'Check cache for already built JTReg' id: get-cached - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: jtreg/installed key: jtreg-${{ steps.version.outputs.value }} - name: 'Checkout the JTReg source' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: openjdk/jtreg ref: jtreg-${{ steps.version.outputs.value }} @@ -61,7 +61,7 @@ runs: if: (steps.get-cached.outputs.cache-hit != 'true') - name: 'Upload JTReg artifact' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: bundles-jtreg-${{ steps.version.outputs.value }} path: jtreg/installed diff --git a/.github/actions/do-build/action.yml b/.github/actions/do-build/action.yml index 6f2c2ce02180..6f6bbdabb687 100644 --- a/.github/actions/do-build/action.yml +++ b/.github/actions/do-build/action.yml @@ -66,7 +66,7 @@ runs: shell: bash - name: 'Upload build logs' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: failure-logs-${{ inputs.platform }}${{ inputs.debug-suffix }} path: failure-logs @@ -74,7 +74,7 @@ runs: # This is the best way I found to abort the job with an error message - name: 'Notify about build failures' - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: core.setFailed('Build failed. See summary for details.') if: steps.check.outputs.failure == 'true' diff --git a/.github/actions/get-bootjdk/action.yml b/.github/actions/get-bootjdk/action.yml index 312fb642c82b..d531358b7dd7 100644 --- a/.github/actions/get-bootjdk/action.yml +++ b/.github/actions/get-bootjdk/action.yml @@ -65,7 +65,7 @@ runs: - name: 'Check cache for BootJDK' id: get-cached-bootjdk - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: bootjdk/jdk key: boot-jdk-${{ inputs.platform }}-${{ steps.sha256.outputs.value }} diff --git a/.github/actions/get-bundles/action.yml b/.github/actions/get-bundles/action.yml index 270d15159a0c..2fd847f73d19 100644 --- a/.github/actions/get-bundles/action.yml +++ b/.github/actions/get-bundles/action.yml @@ -54,14 +54,14 @@ runs: steps: - name: 'Download bundles artifact' id: download-bundles - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }} path: bundles continue-on-error: true - name: 'Download bundles artifact (retry)' - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }} path: bundles @@ -69,7 +69,7 @@ runs: - name: 'Download static bundles artifact' id: download-static-bundles - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }}${{ inputs.static-suffix }} path: bundles diff --git a/.github/actions/get-gtest/action.yml b/.github/actions/get-gtest/action.yml index d38d33eabd84..b63bcbd302e6 100644 --- a/.github/actions/get-gtest/action.yml +++ b/.github/actions/get-gtest/action.yml @@ -40,7 +40,7 @@ runs: var: GTEST_VERSION - name: 'Checkout GTest source' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: repository: google/googletest ref: 'v${{ steps.version.outputs.value }}' diff --git a/.github/actions/get-jtreg/action.yml b/.github/actions/get-jtreg/action.yml index 4bb671d25d1b..470ab1a8b02e 100644 --- a/.github/actions/get-jtreg/action.yml +++ b/.github/actions/get-jtreg/action.yml @@ -41,7 +41,7 @@ runs: - name: 'Download JTReg artifact' id: download-jtreg - uses: actions/download-artifact@v4 + uses: actions/download-artifact@v8 with: name: bundles-jtreg-${{ steps.version.outputs.value }} path: jtreg/installed diff --git a/.github/actions/get-msys2/action.yml b/.github/actions/get-msys2/action.yml index d93b6e3763b2..e42b086dd3fd 100644 --- a/.github/actions/get-msys2/action.yml +++ b/.github/actions/get-msys2/action.yml @@ -31,7 +31,7 @@ runs: steps: - name: 'Install MSYS2' id: msys2 - uses: msys2/setup-msys2@v2.28.0 + uses: msys2/setup-msys2@v2.31.0 with: install: 'autoconf tar unzip zip make' path-type: minimal diff --git a/.github/actions/upload-bundles/action.yml b/.github/actions/upload-bundles/action.yml index 3e431b012685..707c809685aa 100644 --- a/.github/actions/upload-bundles/action.yml +++ b/.github/actions/upload-bundles/action.yml @@ -88,7 +88,7 @@ runs: shell: bash - name: 'Upload bundles artifact' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: bundles-${{ inputs.platform }}${{ inputs.debug-suffix }}${{ inputs.static-suffix }}${{ inputs.bundle-suffix }} path: bundles diff --git a/.github/workflows/build-alpine-linux.yml b/.github/workflows/build-alpine-linux.yml index 3dad8ee03b4e..6914f7126a08 100644 --- a/.github/workflows/build-alpine-linux.yml +++ b/.github/workflows/build-alpine-linux.yml @@ -74,7 +74,7 @@ jobs: steps: - name: 'Checkout the JDK source' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: 'Install toolchain and dependencies' run: | diff --git a/.github/workflows/build-cross-compile.yml b/.github/workflows/build-cross-compile.yml index 522da22e1bb3..1ca5c2452996 100644 --- a/.github/workflows/build-cross-compile.yml +++ b/.github/workflows/build-cross-compile.yml @@ -94,7 +94,7 @@ jobs: steps: - name: 'Checkout the JDK source' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: 'Get the BootJDK' id: bootjdk @@ -122,7 +122,7 @@ jobs: - name: 'Check cache for sysroot' id: get-cached-sysroot - uses: actions/cache@v4 + uses: actions/cache@v5 with: path: sysroot key: sysroot-${{ matrix.debian-arch }}-${{ hashFiles('./.github/workflows/build-cross-compile.yml') }} diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index a49eb349fc71..d5c746097f7b 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -84,7 +84,7 @@ jobs: steps: - name: 'Checkout the JDK source' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: 'Get the BootJDK' id: bootjdk diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index be7c99756df9..ed5f6a06b684 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -75,7 +75,7 @@ jobs: steps: - name: 'Checkout the JDK source' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: 'Get the BootJDK' id: bootjdk diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index 4985a6993a0b..cd35e039454d 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -31,6 +31,9 @@ on: platform: required: true type: string + runs-on: + required: true + type: string extra-conf-options: required: false type: string @@ -67,7 +70,7 @@ env: jobs: build-windows: name: build - runs-on: windows-2025 + runs-on: ${{ inputs.runs-on }} defaults: run: shell: bash @@ -83,7 +86,7 @@ jobs: steps: - name: 'Checkout the JDK source' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: 'Get MSYS2' uses: ./.github/actions/get-msys2 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 4e2c21c477cc..321d2fdd783c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -83,7 +83,7 @@ jobs: steps: - name: 'Checkout the scripts' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: sparse-checkout: | .github @@ -364,6 +364,7 @@ jobs: uses: ./.github/workflows/build-windows.yml with: platform: windows-x64 + runs-on: windows-2022 msvc-toolset-version: '14.44' msvc-toolset-architecture: 'x86.x64' configure-arguments: ${{ github.event.inputs.configure-arguments }} @@ -377,6 +378,7 @@ jobs: uses: ./.github/workflows/build-windows.yml with: platform: windows-aarch64 + runs-on: windows-2022 msvc-toolset-version: '14.44' msvc-toolset-architecture: 'arm64' make-target: 'hotspot' @@ -457,6 +459,6 @@ jobs: with: platform: windows-x64 bootjdk-platform: windows-x64 - runs-on: windows-2025 + runs-on: windows-2022 dry-run: ${{ needs.prepare.outputs.dry-run == 'true' }} debug-suffix: -debug diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f2c8916a3696..3355a79be62b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -128,7 +128,7 @@ jobs: steps: - name: 'Checkout the JDK source' - uses: actions/checkout@v4 + uses: actions/checkout@v6 - name: 'Get MSYS2' uses: ./.github/actions/get-msys2 @@ -239,7 +239,7 @@ jobs: if: always() - name: 'Upload test results' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: path: results name: ${{ steps.package.outputs.artifact-name }} @@ -247,7 +247,7 @@ jobs: # This is the best way I found to abort the job with an error message - name: 'Notify about test failures' - uses: actions/github-script@v7 + uses: actions/github-script@v8 with: script: core.setFailed('${{ steps.run-tests.outputs.error-message }}') if: steps.run-tests.outputs.failure == 'true' diff --git a/make/conf/github-actions.conf b/make/conf/github-actions.conf index ea7b2b13ab87..499dc49f4ca3 100644 --- a/make/conf/github-actions.conf +++ b/make/conf/github-actions.conf @@ -41,8 +41,8 @@ MACOS_AARCH64_BOOT_JDK_URL=https://github.com/SAP/SapMachine/releases/download/s MACOS_AARCH64_BOOT_JDK_SHA256=5e17522ae15cc57b7d57e8317b2f5c425aa38a50bd105e3c763a73317e1d8658 MACOS_X64_BOOT_JDK_EXT=tar.gz -MACOS_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_macos-x64_bin.tar.gz -MACOS_X64_BOOT_JDK_SHA256=6bbfb1d01741cbe55ab90299cb91464b695de9a3ace85c15131aa2f50292f321 +MACOS_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.3%2B9/OpenJDK25U-jdk_x64_mac_hotspot_25.0.3_9.tar.gz +MACOS_X64_BOOT_JDK_SHA256=4c539a18b4d656960ff6766727e9ca546fc17f7a29714dba9e7b47bdcb37c447 WINDOWS_X64_BOOT_JDK_EXT=zip WINDOWS_X64_BOOT_JDK_URL=https://github.com/SAP/SapMachine/releases/download/sapmachine-25.0.3/sapmachine-jdk-25.0.3_windows-x64_bin.zip diff --git a/make/hotspot/lib/CompileJvm.gmk b/make/hotspot/lib/CompileJvm.gmk index 0e5cb31302e1..cead9e644360 100644 --- a/make/hotspot/lib/CompileJvm.gmk +++ b/make/hotspot/lib/CompileJvm.gmk @@ -205,6 +205,7 @@ $(eval $(call SetupJdkLibrary, BUILD_LIBJVM, \ DISABLED_WARNINGS_gcc_macroAssembler_ppc_sha.cpp := unused-const-variable, \ DISABLED_WARNINGS_gcc_postaloc.cpp := address, \ DISABLED_WARNINGS_gcc_safepointMechanism.cpp := stringop-overflow, \ + DISABLED_WARNINGS_gcc_shenandoahGenerationalHeap.cpp := stringop-overflow, \ DISABLED_WARNINGS_gcc_shenandoahLock.cpp := stringop-overflow, \ DISABLED_WARNINGS_gcc_stubGenerator_s390.cpp := unused-const-variable, \ DISABLED_WARNINGS_gcc_synchronizer.cpp := stringop-overflow, \ diff --git a/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp index 387db778c1fd..a0be79d02813 100644 --- a/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/barrierSetAssembler_riscv.cpp @@ -228,7 +228,7 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Label* slo BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod(); Assembler::IncompressibleScope scope(masm); // Fixed length: see entry_barrier_offset() - Label local_guard; + Label local_guard, skip_barrier; NMethodPatchingType patching_type = nmethod_patching_type(); if (slow_path == nullptr) { @@ -290,24 +290,26 @@ void BarrierSetAssembler::nmethod_entry_barrier(MacroAssembler* masm, Label* slo ShouldNotReachHere(); } + Label& barrier_target = slow_path == nullptr ? skip_barrier : *slow_path; if (slow_path == nullptr) { - Label skip_barrier; - __ beq(t0, t1, skip_barrier); + __ beq(t0, t1, barrier_target, true /* is_far */); + } else { + __ bne(t0, t1, barrier_target, true /* is_far */); + } + if (slow_path == nullptr) { __ rt_call(StubRoutines::method_entry_barrier()); - __ j(skip_barrier); __ bind(local_guard); MacroAssembler::assert_alignment(__ pc()); __ emit_int32(0); // nmethod guard value. Skipped over in common case. - __ bind(skip_barrier); } else { - __ beq(t0, t1, *continuation); - __ j(*slow_path); __ bind(*continuation); } + + __ bind(skip_barrier); } void BarrierSetAssembler::c2i_entry_barrier(MacroAssembler* masm) { diff --git a/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp b/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp index ac619f83f7de..0d398e08d3df 100644 --- a/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp +++ b/src/hotspot/cpu/riscv/gc/shared/barrierSetNMethod_riscv.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2026, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,17 +41,16 @@ static int slow_path_size(nmethod* nm) { // The slow path code is out of line with C2. - // Leave a jal to the stub in the fast path. - return nm->is_compiled_by_c2() ? 1 : 8; + return nm->is_compiled_by_c2() ? 0 : 4; } static int entry_barrier_offset(nmethod* nm) { BarrierSetAssembler* bs_asm = BarrierSet::barrier_set()->barrier_set_assembler(); switch (bs_asm->nmethod_patching_type()) { case NMethodPatchingType::stw_instruction_and_data_patch: - return -4 * (4 + slow_path_size(nm)); + return -4 * (5 + slow_path_size(nm)); case NMethodPatchingType::conc_instruction_and_data_patch: - return -4 * (15 + slow_path_size(nm)); + return -4 * ((UseZtso ? 14 : 16) + slow_path_size(nm)); } ShouldNotReachHere(); return 0; @@ -103,6 +102,10 @@ class NativeNMethodBarrier { } _guard_addr = reinterpret_cast(instruction_address() + local_guard_offset(nm)); } + + // Perform the checking as verification. + err_msg msg("%s", ""); + assert(check_barrier(msg), "%s", msg.buffer()); } int get_value() { @@ -114,10 +117,6 @@ class NativeNMethodBarrier { } bool check_barrier(err_msg& msg) const; - void verify() const { - err_msg msg("%s", ""); - assert(check_barrier(msg), "%s", msg.buffer()); - } }; // Store the instruction bitmask, bits and name for checking the barrier. @@ -128,8 +127,8 @@ struct CheckInsn { }; static const struct CheckInsn barrierInsn[] = { - { 0x00000fff, 0x00000297, "auipc t0, 0 "}, - { 0x000fffff, 0x0002e283, "lwu t0, guard_offset(t0) "}, + { 0x00000fff, 0x00000297, "auipc t0, 0 " }, + { 0x000fffff, 0x0002e283, "lwu t0, guard_offset(t0)" }, /* ...... */ /* ...... */ /* guard: */ @@ -141,10 +140,11 @@ static const struct CheckInsn barrierInsn[] = { // register numbers and immediate values in the encoding. bool NativeNMethodBarrier::check_barrier(err_msg& msg) const { address addr = instruction_address(); - for(unsigned int i = 0; i < sizeof(barrierInsn)/sizeof(struct CheckInsn); i++ ) { + for (unsigned int i = 0; i < sizeof(barrierInsn) / sizeof(struct CheckInsn); i++) { uint32_t inst = Assembler::ld_instr(addr); if ((inst & barrierInsn[i].mask) != barrierInsn[i].bits) { - msg.print("Addr: " INTPTR_FORMAT " Code: 0x%x not an %s instruction", p2i(addr), inst, barrierInsn[i].name); + msg.print("Nmethod entry barrier did not start with auipc & lwu as expected. " + "Addr: " INTPTR_FORMAT " Code: 0x%x not an %s instruction.", p2i(addr), inst, barrierInsn[i].name); return false; } addr += 4; diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index d0c821357976..0b514cd29a92 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -881,6 +881,14 @@ void* os::lookup_function(const char* name) { return dlsym(RTLD_DEFAULT, name); } +int64_t os::ftell(FILE* file) { + return ::ftell(file); +} + +int os::fseek(FILE* file, int64_t offset, int whence) { + return ::fseek(file, offset, whence); +} + jlong os::lseek(int fd, jlong offset, int whence) { return (jlong) ::lseek(fd, offset, whence); } diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index fee71654cf40..4969f0ecf73d 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -5087,6 +5087,13 @@ jlong os::seek_to_file_offset(int fd, jlong offset) { return (jlong)::_lseeki64(fd, (__int64)offset, SEEK_SET); } +int64_t os::ftell(FILE* file) { + return ::_ftelli64(file); +} + +int os::fseek(FILE* file, int64_t offset, int whence) { + return ::_fseeki64(file,offset, whence); +} jlong os::lseek(int fd, jlong offset, int whence) { return (jlong) ::_lseeki64(fd, offset, whence); diff --git a/src/hotspot/share/cds/aotArtifactFinder.cpp b/src/hotspot/share/cds/aotArtifactFinder.cpp index d8999774a53b..dada68447948 100644 --- a/src/hotspot/share/cds/aotArtifactFinder.cpp +++ b/src/hotspot/share/cds/aotArtifactFinder.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ #include "cds/heapShared.hpp" #include "cds/lambdaProxyClassDictionary.hpp" #include "classfile/systemDictionaryShared.hpp" +#include "classfile/vmClasses.hpp" #include "logging/log.hpp" #include "memory/metaspaceClosure.hpp" #include "oops/instanceKlass.hpp" @@ -168,6 +169,7 @@ void AOTArtifactFinder::find_artifacts() { end_scanning_for_oops(); TrainingData::cleanup_training_data(); + check_critical_classes(); } void AOTArtifactFinder::start_scanning_for_oops() { @@ -228,6 +230,7 @@ void AOTArtifactFinder::add_cached_instance_class(InstanceKlass* ik) { bool created; _seen_classes->put_if_absent(ik, &created); if (created) { + check_critical_class(ik); append_to_all_cached_classes(ik); // All super types must be added. @@ -300,3 +303,25 @@ void AOTArtifactFinder::all_cached_classes_do(MetaspaceClosure* it) { it->push(_all_cached_classes->adr_at(i)); } } + +void AOTArtifactFinder::check_critical_classes() { + if (CDSConfig::is_dumping_static_archive()) { + // vmClasses are store in the AOT cache (or AOT config file, or static archive). + // If any of the vmClasses is excluded, (usually due to incompatible JVMTI agent), + // the resulting cache/config/archive is unusable. + for (auto id : EnumRange{}) { + check_critical_class(vmClasses::klass_at(id)); + } + } +} + +void AOTArtifactFinder::check_critical_class(InstanceKlass* ik) { + if (SystemDictionaryShared::is_excluded_class(ik)) { + ResourceMark rm; + const char* msg = err_msg("Critical class %s has been excluded. %s cannot be written.", + ik->external_name(), + CDSConfig::type_of_archive_being_written()); + MetaspaceShared::unrecoverable_writing_error(msg); + } +} + diff --git a/src/hotspot/share/cds/aotArtifactFinder.hpp b/src/hotspot/share/cds/aotArtifactFinder.hpp index 5d293f20af07..d9f71a91d5c5 100644 --- a/src/hotspot/share/cds/aotArtifactFinder.hpp +++ b/src/hotspot/share/cds/aotArtifactFinder.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,12 +80,14 @@ class AOTArtifactFinder : AllStatic { static void add_cached_type_array_class(TypeArrayKlass* tak); static void add_cached_instance_class(InstanceKlass* ik); static void append_to_all_cached_classes(Klass* k); + static void check_critical_class(InstanceKlass* ik); public: static void initialize(); static void find_artifacts(); static void add_cached_class(Klass* k); static void add_aot_inited_class(InstanceKlass* ik); static void all_cached_classes_do(MetaspaceClosure* it); + static void check_critical_classes(); static void dispose(); }; diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index 06cbaf1dbe79..1e2047a27c47 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -300,6 +300,7 @@ bool HeapShared::archive_object(oop obj, oop referrer, KlassSubGraphInfo* subgra debug_trace(); return false; } else { + AOTArtifactFinder::add_cached_class(obj->klass()); count_allocation(obj->size()); ArchiveHeapWriter::add_source_obj(obj); CachedOopInfo info = make_cached_oop_info(obj, referrer); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp index 6498f0acdb67..05e226288972 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp @@ -184,8 +184,8 @@ void ShenandoahAdaptiveHeuristics::record_success_concurrent() { } } -void ShenandoahAdaptiveHeuristics::record_success_degenerated() { - ShenandoahHeuristics::record_success_degenerated(); +void ShenandoahAdaptiveHeuristics::record_degenerated() { + ShenandoahHeuristics::record_degenerated(); // Adjust both trigger's parameters in the case of a degenerated GC because // either of them should have triggered earlier to avoid this case. adjust_margin_of_error(DEGENERATE_PENALTY_SD); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp index 014a4d991311..1ba18f37c2bb 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp @@ -32,25 +32,62 @@ #include "memory/allocation.hpp" #include "utilities/numberSeq.hpp" +/** + * ShenanoahAllocationRate maintains a truncated history of recently sampled allocation rates for the purpose of providing + * informed estimates of current and future allocation rates based on weighted averages and standard deviations of the + * truncated history. More recently sampled allocations are weighted more heavily than older samples when computing + * averages and standard deviations. + */ class ShenandoahAllocationRate : public CHeapObj { public: explicit ShenandoahAllocationRate(); + + // Reset the _last_sample_value to zero, _last_sample_time to current time. void allocation_counter_reset(); + // Force an allocation rate sample to be taken, even if the time since last sample is not greater than + // 1s/ShenandoahAdaptiveSampleFrequencyHz, except when current_time - _last_sample_time < MinSampleTime (2 ms). + // The sampled allocation rate is computed from (allocated - _last_sample_value) / (current_time - _last_sample_time). + // Return the newly computed rate if the sample is taken, zero if it is not an appropriate time to add a sample. + // In the case that a new sample is not taken, overwrite unaccounted_bytes_allocated with bytes allocated since + // the previous sample was taken (allocated - _last_sample_value). Otherwise, overwrite unaccounted_bytes_allocated + // with 0. double force_sample(size_t allocated, size_t &unaccounted_bytes_allocated); + + // Add an allocation rate sample if the time since last sample is greater than 1s/ShenandoahAdaptiveSampleFrequencyHz. + // The sampled allocation rate is computed from (allocated - _last_sample_value) / (current_time - _last_sample_time). + // Return the newly computed rate if the sample is taken, zero if it is not an appropriate time to add a sample. double sample(size_t allocated); + // Return an estimate of the upper bound on allocation rate, with the upper bound computed as the weighted average + // of recently sampled instantaneous allocation rates added to sds times the standard deviation computed for the + // sequence of recently sampled average allocation rates. double upper_bound(double sds) const; + + // Test whether rate significantly diverges from the computed average allocation rate. If so, return true. + // Otherwise, return false. Significant divergence is recognized if (rate - _rate.avg()) / _rate.sd() > threshold. bool is_spiking(double rate, double threshold) const; private: + // Return the instantaneous rate calculated from (allocated - _last_sample_value) / (time - _last_sample_time). + // Return Sentinel value 0.0 if (time - _last_sample_time) == 0 or if (allocated <= _last_sample_value). double instantaneous_rate(double time, size_t allocated) const; + // Time at which previous allocation rate sample was collected. double _last_sample_time; + + // Bytes allocated as of the time at which previous allocation rate sample was collected. size_t _last_sample_value; + + // The desired interval of time between consecutive samples of the allocation rate. double _interval_sec; + + // Holds a sequence of the most recently sampled instantaneous allocation rates TruncatedSeq _rate; + + // Holds a sequence of the most recently computed weighted average of allocation rates, with each weighted average + // computed immediately after an instantaneous rate was sampled TruncatedSeq _rate_avg; }; @@ -77,7 +114,7 @@ class ShenandoahAdaptiveHeuristics : public ShenandoahHeuristics { virtual void record_cycle_start() override; virtual void record_success_concurrent() override; - virtual void record_success_degenerated() override; + virtual void record_degenerated() override; virtual void record_success_full() override; virtual bool should_start_gc() override; @@ -154,6 +191,8 @@ class ShenandoahAdaptiveHeuristics : public ShenandoahHeuristics { } public: + // Sample the allocation rate at GC trigger time if possible. Return the number of allocated bytes that were + // not accounted for in the sample. This must be called before resetting bytes allocated since gc start. virtual size_t force_alloc_rate_sample(size_t bytes_allocated) override { size_t unaccounted_bytes; _allocation_rate.force_sample(bytes_allocated, unaccounted_bytes); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp index c8a0c3dc5183..0aa117385cff 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp @@ -242,7 +242,7 @@ void ShenandoahHeuristics::record_success_concurrent() { adjust_penalty(Concurrent_Adjust); } -void ShenandoahHeuristics::record_success_degenerated() { +void ShenandoahHeuristics::record_degenerated() { adjust_penalty(Degenerated_Penalty); } diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp index 3cd2cb1d171d..e1139765022a 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp @@ -129,6 +129,13 @@ class ShenandoahHeuristics : public CHeapObj { #endif } + inline void update_livedata(size_t live) { + _region_union._live_data = live; +#ifdef ASSERT + _union_tag = is_live_data; +#endif + } + inline ShenandoahHeapRegion* get_region() const { assert(_union_tag != is_uninitialized, "Cannot fetch region from uninitialized RegionData"); return _region; @@ -218,7 +225,7 @@ class ShenandoahHeuristics : public CHeapObj { virtual void record_success_concurrent(); - virtual void record_success_degenerated(); + virtual void record_degenerated(); virtual void record_success_full(); diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp index e963bcc35bb4..21eb73e5796d 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp @@ -88,6 +88,17 @@ bool ShenandoahOldHeuristics::prime_collection_set(ShenandoahCollectionSet* coll return false; } + // Between consecutive mixed-evacuation cycles, the live data within each candidate region may change due to + // promotions and old-gen evacuations. Re-sort the candidate regions in order to first evacuate regions that have + // the smallest amount of live data. These are easiest to evacuate with least effort. Doing these first allows + // us to more quickly replenish free memory with empty regions. + for (uint i = _next_old_collection_candidate; i < _last_old_collection_candidate; i++) { + ShenandoahHeapRegion* r = _region_data[i].get_region(); + _region_data[i].update_livedata(r->get_mixed_candidate_live_data_bytes()); + } + QuickSort::sort(_region_data + _next_old_collection_candidate, unprocessed_old_collection_candidates(), + compare_by_live); + _first_pinned_candidate = NOT_FOUND; uint included_old_regions = 0; @@ -407,6 +418,8 @@ void ShenandoahOldHeuristics::prepare_for_old_collections() { ShenandoahHeapRegion* r = candidates[i].get_region(); size_t region_garbage = r->garbage(); size_t region_free = r->free(); + + r->capture_mixed_candidate_garbage(); candidates_garbage += region_garbage; unfragmented += region_free; } @@ -449,6 +462,8 @@ void ShenandoahOldHeuristics::prepare_for_old_collections() { r->index(), ShenandoahHeapRegion::region_state_to_string(r->state())); const size_t region_garbage = r->garbage(); const size_t region_free = r->free(); + + r->capture_mixed_candidate_garbage(); candidates_garbage += region_garbage; unfragmented += region_free; defrag_count++; @@ -721,10 +736,10 @@ void ShenandoahOldHeuristics::record_success_concurrent() { this->ShenandoahHeuristics::record_success_concurrent(); } -void ShenandoahOldHeuristics::record_success_degenerated() { +void ShenandoahOldHeuristics::record_degenerated() { // Forget any triggers that occurred while OLD GC was ongoing. If we really need to start another, it will retrigger. clear_triggers(); - this->ShenandoahHeuristics::record_success_degenerated(); + this->ShenandoahHeuristics::record_degenerated(); } void ShenandoahOldHeuristics::record_success_full() { diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.hpp index 8d3fec746bae..b4ef625aac7d 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.hpp @@ -190,7 +190,7 @@ class ShenandoahOldHeuristics : public ShenandoahHeuristics { void record_success_concurrent() override; - void record_success_degenerated() override; + void record_degenerated() override; void record_success_full() override; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp b/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp index 86ff6f22c721..71fd6e376148 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.cpp @@ -57,21 +57,13 @@ ShenandoahAgeCensus::ShenandoahAgeCensus(uint max_workers) // Sentinel value _tenuring_threshold[i] = MAX_COHORTS; } - if (ShenandoahGenerationalAdaptiveTenuring) { - _local_age_tables = NEW_C_HEAP_ARRAY(AgeTable*, _max_workers, mtGC); - CENSUS_NOISE(_local_noise = NEW_C_HEAP_ARRAY(ShenandoahNoiseStats, max_workers, mtGC);) - for (uint i = 0; i < _max_workers; i++) { - _local_age_tables[i] = new AgeTable(false); - CENSUS_NOISE(_local_noise[i].clear();) - } - } else { - _local_age_tables = nullptr; + _local_age_tables = NEW_C_HEAP_ARRAY(AgeTable*, _max_workers, mtGC); + CENSUS_NOISE(_local_noise = NEW_C_HEAP_ARRAY(ShenandoahNoiseStats, max_workers, mtGC);) + for (uint i = 0; i < _max_workers; i++) { + _local_age_tables[i] = new AgeTable(false); + CENSUS_NOISE(_local_noise[i].clear();) } _epoch = MAX_SNAPSHOTS - 1; // see prepare_for_census_update() - - if (!ShenandoahGenerationalAdaptiveTenuring) { - _tenuring_threshold[_epoch] = InitialTenuringThreshold; - } } ShenandoahAgeCensus::~ShenandoahAgeCensus() { @@ -154,7 +146,6 @@ void ShenandoahAgeCensus::prepare_for_census_update() { // and compute the new tenuring threshold. void ShenandoahAgeCensus::update_census(size_t age0_pop) { prepare_for_census_update(); - assert(ShenandoahGenerationalAdaptiveTenuring, "Only update census when adaptive tenuring is enabled"); assert(_global_age_tables[_epoch]->is_clear(), "Dirty decks"); CENSUS_NOISE(assert(_global_noise[_epoch].is_clear(), "Dirty decks");) @@ -195,10 +186,6 @@ void ShenandoahAgeCensus::reset_global() { // Reset the local age tables, clearing any partial census. void ShenandoahAgeCensus::reset_local() { - if (!ShenandoahGenerationalAdaptiveTenuring) { - assert(_local_age_tables == nullptr, "Error"); - return; - } for (uint i = 0; i < _max_workers; i++) { _local_age_tables[i]->clear(); CENSUS_NOISE(_local_noise[i].clear();) @@ -221,10 +208,6 @@ bool ShenandoahAgeCensus::is_clear_global() { // Is local census information clear? bool ShenandoahAgeCensus::is_clear_local() { - if (!ShenandoahGenerationalAdaptiveTenuring) { - assert(_local_age_tables == nullptr, "Error"); - return true; - } for (uint i = 0; i < _max_workers; i++) { bool clear = _local_age_tables[i]->is_clear(); CENSUS_NOISE(clear |= _local_noise[i].is_clear();) @@ -258,7 +241,6 @@ void ShenandoahAgeCensus::update_total() { #endif // !PRODUCT void ShenandoahAgeCensus::update_tenuring_threshold() { - assert(ShenandoahGenerationalAdaptiveTenuring, "Only update when adaptive tenuring is enabled"); uint tt = compute_tenuring_threshold(); assert(tt <= MAX_COHORTS, "Out of bounds"); _tenuring_threshold[_epoch] = tt; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.hpp b/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.hpp index 39ea4ee9002a..5ccd0b21398f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAgeCensus.hpp @@ -173,7 +173,6 @@ class ShenandoahAgeCensus: public CHeapObj { ~ShenandoahAgeCensus(); // Return the local age table (population vector) for worker_id. - // Only used in the case of ShenandoahGenerationalAdaptiveTenuring AgeTable* get_local_age_table(uint worker_id) const { return _local_age_tables[worker_id]; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp index 8247b82e8618..171ee770db38 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp @@ -199,6 +199,7 @@ void ShenandoahArguments::initialize() { && strcmp(ShenandoahGCHeuristics, "adaptive") != 0) { log_warning(gc)("Ignoring -XX:ShenandoahGCHeuristics input: %s, because generational shenandoah only" " supports adaptive heuristics", ShenandoahGCHeuristics); + FLAG_SET_ERGO(ShenandoahGCHeuristics, "adaptive"); } FullGCForwarding::initialize_flags(MaxHeapSize); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp index c23f30a55e9d..ad00ab2ada9a 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp @@ -499,7 +499,8 @@ void ShenandoahAsserts::assert_control_or_vm_thread_at_safepoint(bool at_safepoi } void ShenandoahAsserts::assert_generations_reconciled(const char* file, int line) { - if (!SafepointSynchronize::is_at_safepoint()) { + if (!ShenandoahSafepoint::is_at_shenandoah_safepoint()) { + // Only shenandoah safepoint operations participate in the active/gc generation scheme return; } @@ -510,6 +511,6 @@ void ShenandoahAsserts::assert_generations_reconciled(const char* file, int line return; } - ShenandoahMessageBuffer msg("Active(%d) & GC(%d) Generations aren't reconciled", agen->type(), ggen->type()); + ShenandoahMessageBuffer msg("Active(%s) & GC(%s) Generations aren't reconciled", agen->name(), ggen->name()); report_vm_error(file, line, msg.buffer()); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.cpp b/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.cpp index d79e7dcefb9d..5dfbf0af469b 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.cpp @@ -257,10 +257,10 @@ void ShenandoahCollectorPolicy::print_gc_stats(outputStream* out) const { out->print_cr("%5zu Full GCs (%.2f%%)", _success_full_gcs, percent_of(_success_full_gcs, completed_gcs)); if (!ExplicitGCInvokesConcurrent) { - out->print_cr(" %5zu invoked explicitly (%.2f%%)", explicit_requests, percent_of(explicit_requests, _success_concurrent_gcs)); + out->print_cr(" %5zu invoked explicitly (%.2f%%)", explicit_requests, percent_of(explicit_requests, _success_full_gcs)); } if (!ShenandoahImplicitGCInvokesConcurrent) { - out->print_cr(" %5zu invoked implicitly (%.2f%%)", implicit_requests, percent_of(implicit_requests, _success_concurrent_gcs)); + out->print_cr(" %5zu invoked implicitly (%.2f%%)", implicit_requests, percent_of(implicit_requests, _success_full_gcs)); } out->print_cr(" %5zu caused by allocation failure (%.2f%%)", _alloc_failure_full, percent_of(_alloc_failure_full, _success_full_gcs)); out->print_cr(" %5zu upgraded from Degenerated GC (%.2f%%)", _alloc_failure_degenerated_upgrade_to_full, percent_of(_alloc_failure_degenerated_upgrade_to_full, _success_full_gcs)); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp index 64093a7c4bf1..b207b8d2ea6e 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahConcurrentGC.cpp @@ -1168,7 +1168,7 @@ void ShenandoahConcurrentGC::op_final_update_refs() { // Clear cancelled GC, if set. On cancellation path, the block before would handle // everything. if (heap->cancelled_gc()) { - heap->clear_cancelled_gc(true /* clear oom handler */); + heap->clear_cancelled_gc(); } // Has to be done before cset is clear diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index bdd495a86853..458b7ab99afc 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp @@ -43,7 +43,8 @@ ShenandoahControlThread::ShenandoahControlThread() : ShenandoahController(), _requested_gc_cause(GCCause::_no_cause_specified), - _degen_point(ShenandoahGC::_degenerated_outside_cycle) { + _degen_point(ShenandoahGC::_degenerated_outside_cycle), + _control_lock(CONTROL_LOCK_RANK, "ShenandoahControl_lock", true) { set_name("Shenandoah Control Thread"); create_and_start(); } @@ -239,7 +240,9 @@ void ShenandoahControlThread::run_service() { sleep = MIN2(ShenandoahControlIntervalMax, MAX2(1, sleep * 2)); last_sleep_adjust_time = current; } - os::naked_short_sleep(sleep); + + MonitorLocker ml(&_control_lock, Mutex::_no_safepoint_check_flag); + ml.wait(sleep); } } @@ -349,6 +352,16 @@ void ShenandoahControlThread::request_gc(GCCause::Cause cause) { } } +void ShenandoahControlThread::notify_control_thread(GCCause::Cause cause) { + // Although setting gc request is under _controller_lock, the read side (run_service()) + // does not take the lock. We need to enforce following order, so that read side sees + // latest requested gc cause when the flag is set. + MonitorLocker controller(&_control_lock, Mutex::_no_safepoint_check_flag); + _requested_gc_cause = cause; + _gc_requested.set(); + controller.notify(); +} + void ShenandoahControlThread::handle_requested_gc(GCCause::Cause cause) { if (should_terminate()) { log_info(gc)("Control thread is terminating, no more GCs"); @@ -360,8 +373,7 @@ void ShenandoahControlThread::handle_requested_gc(GCCause::Cause cause) { // The whitebox caller thread will arrange for itself to wait until the GC notifies // it that has reached the requested breakpoint (phase in the GC). if (cause == GCCause::_wb_breakpoint) { - _requested_gc_cause = cause; - _gc_requested.set(); + notify_control_thread(cause); return; } @@ -378,12 +390,7 @@ void ShenandoahControlThread::handle_requested_gc(GCCause::Cause cause) { size_t current_gc_id = get_gc_id(); size_t required_gc_id = current_gc_id + 1; while (current_gc_id < required_gc_id && !should_terminate()) { - // Although setting gc request is under _gc_waiters_lock, but read side (run_service()) - // does not take the lock. We need to enforce following order, so that read side sees - // latest requested gc cause when the flag is set. - _requested_gc_cause = cause; - _gc_requested.set(); - + notify_control_thread(cause); ml.wait(); current_gc_id = get_gc_id(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp index 9d95b5df7ed3..42955d133ac0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.hpp @@ -47,6 +47,9 @@ class ShenandoahControlThread: public ShenandoahController { GCCause::Cause _requested_gc_cause; ShenandoahGC::ShenandoahDegenPoint _degen_point; + // This lock is used to coordinate waking up the control thread + Monitor _control_lock; + public: ShenandoahControlThread(); @@ -56,6 +59,8 @@ class ShenandoahControlThread: public ShenandoahController { void request_gc(GCCause::Cause cause) override; private: + // Sets the requested cause and flag and notifies the control thread + void notify_control_thread(GCCause::Cause cause); bool check_cancellation_or_degen(ShenandoahGC::ShenandoahDegenPoint point); void service_concurrent_normal_cycle(GCCause::Cause cause); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahController.hpp b/src/hotspot/share/gc/shenandoah/shenandoahController.hpp index d24f52cb3f17..7837075b0ede 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahController.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahController.hpp @@ -44,6 +44,9 @@ class ShenandoahController: public ConcurrentGCThread { shenandoah_padding(2); protected: + const Mutex::Rank WAITERS_LOCK_RANK = Mutex::safepoint - 5; + const Mutex::Rank CONTROL_LOCK_RANK = Mutex::nosafepoint - 2; + // While we could have a single lock for these, it may risk unblocking // GC waiters when alloc failure GC cycle finishes. We want instead // to make complete explicit cycle for demanding customers. @@ -57,8 +60,8 @@ class ShenandoahController: public ConcurrentGCThread { ShenandoahController(): _allocs_seen(0), _gc_id(0), - _alloc_failure_waiters_lock(Mutex::safepoint-2, "ShenandoahAllocFailureGC_lock", true), - _gc_waiters_lock(Mutex::safepoint-2, "ShenandoahRequestedGC_lock", true) + _alloc_failure_waiters_lock(WAITERS_LOCK_RANK, "ShenandoahAllocFailureWaiters_lock", true), + _gc_waiters_lock(WAITERS_LOCK_RANK, "ShenandoahGCWaiters_lock", true) { } // Request a collection cycle. This handles "explicit" gc requests diff --git a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp index 0f84d95d02a8..641274d30720 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp @@ -94,7 +94,7 @@ void ShenandoahDegenGC::op_degenerated() { // Degenerated GC is STW, but it can also fail. Current mechanics communicates // GC failure via cancelled_concgc() flag. So, if we detect the failure after // some phase, we have to upgrade the Degenerate GC to Full GC. - heap->clear_cancelled_gc(true /* clear oom handler */); + heap->clear_cancelled_gc(); #ifdef ASSERT if (heap->mode()->is_generational()) { @@ -313,8 +313,12 @@ void ShenandoahDegenGC::op_degenerated() { policy->record_degenerated(_generation->is_young(), _abbreviated, progress); if (progress) { heap->notify_gc_progress(); + _generation->heuristics()->record_degenerated(); } else if (!heap->mode()->is_generational() || policy->generational_should_upgrade_degenerated_gc()) { + // Upgrade to full GC, register full-GC impact on heuristics. op_degenerated_futile(); + } else { + _generation->heuristics()->record_degenerated(); } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp index 557a3847bab6..b9455ebfeb0f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp @@ -890,8 +890,11 @@ class ShenandoahCompactObjectsClosure : public ObjectClosure { Copy::aligned_conjoint_words(compact_from, compact_to, size); oop new_obj = cast_to_oop(compact_to); - ContinuationGCSupport::relativize_stack_chunk(new_obj); + // Restore the mark word before relativizing the stack chunk. The copy's + // mark word contains the full GC forwarding encoding, which would cause + // is_stackChunk() to read garbage (especially with compact headers). new_obj->init_mark(); + ContinuationGCSupport::relativize_stack_chunk(new_obj); } } }; @@ -1165,7 +1168,7 @@ ShenandoahGenerationalHeap::TransferResult ShenandoahFullGC::phase5_epilog() { // Set mark incomplete because the marking bitmaps have been reset except pinned regions. heap->global_generation()->set_mark_incomplete(); - heap->clear_cancelled_gc(true /* clear oom handler */); + heap->clear_cancelled_gc(); } _preserved_marks->restore(heap->workers()); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp index 7b425a8fd46b..664ec40e37e0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp @@ -685,7 +685,7 @@ void ShenandoahGeneration::prepare_regions_and_collection_set(bool concurrent) { } // Tally the census counts and compute the adaptive tenuring threshold - if (is_generational && ShenandoahGenerationalAdaptiveTenuring) { + if (is_generational) { // Objects above TAMS weren't included in the age census. Since they were all // allocated in this cycle they belong in the age 0 cohort. We walk over all // young regions and sum the volume of objects between TAMS and top. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.hpp b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.hpp index c49deef561b0..52b08fc0c520 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.hpp @@ -142,6 +142,11 @@ class ShenandoahGeneration : public CHeapObj, public ShenandoahSpaceInfo { size_t soft_available() const override; size_t bytes_allocated_since_gc_start() const override; + + // Reset the bytes allocated within this generation since the start of GC. The argument initial_bytes_allocated + // is normally zero. In the case that some memory was allocated following the last allocation rate sample that + // precedes the start of GC, the number of bytes allocated is supplied as the initial value of bytes_allocated_since_gc_start. + // We will behave as if these bytes were allocated after the start of GC. void reset_bytes_allocated_since_gc_start(size_t initial_bytes_allocated); void increase_allocated(size_t bytes); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp index cd144cf05712..125c60b54460 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp @@ -47,7 +47,7 @@ #include "utilities/events.hpp" ShenandoahGenerationalControlThread::ShenandoahGenerationalControlThread() : - _control_lock(Mutex::nosafepoint - 2, "ShenandoahGCRequest_lock", true), + _control_lock(CONTROL_LOCK_RANK, "ShenandoahGCRequest_lock", true), _requested_gc_cause(GCCause::_no_gc), _requested_generation(nullptr), _gc_mode(none), @@ -119,10 +119,9 @@ void ShenandoahGenerationalControlThread::check_for_request(ShenandoahGCRequest& // failure (degenerated cycle), or old marking was cancelled to run a young collection. // In either case, the correct generation for the next cycle can be determined by // the cancellation cause. - request.cause = _heap->cancelled_cause(); + request.cause = _heap->clear_cancellation(GCCause::_shenandoah_concurrent_gc); if (request.cause == GCCause::_shenandoah_concurrent_gc) { request.generation = _heap->young_generation(); - _heap->clear_cancelled_gc(false); } } else { request.cause = _requested_gc_cause; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp index 316ac61dc352..2c817774b374 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalHeap.cpp @@ -337,18 +337,19 @@ oop ShenandoahGenerationalHeap::try_evacuate_object(oop p, Thread* thread, Shena ShenandoahHeap::increase_object_age(copy_val, from_region->age() + 1); } + // Relativize stack chunks before publishing the copy. After the forwarding CAS, + // mutators can see the copy and thaw it via the fast path if flags == 0. We must + // relativize derived pointers and set gc_mode before that happens. Skip if the + // copy's mark word is already a forwarding pointer (another thread won the race + // and overwrote the original's header before we copied it). + if (!ShenandoahForwarding::is_forwarded(copy_val)) { + ContinuationGCSupport::relativize_stack_chunk(copy_val); + } + // Try to install the new forwarding pointer. oop result = ShenandoahForwarding::try_update_forwardee(p, copy_val); if (result == copy_val) { // Successfully evacuated. Our copy is now the public one! - - // This is necessary for virtual thread support. This uses the mark word without - // considering that it may now be a forwarding pointer (and could therefore crash). - // Secondarily, we do not want to spend cycles relativizing stack chunks for oops - // that lost the evacuation race (and will therefore not become visible). It is - // safe to do this on the public copy (this is also done during concurrent mark). - ContinuationGCSupport::relativize_stack_chunk(copy_val); - if (ShenandoahEvacTracking) { // Record that the evacuation succeeded evac_tracker()->end_evacuation(thread, size * HeapWordSize, from_region->affiliation(), target_gen); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp index 9be46eb20d5d..c6e529fcaa2d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.cpp @@ -1402,12 +1402,21 @@ oop ShenandoahHeap::try_evacuate_object(oop p, Thread* thread, ShenandoahHeapReg // Copy the object: Copy::aligned_disjoint_words(cast_from_oop(p), copy, size); - // Try to install the new forwarding pointer. oop copy_val = cast_to_oop(copy); + + // Relativize stack chunks before publishing the copy. After the forwarding CAS, + // mutators can see the copy and thaw it via the fast path if flags == 0. We must + // relativize derived pointers and set gc_mode before that happens. Skip if the + // copy's mark word is already a forwarding pointer (another thread won the race + // and overwrote the original's header before we copied it). + if (!ShenandoahForwarding::is_forwarded(copy_val)) { + ContinuationGCSupport::relativize_stack_chunk(copy_val); + } + + // Try to install the new forwarding pointer. oop result = ShenandoahForwarding::try_update_forwardee(p, copy_val); if (result == copy_val) { // Successfully evacuated. Our copy is now the public one! - ContinuationGCSupport::relativize_stack_chunk(copy_val); shenandoah_assert_correct(nullptr, copy_val); if (ShenandoahEvacTracking) { evac_tracker()->end_evacuation(thread, size * HeapWordSize, from_region->affiliation(), target_gen); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp index f8d609d61527..b5b7200329ad 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.hpp @@ -458,9 +458,12 @@ class ShenandoahHeap : public CollectedHeap { // This indicates the reason the last GC cycle was cancelled. inline GCCause::Cause cancelled_cause() const; - // Clears the cancellation cause and optionally resets the oom handler (cancelling an - // old mark does _not_ touch the oom handler). - inline void clear_cancelled_gc(bool clear_oom_handler = true); + // Clears the cancellation cause and resets the oom handler + inline void clear_cancelled_gc(); + + // Clears the cancellation cause iff the current cancellation reason equals the given + // expected cancellation cause. Does not reset the oom handler. + inline GCCause::Cause clear_cancellation(GCCause::Cause expected); void cancel_concurrent_mark(); @@ -477,6 +480,8 @@ class ShenandoahHeap : public CollectedHeap { ShenandoahRegionIterator _update_refs_iterator; private: + inline void reset_cancellation_time(); + // GC support // Evacuation virtual void evacuate_collection_set(bool concurrent); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp index a4c5c91966fc..08c0ae6a6233 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeap.inline.hpp @@ -31,6 +31,7 @@ #include "classfile/javaClasses.inline.hpp" #include "gc/shared/continuationGCSupport.inline.hpp" +#include "gc/shared/gcCause.hpp" #include "gc/shared/markBitMap.inline.hpp" #include "gc/shared/suspendibleThreadSet.hpp" #include "gc/shared/threadLocalAllocBuffer.inline.hpp" @@ -268,16 +269,25 @@ inline GCCause::Cause ShenandoahHeap::cancelled_cause() const { return _cancelled_gc.get(); } -inline void ShenandoahHeap::clear_cancelled_gc(bool clear_oom_handler) { +inline void ShenandoahHeap::clear_cancelled_gc() { _cancelled_gc.set(GCCause::_no_gc); + reset_cancellation_time(); + _oom_evac_handler.clear(); +} + +inline GCCause::Cause ShenandoahHeap::clear_cancellation(const GCCause::Cause expected) { + const GCCause::Cause cancellation_cause = _cancelled_gc.cmpxchg(GCCause::_no_gc, expected); + if (cancellation_cause == expected) { + reset_cancellation_time(); + } + return cancellation_cause; +} + +inline void ShenandoahHeap::reset_cancellation_time() { if (_cancel_requested_time > 0) { log_debug(gc)("GC cancellation took %.3fs", (os::elapsedTime() - _cancel_requested_time)); _cancel_requested_time = 0; } - - if (clear_oom_handler) { - _oom_evac_handler.clear(); - } } inline HeapWord* ShenandoahHeap::allocate_from_gclab(Thread* thread, size_t size) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp index b959494ae99f..2736376fe9a2 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp @@ -75,6 +75,7 @@ ShenandoahHeapRegion::ShenandoahHeapRegion(HeapWord* start, size_t index, bool c _plab_allocs(0), _live_data(0), _critical_pins(0), + _mixed_candidate_garbage_words(0), _update_watermark(start), _age(0), #ifdef SHENANDOAH_CENSUS_NOISE @@ -565,22 +566,27 @@ void ShenandoahHeapRegion::recycle_internal() { assert(_recycling.is_set() && is_trash(), "Wrong state"); ShenandoahHeap* heap = ShenandoahHeap::heap(); - set_top(bottom()); + _mixed_candidate_garbage_words = 0; clear_live_data(); reset_alloc_metadata(); heap->marking_context()->reset_top_at_mark_start(this); set_update_watermark(bottom()); if (ZapUnusedHeapArea) { - SpaceMangler::mangle_region(MemRegion(bottom(), end())); + SpaceMangler::mangle_region(MemRegion(bottom(), top())); } + set_top(bottom()); + set_affiliation(FREE); + // Lastly, set region state to empty make_empty(); - set_affiliation(FREE); } void ShenandoahHeapRegion::try_recycle_under_lock() { shenandoah_assert_heaplocked(); - if (is_trash() && _recycling.try_set()) { + if (!is_trash()) { + return; + } + if (_recycling.try_set()) { if (is_trash()) { ShenandoahHeap* heap = ShenandoahHeap::heap(); ShenandoahGeneration* generation = heap->generation_for(affiliation()); @@ -600,12 +606,16 @@ void ShenandoahHeapRegion::try_recycle_under_lock() { os::naked_yield(); } } + assert(!is_trash(), "Must not"); } } void ShenandoahHeapRegion::try_recycle() { shenandoah_assert_not_heaplocked(); - if (is_trash() && _recycling.try_set()) { + if (!is_trash()) { + return; + } + if (_recycling.try_set()) { // Double check region state after win the race to set recycling flag if (is_trash()) { ShenandoahHeap* heap = ShenandoahHeap::heap(); @@ -825,7 +835,7 @@ void ShenandoahHeapRegion::set_state(RegionState to) { evt.set_to(to); evt.commit(); } - Atomic::store(&_state, to); + Atomic::release_store(&_state, to); } void ShenandoahHeapRegion::record_pin() { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp index 4c99364bc6ed..20040eebafd8 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp @@ -43,6 +43,7 @@ class ShenandoahHeapRegion { friend class VMStructs; friend class ShenandoahHeapRegionStateConstant; private: + /* Region state is described by a state machine. Transitions are guarded by heap lock, which allows changing the state of several regions atomically. @@ -216,7 +217,7 @@ class ShenandoahHeapRegion { bool is_alloc_allowed() const { auto cur_state = state(); return is_empty_state(cur_state) || cur_state == _regular || cur_state == _pinned; } bool is_stw_move_allowed() const { auto cur_state = state(); return cur_state == _regular || cur_state == _cset || (ShenandoahHumongousMoves && cur_state == _humongous_start); } - RegionState state() const { return Atomic::load(&_state); } + RegionState state() const { return Atomic::load_acquire(&_state); } int state_ordinal() const { return region_state_to_ordinal(state()); } void record_pin(); @@ -259,6 +260,8 @@ class ShenandoahHeapRegion { volatile size_t _live_data; volatile size_t _critical_pins; + size_t _mixed_candidate_garbage_words; + HeapWord* volatile _update_watermark; uint _age; @@ -379,6 +382,14 @@ class ShenandoahHeapRegion { inline size_t get_live_data_bytes() const; inline size_t get_live_data_words() const; + inline size_t get_mixed_candidate_live_data_bytes() const; + inline size_t get_mixed_candidate_live_data_words() const; + + inline void capture_mixed_candidate_garbage(); + + // Returns garbage by calculating difference between used and get_live_data_words. The value returned is only + // meaningful immediately following completion of marking. If there have been subsequent allocations in this region, + // use a different approach to determine garbage, such as (used() - get_mixed_candidate_live_data_bytes()) inline size_t garbage() const; void print_on(outputStream* st) const; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp index 57a5391ffe90..71b23d1f6fdb 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp @@ -157,6 +157,23 @@ inline size_t ShenandoahHeapRegion::get_live_data_bytes() const { return get_live_data_words() * HeapWordSize; } +inline size_t ShenandoahHeapRegion::get_mixed_candidate_live_data_bytes() const { + shenandoah_assert_heaplocked_or_safepoint(); + assert(used() >= _mixed_candidate_garbage_words * HeapWordSize, "used must exceed garbage"); + return used() - _mixed_candidate_garbage_words * HeapWordSize; +} + +inline size_t ShenandoahHeapRegion::get_mixed_candidate_live_data_words() const { + shenandoah_assert_heaplocked_or_safepoint(); + assert(used() >= _mixed_candidate_garbage_words * HeapWordSize, "used must exceed garbage"); + return used() / HeapWordSize - _mixed_candidate_garbage_words; +} + +inline void ShenandoahHeapRegion::capture_mixed_candidate_garbage() { + shenandoah_assert_heaplocked_or_safepoint(); + _mixed_candidate_garbage_words = garbage() / HeapWordSize; +} + inline bool ShenandoahHeapRegion::has_live() const { return get_live_data_words() != 0; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp index c588a03fdf90..09b872deadad 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp @@ -77,10 +77,9 @@ void ShenandoahMark::do_task(ShenandoahObjToScanQueue* q, T* cl, ShenandoahLiveD if (task->is_not_chunked()) { if (obj->is_instance()) { // Case 1: Normal oop, process as usual. - if (ContinuationGCSupport::relativize_stack_chunk(obj)) { - // Loom doesn't support mixing of weak marking and strong marking of - // stack chunks. - cl->set_weak(false); + if (obj->is_stackChunk()) { + // Loom doesn't support mixing of weak marking and strong marking of stack chunks. + cl->set_weak(false); } obj->oop_iterate(cl); @@ -118,13 +117,11 @@ inline void ShenandoahMark::count_liveness(ShenandoahLiveData* live_data, oop ob // Age census for objects in the young generation if (GENERATION == YOUNG || (GENERATION == GLOBAL && region->is_young())) { assert(heap->mode()->is_generational(), "Only if generational"); - if (ShenandoahGenerationalAdaptiveTenuring) { - assert(region->is_young(), "Only for young objects"); - uint age = ShenandoahHeap::get_object_age(obj); - ShenandoahAgeCensus* const census = ShenandoahGenerationalHeap::heap()->age_census(); - CENSUS_NOISE(census->add(age, region->age(), region->youth(), size, worker_id);) - NO_CENSUS_NOISE(census->add(age, region->age(), size, worker_id);) - } + assert(region->is_young(), "Only for young objects"); + const uint age = ShenandoahHeap::get_object_age(obj); + ShenandoahAgeCensus* const census = ShenandoahGenerationalHeap::heap()->age_census(); + CENSUS_NOISE(census->add(age, region->age(), region->youth(), size, worker_id);) + NO_CENSUS_NOISE(census->add(age, region->age(), size, worker_id);) } if (!region->is_humongous_start()) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp index 82378d43cf1d..c510c2a3601f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoah_globals.hpp @@ -84,9 +84,6 @@ "many consecutive young-gen collections have been " \ "completed following the preceding old-gen collection.") \ \ - product(bool, ShenandoahGenerationalAdaptiveTenuring, true, EXPERIMENTAL, \ - "(Generational mode only) Dynamically adapt tenuring age.") \ - \ product(bool, ShenandoahGenerationalCensusIgnoreOlderCohorts, true, \ EXPERIMENTAL,\ "(Generational mode only) Ignore mortality rates older than the " \ @@ -111,8 +108,7 @@ "(Generational mode only) Cohort mortality rates below this " \ "value will be treated as indicative of longevity, leading to " \ "tenuring. A lower value delays tenuring, a higher value hastens "\ - "it. Used only when ShenandoahGenerationalhenAdaptiveTenuring is "\ - "enabled.") \ + "it.") \ range(0.001,0.999) \ \ product(size_t, ShenandoahGenerationalTenuringCohortPopulationThreshold, \ diff --git a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp index 396c6db150d8..d5b144ec28e0 100644 --- a/src/hotspot/share/prims/jvmtiRedefineClasses.cpp +++ b/src/hotspot/share/prims/jvmtiRedefineClasses.cpp @@ -1485,6 +1485,8 @@ jvmtiError VM_RedefineClasses::load_new_class_versions() { } else { return JVMTI_ERROR_INTERNAL; } + } else if (res != JVMTI_ERROR_NONE) { + return res; } #ifdef ASSERT @@ -2057,7 +2059,7 @@ bool VM_RedefineClasses::rewrite_cp_refs_in_record_attribute(InstanceKlass* scra AnnotationArray* type_annotations = component->type_annotations(); if (type_annotations != nullptr && type_annotations->length() != 0) { int byte_i = 0; // byte index into annotations - if (!rewrite_cp_refs_in_annotations_typeArray(type_annotations, byte_i)) { + if (!rewrite_cp_refs_in_type_annotations_typeArray(type_annotations, byte_i, "record_info")) { log_debug(redefine, class, annotation)("bad record_component_type_annotations at %d", i); // propagate failure back to caller return false; diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index 42551edd0ba0..b9fa5374e7d9 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -671,6 +671,8 @@ class os: AllStatic { static int open(const char *path, int oflag, int mode); static FILE* fdopen(int fd, const char* mode); static FILE* fopen(const char* path, const char* mode); + static int64_t ftell(FILE* file); + static int fseek(FILE* file, int64_t offset, int whence); static jlong lseek(int fd, jlong offset, int whence); static bool file_exists(const char* file); diff --git a/src/hotspot/share/utilities/ostream.cpp b/src/hotspot/share/utilities/ostream.cpp index f3c469f14864..dea21234d3ba 100644 --- a/src/hotspot/share/utilities/ostream.cpp +++ b/src/hotspot/share/utilities/ostream.cpp @@ -611,15 +611,15 @@ void fileStream::write(const char* s, size_t len) { } } -long fileStream::fileSize() { - long size = -1; +int64_t fileStream::fileSize() { + int64_t size = -1; if (_file != nullptr) { - long pos = ::ftell(_file); + int64_t pos = os::ftell(_file); if (pos < 0) return pos; - if (::fseek(_file, 0, SEEK_END) == 0) { - size = ::ftell(_file); + if (os::fseek(_file, 0, SEEK_END) == 0) { + size = os::ftell(_file); } - ::fseek(_file, pos, SEEK_SET); + os::fseek(_file, pos, SEEK_SET); } return size; } diff --git a/src/hotspot/share/utilities/ostream.hpp b/src/hotspot/share/utilities/ostream.hpp index 79e95734a534..29761f52c2cb 100644 --- a/src/hotspot/share/utilities/ostream.hpp +++ b/src/hotspot/share/utilities/ostream.hpp @@ -298,7 +298,7 @@ class fileStream : public outputStream { fclose(_file); _need_close = false; } - long fileSize(); + int64_t fileSize(); void flush(); }; diff --git a/src/java.base/share/data/cacerts/wisekeyglobalrootgbca b/src/java.base/share/data/cacerts/wisekeyglobalrootgbca new file mode 100644 index 000000000000..5c2c35d04c1d --- /dev/null +++ b/src/java.base/share/data/cacerts/wisekeyglobalrootgbca @@ -0,0 +1,29 @@ +Owner: CN=OISTE WISeKey Global Root GB CA, OU=OISTE Foundation Endorsed, O=WISeKey, C=CH +Issuer: CN=OISTE WISeKey Global Root GB CA, OU=OISTE Foundation Endorsed, O=WISeKey, C=CH +Serial number: 76b1205274f0858746b3f8231af6c2c0 +Valid from: Mon Dec 01 15:00:32 GMT 2014 until: Thu Dec 01 15:10:31 GMT 2039 +Signature algorithm name: SHA256withRSA +Subject Public Key Algorithm: 2048-bit RSA key +Version: 3 +-----BEGIN CERTIFICATE----- +MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBt +MQswCQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUg +Rm91bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9i +YWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAwMzJaFw0zOTEyMDExNTEwMzFaMG0x +CzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBG +b3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh +bCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3 +HEokKtaXscriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGx +WuR51jIjK+FTzJlFXHtPrby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX +1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNk +u7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4oQnc/nSMbsrY9gBQHTC5P +99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvgGUpuuy9r +M2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUw +AwEB/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUB +BAMCAQAwDQYJKoZIhvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrgh +cViXfa43FK8+5/ea4n32cZiZBKpDdHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5 +gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0VQreUGdNZtGn//3ZwLWoo4rO +ZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEuiHZeeevJuQHHf +aPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic +Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= +-----END CERTIFICATE----- diff --git a/src/java.base/share/data/cacerts/wisekeyglobalrootgcca b/src/java.base/share/data/cacerts/wisekeyglobalrootgcca new file mode 100644 index 000000000000..e42432b95a64 --- /dev/null +++ b/src/java.base/share/data/cacerts/wisekeyglobalrootgcca @@ -0,0 +1,22 @@ +Owner: CN=OISTE WISeKey Global Root GC CA, OU=OISTE Foundation Endorsed, O=WISeKey, C=CH +Issuer: CN=OISTE WISeKey Global Root GC CA, OU=OISTE Foundation Endorsed, O=WISeKey, C=CH +Serial number: 212a560caeda0cab4045bf2ba22d3aea +Valid from: Tue May 09 09:48:34 GMT 2017 until: Fri May 09 09:58:33 GMT 2042 +Signature algorithm name: SHA384withECDSA +Subject Public Key Algorithm: 384-bit EC (secp384r1) key +Version: 3 +-----BEGIN CERTIFICATE----- +MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQsw +CQYDVQQGEwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91 +bmRhdGlvbiBFbmRvcnNlZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwg +Um9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRaFw00MjA1MDkwOTU4MzNaMG0xCzAJ +BgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQLExlPSVNURSBGb3Vu +ZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2JhbCBS +b290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4ni +eUqjFqdrVCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4W +p2OQ0jnUsYd4XxiWD1AbNTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8E +BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7T +rYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0EAwMDaAAwZQIwJsdpW9zV +57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtkAjEA2zQg +Mgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 +-----END CERTIFICATE----- diff --git a/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java b/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java index ed502e8da9b8..f76e04051243 100644 --- a/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java +++ b/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,7 @@ package javax.swing.text; +import java.awt.Color; import java.awt.Graphics; import java.awt.HeadlessException; import java.awt.Point; @@ -690,7 +691,25 @@ public void paint(Graphics g) { // semantics of damage we can't really get around this. damage(r); } - g.setColor(component.getCaretColor()); + if (component.isEditable()) { + g.setColor(component.getCaretColor()); + } else { + Color caretColor = component.getCaretColor(); + if (caretColor == null) { + caretColor = g.getColor(); + } + Color bg = component.getBackground(); + if (bg == null) { + g.setColor(caretColor); + } else { + int red = (caretColor.getRed() + bg.getRed()) / 2; + int green = (caretColor.getGreen() + bg.getGreen()) / 2; + int blue = (caretColor.getBlue() + bg.getBlue()) / 2; + int alpha = 127; + Color newCaretColor = new Color(red, green, blue, alpha); + g.setColor(newCaretColor); + } + } int paintWidth = getCaretWidth(r.height); r.x -= paintWidth >> 1; g.fillRect(r.x, r.y, paintWidth, r.height); diff --git a/src/java.desktop/share/legal/lcms.md b/src/java.desktop/share/legal/lcms.md index 20a22ea4db59..b2ea686eee06 100644 --- a/src/java.desktop/share/legal/lcms.md +++ b/src/java.desktop/share/legal/lcms.md @@ -1,4 +1,4 @@ -## Little Color Management System (LCMS) v2.18 +## Little Color Management System (LCMS) v2.19.1 ### LCMS License
@@ -86,6 +86,7 @@ Amyspark
 Lovell Fuller
 Eli Schwartz
 Diogo Teles Sant'Anna
+Vlad Erium
 
 Special Thanks
 --------------
diff --git a/src/java.desktop/share/native/liblcms/cmscgats.c b/src/java.desktop/share/native/liblcms/cmscgats.c
index e8a75c7355fd..d1585443816d 100644
--- a/src/java.desktop/share/native/liblcms/cmscgats.c
+++ b/src/java.desktop/share/native/liblcms/cmscgats.c
@@ -1274,19 +1274,26 @@ void* AllocChunk(cmsIT8* it8, cmsUInt32Number size)
 
         it8 ->Allocator.Used = 0;
         new_block = (cmsUInt8Number*)AllocBigBlock(it8, it8->Allocator.BlockSize);
-        if (new_block == NULL)
-            return NULL;
+        if (new_block == NULL) goto Error;
 
         it8->Allocator.Block = new_block;
     }
 
     if (it8->Allocator.Block == NULL)
-        return NULL;
+        goto Error;
 
     ptr = it8 ->Allocator.Block + it8 ->Allocator.Used;
     it8 ->Allocator.Used += size;
 
     return (void*) ptr;
+
+Error:
+
+    SynError(it8, "Allocation error");
+    it8->Allocator.BlockSize = 0;
+    it8->Allocator.Used = 0;
+    it8->Allocator.Block = NULL;
+    return NULL;
 }
 
 
@@ -1706,8 +1713,8 @@ cmsBool SetDataFormat(cmsIT8* it8, int n, const char *label)
             return FALSE;
     }
 
-    if (n >= t -> nSamples) {
-        SynError(it8, "More than NUMBER_OF_FIELDS fields.");
+    if (n < 0 || n >= t -> nSamples) {
+        SynError(it8, "Invalid or more than NUMBER_OF_FIELDS fields.");
         return FALSE;
     }
 
@@ -1720,9 +1727,11 @@ cmsBool SetDataFormat(cmsIT8* it8, int n, const char *label)
 }
 
 
-cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE  h, int n, const char *Sample)
+cmsBool CMSEXPORT cmsIT8SetDataFormat(cmsHANDLE h, int n, const char *Sample)
 {
     cmsIT8* it8 = (cmsIT8*)h;
+
+    _cmsAssert(n >= 0);
     return SetDataFormat(it8, n, Sample);
 }
 
@@ -3144,6 +3153,8 @@ cmsBool ParseCube(cmsIT8* cube, cmsStage** Shaper, cmsStage** CLUT, char title[]
             InSymbol(cube);
             if (!Check(cube, SINUM, "Shaper size expected")) return FALSE;
             shaper_size = cube->inum;
+            if (shaper_size < 2 || shaper_size > 65536)
+                 return SynError(cube, "LUT_1D_SIZE '%d' is out of bounds", shaper_size);
             InSymbol(cube);
             break;
 
@@ -3209,7 +3220,16 @@ cmsBool ParseCube(cmsIT8* cube, cmsStage** Shaper, cmsStage** CLUT, char title[]
 
             if (lut_size > 0) {
 
-                int nodes = lut_size * lut_size * lut_size;
+                int nodes;
+
+                /**
+                * Professional LUT generation tools (e.g., Nobe LutBake) list 65×65×65 as their highest supported size.
+                */
+                if (lut_size < 2 || lut_size > 65)
+                    return SynError(cube, "LUT size '%d' is not allowed", lut_size);
+
+                nodes = lut_size * lut_size * lut_size;
+
 
                 cmsFloat32Number* lut_table = (cmsFloat32Number*) _cmsMalloc(cube->ContextID, nodes * 3 * sizeof(cmsFloat32Number));
                 if (lut_table == NULL) return FALSE;
@@ -3280,13 +3300,17 @@ cmsHPROFILE CMSEXPORT cmsCreateDeviceLinkFromCubeFileTHR(cmsContext ContextID, c
 
     // Populates the pipeline
     if (Shaper != NULL) {
-        if (!cmsPipelineInsertStage(Pipeline, cmsAT_BEGIN, Shaper))
+        if (!cmsPipelineInsertStage(Pipeline, cmsAT_BEGIN, Shaper)) {
+            cmsStageFree(Shaper);
             goto Done;
+        }
     }
 
     if (CLUT != NULL) {
-        if (!cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT))
+        if (!cmsPipelineInsertStage(Pipeline, cmsAT_END, CLUT)) {
+            cmsStageFree(CLUT);
             goto Done;
+        }
     }
 
     // Propagate the description. We put no copyright because we know
diff --git a/src/java.desktop/share/native/liblcms/cmserr.c b/src/java.desktop/share/native/liblcms/cmserr.c
index 877beb9ca6a3..220602d4a361 100644
--- a/src/java.desktop/share/native/liblcms/cmserr.c
+++ b/src/java.desktop/share/native/liblcms/cmserr.c
@@ -77,25 +77,64 @@ int CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2)
     return (toupper(*us1) - toupper(*--us2));
 }
 
+#ifdef CMS_LARGE_FILE_SUPPORT
+
+long long int CMSEXPORT cmsfilelength(FILE* f)
+{
+    long long int p, n;
+
+#ifdef CMS_IS_WINDOWS_
+    p = _ftelli64(f);
+    if (p == -1LL)
+        return -1LL;
+
+    if (_fseeki64(f, 0, SEEK_END) != 0)
+        return -1LL;
+
+    n = _ftelli64(f);
+
+    if (_fseeki64(f, p, SEEK_SET) != 0)
+        return -1LL;
+#else
+    p = (long long int) ftello(f);
+    if (p < 0)
+        return -1LL;
+
+    if (fseeko(f, 0, SEEK_END) != 0)
+        return -1LL;
+
+    n = (long long int) ftello(f);
+
+    if (fseeko(f, (off_t) p, SEEK_SET) != 0)
+        return -1LL;
+#endif
+
+    return n;
+}
+
+#else
+
 // long int because C99 specifies ftell in such way (7.19.9.2)
 long int CMSEXPORT cmsfilelength(FILE* f)
 {
-    long int p , n;
+    long int p, n;
 
-    p = ftell(f); // register current file position
+    p = ftell(f);
     if (p == -1L)
         return -1L;
 
-    if (fseek(f, 0, SEEK_END) != 0) {
+    if (fseek(f, 0, SEEK_END) != 0)
         return -1L;
-    }
 
     n = ftell(f);
-    fseek(f, p, SEEK_SET); // file position restored
+
+    if (fseek(f, p, SEEK_SET) != 0)
+        return -1L;
 
     return n;
 }
 
+#endif
 
 // Memory handling ------------------------------------------------------------------
 //
@@ -104,7 +143,11 @@ long int CMSEXPORT cmsfilelength(FILE* f)
 // amount of memory that can be reclaimed. This is mostly as a safety feature to prevent
 // bogus or evil code to allocate huge blocks that otherwise lcms would never need.
 
-#define MAX_MEMORY_FOR_ALLOC  ((cmsUInt32Number)(1024U*1024U*512U))
+#ifdef CMS_LARGE_FILE_SUPPORT
+#   define MAX_MEMORY_FOR_ALLOC  ((cmsUInt32Number)(1024U*1024U*2048U))
+#else
+#   define MAX_MEMORY_FOR_ALLOC  ((cmsUInt32Number)(1024U*1024U*512U))
+#endif
 
 // User may override this behaviour by using a memory plug-in, which basically replaces
 // the default memory management functions. In this case, no check is performed and it
diff --git a/src/java.desktop/share/native/liblcms/cmsio0.c b/src/java.desktop/share/native/liblcms/cmsio0.c
index 5a4f09af5bcf..6e2a856b4b81 100644
--- a/src/java.desktop/share/native/liblcms/cmsio0.c
+++ b/src/java.desktop/share/native/liblcms/cmsio0.c
@@ -106,6 +106,9 @@ cmsBool  NULLWrite(cmsIOHANDLER* iohandler, cmsUInt32Number size, const void *Pt
 {
     FILENULL* ResData = (FILENULL*) iohandler ->stream;
 
+    if (size > (cmsUInt32Number)(0xFFFFFFFFU - ResData->Pointer))
+        return FALSE;
+
     ResData ->Pointer += size;
     if (ResData ->Pointer > iohandler->UsedSpace)
         iohandler->UsedSpace = ResData ->Pointer;
@@ -159,7 +162,6 @@ cmsIOHANDLER*  CMSEXPORT cmsOpenIOhandlerFromNULL(cmsContext ContextID)
 
 }
 
-
 // Memory-based stream --------------------------------------------------------------
 
 // Those functions implements an iohandler which takes a block of memory as storage medium.
@@ -179,12 +181,20 @@ cmsUInt32Number MemoryRead(struct _cms_io_handler* iohandler, void *Buffer, cmsU
     cmsUInt8Number* Ptr;
     cmsUInt32Number len = size * count;
 
-    if (ResData -> Pointer + len > ResData -> Size){
-
-        len = (ResData -> Size - ResData -> Pointer);
-        cmsSignalError(iohandler ->ContextID, cmsERROR_READ, "Read from memory error. Got %d bytes, block should be of %d bytes", len, count * size);
+    if (size == 0 || count == 0)
         return 0;
-    }
+
+    if ((len / count) != size)
+        goto ReadError;
+
+    if (Buffer == NULL)
+        goto ReadError;
+
+    if (len > ResData->Size)
+        goto ReadError;
+
+    if (ResData -> Pointer > ResData -> Size - len)
+        goto ReadError;
 
     Ptr  = ResData -> Block;
     Ptr += ResData -> Pointer;
@@ -192,18 +202,21 @@ cmsUInt32Number MemoryRead(struct _cms_io_handler* iohandler, void *Buffer, cmsU
     ResData -> Pointer += len;
 
     return count;
+
+ReadError:
+    cmsSignalError(iohandler->ContextID, cmsERROR_READ, "Read from memory error");
+    return 0;
+
 }
 
 // SEEK_CUR is assumed
 static
-cmsBool  MemorySeek(struct _cms_io_handler* iohandler, cmsUInt32Number offset)
+cmsBool MemorySeek(struct _cms_io_handler* iohandler, cmsUInt32Number offset)
 {
     FILEMEM* ResData = (FILEMEM*) iohandler ->stream;
 
-    if (offset > ResData ->Size) {
-        cmsSignalError(iohandler ->ContextID, cmsERROR_SEEK,  "Too few data; probably corrupted profile");
+    if (offset > ResData ->Size)
         return FALSE;
-    }
 
     ResData ->Pointer = offset;
     return TRUE;
@@ -226,15 +239,17 @@ cmsBool MemoryWrite(struct _cms_io_handler* iohandler, cmsUInt32Number size, con
 {
     FILEMEM* ResData = (FILEMEM*) iohandler ->stream;
 
-    if (ResData == NULL) return FALSE; // Housekeeping
-
-    // Check for available space. Clip.
-    if (ResData->Pointer + size > ResData->Size) {
-        size = ResData ->Size - ResData->Pointer;
-    }
+    if (ResData == NULL || Ptr == NULL) goto WriteError;
 
     if (size == 0) return TRUE;     // Write zero bytes is ok, but does nothing
 
+    // Check for available space.  Truncate the output in case the space
+    // is not enough instead of erroring out.  See
+    // https://github.com/hughsie/colord/issues/147.
+
+    if (size > ResData->Size - ResData->Pointer)
+        size = ResData->Size - ResData->Pointer;
+
     memmove(ResData ->Block + ResData ->Pointer, Ptr, size);
     ResData ->Pointer += size;
 
@@ -242,6 +257,10 @@ cmsBool MemoryWrite(struct _cms_io_handler* iohandler, cmsUInt32Number size, con
         iohandler->UsedSpace = ResData ->Pointer;
 
     return TRUE;
+
+WriteError:
+    cmsSignalError(iohandler->ContextID, cmsERROR_WRITE, "Write to memory error");
+    return FALSE;
 }
 
 
@@ -362,8 +381,15 @@ cmsUInt32Number FileRead(cmsIOHANDLER* iohandler, void *Buffer, cmsUInt32Number
 static
 cmsBool  FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset)
 {
+#ifdef CMS_LARGE_FILE_SUPPORT
+#  ifdef CMS_IS_WINDOWS_
+    if (_fseeki64((FILE*) iohandler->stream, (long long int) offset, SEEK_SET) != 0) {
+#  else
+    if (fseeko((FILE*) iohandler->stream, (off_t) offset, SEEK_SET) != 0) {
+#  endif
+#else
     if (fseek((FILE*) iohandler ->stream, (long) offset, SEEK_SET) != 0) {
-
+#endif
        cmsSignalError(iohandler ->ContextID, cmsERROR_FILE, "Seek error; probably corrupted file");
        return FALSE;
     }
@@ -375,13 +401,24 @@ cmsBool  FileSeek(cmsIOHANDLER* iohandler, cmsUInt32Number offset)
 static
 cmsUInt32Number FileTell(cmsIOHANDLER* iohandler)
 {
+#ifdef CMS_LARGE_FILE_SUPPORT
+#  ifdef CMS_IS_WINDOWS_
+    long long int t = _ftelli64((FILE*) iohandler->stream);
+#  else
+    long long int t = (long long int) ftello((FILE*) iohandler->stream);
+#  endif
+    if (t < 0) {
+        cmsSignalError(iohandler->ContextID, cmsERROR_FILE, "Tell error; probably corrupted file");
+        return 0;
+    }
+#else
     long t = ftell((FILE*)iohandler ->stream);
     if (t == -1L) {
         cmsSignalError(iohandler->ContextID, cmsERROR_FILE, "Tell error; probably corrupted file");
         return 0;
     }
-
-    return (cmsUInt32Number)t;
+#endif
+    return (cmsUInt32Number) t;
 }
 
 // Writes data to stream, also keeps used space for further reference. Returns TRUE on success, FALSE on error
@@ -408,7 +445,11 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
 {
     cmsIOHANDLER* iohandler = NULL;
     FILE* fm = NULL;
-    cmsInt32Number fileLen;
+#ifdef CMS_LARGE_FILE_SUPPORT
+    long long int fileLen;
+#else
+    long int fileLen;
+#endif
     char mode[4] = { 0,0,0,0 };
 
     _cmsAssert(FileName != NULL);
@@ -459,7 +500,7 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
              cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' not found", FileName);
             return NULL;
         }
-        fileLen = (cmsInt32Number)cmsfilelength(fm);
+        fileLen = cmsfilelength(fm);
         if (fileLen < 0)
         {
             fclose(fm);
@@ -467,6 +508,15 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
             cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of file '%s'", FileName);
             return NULL;
         }
+#ifdef CMS_LARGE_FILE_SUPPORT
+        if (fileLen > (long long int) 0xFFFFFFFFLL)
+        {
+            fclose(fm);
+            _cmsFree(ContextID, iohandler);
+            cmsSignalError(ContextID, cmsERROR_FILE, "File '%s' is too large", FileName);
+            return NULL;
+        }
+#endif
         iohandler -> ReportedSize = (cmsUInt32Number) fileLen;
         break;
 
@@ -506,14 +556,25 @@ cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromFile(cmsContext ContextID, const cha
 cmsIOHANDLER* CMSEXPORT cmsOpenIOhandlerFromStream(cmsContext ContextID, FILE* Stream)
 {
     cmsIOHANDLER* iohandler = NULL;
-    cmsInt32Number fileSize;
+#ifdef CMS_LARGE_FILE_SUPPORT
+    long long int fileSize;
+#else
+    long int fileSize;
+#endif
 
-    fileSize = (cmsInt32Number)cmsfilelength(Stream);
+    fileSize = cmsfilelength(Stream);
     if (fileSize < 0)
     {
         cmsSignalError(ContextID, cmsERROR_FILE, "Cannot get size of stream");
         return NULL;
     }
+#ifdef CMS_LARGE_FILE_SUPPORT
+    if (fileSize > (long long int) 0xFFFFFFFFLL)
+    {
+        cmsSignalError(ContextID, cmsERROR_FILE, "Stream is too large");
+        return NULL;
+    }
+#endif
 
     iohandler = (cmsIOHANDLER*) _cmsMallocZero(ContextID, sizeof(cmsIOHANDLER));
     if (iohandler == NULL) return NULL;
@@ -626,6 +687,18 @@ cmsTagSignature CMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, cmsUInt32Numb
     return Icc ->TagNames[n];
 }
 
+// Return location of the tag
+cmsBool CMSEXPORT cmsGetTagOffsetAndSize(cmsHPROFILE hProfile, cmsUInt32Number n, cmsUInt32Number* offset, cmsUInt32Number* size)
+{
+    _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile;
+
+    if (n > Icc->TagCount) return FALSE;
+    if (n >= MAX_TABLE_TAG) return FALSE;
+
+    if (offset != NULL) *offset = Icc->TagOffsets[n];
+    if (size != NULL) *size = Icc->TagSizes[n];
+    return TRUE;
+}
 
 static
 int SearchOneTag(_cmsICCPROFILE* Profile, cmsTagSignature sig)
@@ -791,7 +864,8 @@ cmsUInt32Number _validatedVersion(cmsUInt32Number DWord)
 static
 cmsBool validDeviceClass(cmsProfileClassSignature cl)
 {
-    if ((int)cl == 0) return TRUE; // We allow zero because older lcms versions defaulted to that.
+    if (cl == (cmsProfileClassSignature)0)
+        return TRUE; // We allow zero because older lcms versions defaulted to that.
 
     switch (cl)
     {
@@ -802,6 +876,10 @@ cmsBool validDeviceClass(cmsProfileClassSignature cl)
     case cmsSigAbstractClass:
     case cmsSigColorSpaceClass:
     case cmsSigNamedColorClass:
+    case cmsSigColorEncodingSpaceClass:
+    case cmsSigMultiplexIdentificationClass:
+    case cmsSigMultiplexLinkClass:
+    case cmsSigMultiplexVisualizationClass:
         return TRUE;
 
     default:
@@ -1010,6 +1088,17 @@ cmsBool _cmsWriteHeader(_cmsICCPROFILE* Icc, cmsUInt32Number UsedSpace)
 
 // ----------------------------------------------------------------------- Set/Get several struct members
 
+cmsUInt32Number CMSEXPORT cmsGetHeaderCMM(cmsHPROFILE hProfile)
+{
+    _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile;
+    return Icc->CMM;
+}
+
+void CMSEXPORT _cmsSetHeaderCMM(cmsHPROFILE hProfile, cmsUInt32Number CMM)
+{
+    _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile;
+    Icc->CMM = CMM;
+}
 
 cmsUInt32Number CMSEXPORT cmsGetHeaderRenderingIntent(cmsHPROFILE hProfile)
 {
@@ -1228,7 +1317,6 @@ cmsHPROFILE CMSEXPORT cmsOpenProfileFromIOhandler2THR(cmsContext ContextID, cmsI
     return NULL;
 }
 
-
 // Create profile from disk file
 cmsHPROFILE CMSEXPORT cmsOpenProfileFromFileTHR(cmsContext ContextID, const char *lpFileName, const char *sAccess)
 {
@@ -1296,7 +1384,6 @@ cmsHPROFILE  CMSEXPORT cmsOpenProfileFromStream(FILE* ICCProfile, const char *sA
     return cmsOpenProfileFromStreamTHR(NULL, ICCProfile, sAccess);
 }
 
-
 // Open from memory block
 cmsHPROFILE CMSEXPORT cmsOpenProfileFromMemTHR(cmsContext ContextID, const void* MemPtr, cmsUInt32Number dwSize)
 {
@@ -1445,7 +1532,6 @@ cmsBool SaveTags(_cmsICCPROFILE* Icc, _cmsICCPROFILE* FileOrig)
     return TRUE;
 }
 
-
 // Fill the offset and size fields for all linked tags
 static
 cmsBool SetLinks( _cmsICCPROFILE* Icc)
@@ -1527,7 +1613,6 @@ cmsUInt32Number CMSEXPORT cmsSaveProfileToIOhandler(cmsHPROFILE hProfile, cmsIOH
     return 0;
 }
 
-
 // Low-level save to disk.
 cmsBool  CMSEXPORT cmsSaveProfileToFile(cmsHPROFILE hProfile, const char* FileName)
 {
@@ -1663,21 +1748,23 @@ cmsBool IsTypeSupported(cmsTagDescriptor* TagDescriptor, cmsTagTypeSignature Typ
     return FALSE;
 }
 
-
 // That's the main read function
 void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
 {
-    _cmsICCPROFILE* Icc = (_cmsICCPROFILE*) hProfile;
+    _cmsICCPROFILE* Icc = (_cmsICCPROFILE*)hProfile;
+    cmsBool avoidCheck;
     cmsIOHANDLER* io;
     cmsTagTypeHandler* TypeHandler;
     cmsTagTypeHandler LocalTypeHandler;
-    cmsTagDescriptor*  TagDescriptor;
+    cmsTagDescriptor* TagDescriptor = NULL;
     cmsTagTypeSignature BaseType;
     cmsUInt32Number Offset, TagSize;
     cmsUInt32Number ElemCount;
     int n;
 
-    if (!_cmsLockMutex(Icc->ContextID, Icc ->UsrMutex)) return NULL;
+    if (!_cmsLockMutex(Icc->ContextID, Icc->UsrMutex)) return NULL;
+
+    avoidCheck = _cmsAvoidTypeCheckOnTags(Icc->ContextID);
 
     n = _cmsSearchTag(Icc, sig, TRUE);
     if (n < 0)
@@ -1688,7 +1775,7 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
     }
 
     // If the element is already in memory, return the pointer
-    if (Icc -> TagPtrs[n]) {
+    if (Icc->TagPtrs[n]) {
 
         if (Icc->TagTypeHandlers[n] == NULL) goto Error;
 
@@ -1696,24 +1783,26 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
         BaseType = Icc->TagTypeHandlers[n]->Signature;
         if (BaseType == 0) goto Error;
 
-        TagDescriptor = _cmsGetTagDescriptor(Icc->ContextID, sig);
-        if (TagDescriptor == NULL) goto Error;
+        if (!avoidCheck) {
 
-        if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+            TagDescriptor = _cmsGetTagDescriptor(Icc->ContextID, sig);
+            if (TagDescriptor == NULL) goto Error;
+            if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+        }
 
-        if (Icc ->TagSaveAsRaw[n]) goto Error;  // We don't support read raw tags as cooked
+        if (Icc->TagSaveAsRaw[n]) goto Error;  // We don't support read raw tags as cooked
 
-        _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
-        return Icc -> TagPtrs[n];
+        _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
+        return Icc->TagPtrs[n];
     }
 
     // We need to read it. Get the offset and size to the file
-    Offset    = Icc -> TagOffsets[n];
-    TagSize   = Icc -> TagSizes[n];
+    Offset = Icc->TagOffsets[n];
+    TagSize = Icc->TagSizes[n];
 
     if (TagSize < 8) goto Error;
 
-    io = Icc ->IOhandler;
+    io = Icc->IOhandler;
 
     if (io == NULL) { // This is a built-in profile that has been manipulated, abort early
 
@@ -1722,70 +1811,75 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
     }
 
     // Seek to its location
-    if (!io -> Seek(io, Offset))
+    if (!io->Seek(io, Offset))
         goto Error;
 
-    // Search for support on this tag
-    TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
-    if (TagDescriptor == NULL) {
+    if (!avoidCheck) {
+        // Search for support on this tag
+        TagDescriptor = _cmsGetTagDescriptor(Icc->ContextID, sig);
+        if (TagDescriptor == NULL) {
 
-        char String[5];
+            char String[5];
 
-        _cmsTagSignature2String(String, sig);
+            _cmsTagSignature2String(String, sig);
 
-        // An unknown element was found.
-        cmsSignalError(Icc ->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown tag type '%s' found.", String);
-        goto Error;     // Unsupported.
+            // An unknown element was found.
+            cmsSignalError(Icc->ContextID, cmsERROR_UNKNOWN_EXTENSION, "Unknown tag type '%s' found.", String);
+            goto Error;     // Unsupported.
+        }
     }
 
     // if supported, get type and check if in list
     BaseType = _cmsReadTypeBase(io);
     if (BaseType == 0) goto Error;
 
-    if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+    if (!avoidCheck) {
+        if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+    }
 
-    TagSize  -= 8;       // Already read by the type base logic
+    TagSize -= 8;       // Already read by the type base logic
 
     // Get type handler
-    TypeHandler = _cmsGetTagTypeHandler(Icc ->ContextID, BaseType);
+    TypeHandler = _cmsGetTagTypeHandler(Icc->ContextID, BaseType);
     if (TypeHandler == NULL) goto Error;
     LocalTypeHandler = *TypeHandler;
 
 
     // Read the tag
-    Icc -> TagTypeHandlers[n] = TypeHandler;
+    Icc->TagTypeHandlers[n] = TypeHandler;
 
-    LocalTypeHandler.ContextID = Icc ->ContextID;
-    LocalTypeHandler.ICCVersion = Icc ->Version;
-    Icc -> TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize);
+    LocalTypeHandler.ContextID = Icc->ContextID;
+    LocalTypeHandler.ICCVersion = Icc->Version;
+    Icc->TagPtrs[n] = LocalTypeHandler.ReadPtr(&LocalTypeHandler, io, &ElemCount, TagSize);
 
     // The tag type is supported, but something wrong happened and we cannot read the tag.
     // let know the user about this (although it is just a warning)
-    if (Icc -> TagPtrs[n] == NULL) {
+    if (Icc->TagPtrs[n] == NULL) {
 
         char String[5];
 
         _cmsTagSignature2String(String, sig);
-        cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted tag '%s'", String);
+        cmsSignalError(Icc->ContextID, cmsERROR_CORRUPTION_DETECTED, "Corrupted tag '%s'", String);
         goto Error;
     }
 
-    // This is a weird error that may be a symptom of something more serious, the number of
-    // stored item is actually less than the number of required elements.
-    if (ElemCount < TagDescriptor ->ElemCount) {
+    if (!avoidCheck) {
+        // This is a weird error that may be a symptom of something more serious, the number of
+        // stored item is actually less than the number of required elements.
+        if (ElemCount < TagDescriptor->ElemCount) {
 
-        char String[5];
+            char String[5];
 
-        _cmsTagSignature2String(String, sig);
-        cmsSignalError(Icc ->ContextID, cmsERROR_CORRUPTION_DETECTED, "'%s' Inconsistent number of items: expected %d, got %d",
-            String, TagDescriptor ->ElemCount, ElemCount);
-        goto Error;
+            _cmsTagSignature2String(String, sig);
+            cmsSignalError(Icc->ContextID, cmsERROR_CORRUPTION_DETECTED, "'%s' Inconsistent number of items: expected %d, got %d",
+                String, TagDescriptor->ElemCount, ElemCount);
+            goto Error;
+        }
     }
 
-
     // Return the data
-    _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
-    return Icc -> TagPtrs[n];
+    _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
+    return Icc->TagPtrs[n];
 
 
     // Return error and unlock the data
@@ -1794,7 +1888,7 @@ void* CMSEXPORT cmsReadTag(cmsHPROFILE hProfile, cmsTagSignature sig)
     freeOneTag(Icc, n);
     Icc->TagPtrs[n] = NULL;
 
-    _cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
+    _cmsUnlockMutex(Icc->ContextID, Icc->UsrMutex);
     return NULL;
 }
 
@@ -1812,6 +1906,8 @@ cmsTagTypeSignature _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig
 
     // Get the handler. The true type is there
     TypeHandler =  Icc -> TagTypeHandlers[n];
+    if (TypeHandler == NULL) return (cmsTagTypeSignature) 0;
+
     return TypeHandler ->Signature;
 }
 
@@ -2122,7 +2218,6 @@ cmsBool CMSEXPORT cmsLinkTag(cmsHPROFILE hProfile, cmsTagSignature sig, cmsTagSi
     return TRUE;
 }
 
-
 // Returns the tag linked to sig, in the case two tags are sharing same resource
 cmsTagSignature  CMSEXPORT cmsTagLinkedTo(cmsHPROFILE hProfile, cmsTagSignature sig)
 {
diff --git a/src/java.desktop/share/native/liblcms/cmslut.c b/src/java.desktop/share/native/liblcms/cmslut.c
index 28220eae6673..6ac5b63d2de1 100644
--- a/src/java.desktop/share/native/liblcms/cmslut.c
+++ b/src/java.desktop/share/native/liblcms/cmslut.c
@@ -489,25 +489,26 @@ void EvaluateCLUTfloatIn16(const cmsFloat32Number In[], cmsFloat32Number Out[],
 static
 cmsUInt32Number CubeSize(const cmsUInt32Number Dims[], cmsUInt32Number b)
 {
-    cmsUInt32Number rv, dim;
+    cmsUInt32Number dim;
+    cmsUInt64Number rv;
 
     _cmsAssert(Dims != NULL);
 
     for (rv = 1; b > 0; b--) {
 
         dim = Dims[b-1];
-        if (dim <= 1) return 0;  // Error
-
-        rv *= dim;
+        if (dim <= 1) return 0;
 
         // Check for overflow
         if (rv > UINT_MAX / dim) return 0;
+
+        rv *= dim;
     }
 
     // Again, prevent overflow
     if (rv > UINT_MAX / 15) return 0;
 
-    return rv;
+    return (cmsUInt32Number) rv;
 }
 
 static
diff --git a/src/java.desktop/share/native/liblcms/cmsnamed.c b/src/java.desktop/share/native/liblcms/cmsnamed.c
index acdaabc3ec26..4338b7cb8f58 100644
--- a/src/java.desktop/share/native/liblcms/cmsnamed.c
+++ b/src/java.desktop/share/native/liblcms/cmsnamed.c
@@ -116,8 +116,11 @@ cmsBool GrowMLUpool(cmsMLU* mlu)
     return TRUE;
 }
 
-
 // Grows a entry table for a MLU. Each time this function is called, table size is multiplied times two.
+// No need to check integer overflow since that is 2*16*count = 2^32-1 ; => count = 128 M entries,
+// That would be 2Gb, which is over MAX_MEMORY_FOR_ALLOC, even for large file size.
+// I added this check to silence the continuous spam reports of people using AI to catch what
+// they think are "vulnerabilities".
 static
 cmsBool GrowMLUtable(cmsMLU* mlu)
 {
@@ -129,8 +132,12 @@ cmsBool GrowMLUtable(cmsMLU* mlu)
 
     AllocatedEntries = mlu ->AllocatedEntries * 2;
 
-    // Check for overflow
-    if (AllocatedEntries / 2 != mlu ->AllocatedEntries) return FALSE;
+    // Check for overflow in count doubling: if wrapped, result < original
+    if (AllocatedEntries < mlu->AllocatedEntries) return FALSE;
+
+    // Check for overflow in byte-size multiplication:
+    // dividing back by sizeof must recover the original count
+    if ((AllocatedEntries * sizeof(_cmsMLUentry)) / sizeof(_cmsMLUentry) != AllocatedEntries) return FALSE;
 
     // Reallocate the memory
     NewPtr = (_cmsMLUentry*)_cmsRealloc(mlu ->ContextID, mlu ->Entries, AllocatedEntries*sizeof(_cmsMLUentry));
@@ -834,7 +841,8 @@ cmsNAMEDCOLORLIST* CMSEXPORT cmsDupNamedColorList(const cmsNAMEDCOLORLIST* v)
     memmove(NewNC ->Prefix, v ->Prefix, sizeof(v ->Prefix));
     memmove(NewNC ->Suffix, v ->Suffix, sizeof(v ->Suffix));
     NewNC ->ColorantCount = v ->ColorantCount;
-    memmove(NewNC->List, v ->List, v->nColors * sizeof(_cmsNAMEDCOLOR));
+    if (v->nColors > 0)
+        memmove(NewNC->List, v ->List, v->nColors * sizeof(_cmsNAMEDCOLOR));
     NewNC ->nColors = v ->nColors;
     return NewNC;
 }
diff --git a/src/java.desktop/share/native/liblcms/cmsopt.c b/src/java.desktop/share/native/liblcms/cmsopt.c
index 9e71426a3327..bba317223835 100644
--- a/src/java.desktop/share/native/liblcms/cmsopt.c
+++ b/src/java.desktop/share/native/liblcms/cmsopt.c
@@ -1221,10 +1221,13 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
 
         if (Trans[t]) cmsFreeToneCurve(Trans[t]);
         if (TransReverse[t]) cmsFreeToneCurve(TransReverse[t]);
+
+        Trans[t] = NULL;
+        TransReverse[t] = NULL;
     }
 
     cmsPipelineFree(LutPlusCurves);
-
+    LutPlusCurves = NULL;
 
     OptimizedPrelinCurves = _cmsStageGetPtrToCurveSet(OptimizedPrelinMpe);
     OptimizedPrelinCLUT   = (_cmsStageCLutData*) OptimizedCLUTmpe ->Data;
@@ -1235,7 +1238,7 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
         Prelin8Data* p8 = PrelinOpt8alloc(OptimizedLUT ->ContextID,
                                                 OptimizedPrelinCLUT ->Params,
                                                 OptimizedPrelinCurves);
-        if (p8 == NULL) return FALSE;
+        if (p8 == NULL) goto Error;
 
         _cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval8, (void*) p8, Prelin8free, Prelin8dup);
 
@@ -1245,7 +1248,8 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
         Prelin16Data* p16 = PrelinOpt16alloc(OptimizedLUT ->ContextID,
             OptimizedPrelinCLUT ->Params,
             3, OptimizedPrelinCurves, 3, NULL);
-        if (p16 == NULL) return FALSE;
+
+        if (p16 == NULL) goto Error;
 
         _cmsPipelineSetOptimizationParameters(OptimizedLUT, PrelinEval16, (void*) p16, PrelinOpt16free, Prelin16dup);
 
@@ -1259,7 +1263,7 @@ cmsBool OptimizeByComputingLinearization(cmsPipeline** Lut, cmsUInt32Number Inte
 
         if (!FixWhiteMisalignment(OptimizedLUT, ColorSpace, OutputColorSpace)) {
 
-            return FALSE;
+           goto Error;
         }
     }
 
diff --git a/src/java.desktop/share/native/liblcms/cmsps2.c b/src/java.desktop/share/native/liblcms/cmsps2.c
index 80f7c8084ae7..3901f92d2127 100644
--- a/src/java.desktop/share/native/liblcms/cmsps2.c
+++ b/src/java.desktop/share/native/liblcms/cmsps2.c
@@ -358,6 +358,32 @@ char* RemoveCR(const char* txt)
 
 }
 
+// Writes the body of a PostScript string literal, escaping the metacharacters
+// '\\', '(' and ')' and emitting non-printable / high-bit bytes as octal
+// triples per PLRM 3.3.4.1. The caller is responsible for the surrounding
+// '(' and ')' delimiters.
+static
+void EmitPSEscaped(cmsIOHANDLER* m, const char* txt)
+{
+    const unsigned char* p;
+
+    if (txt == NULL) return;
+
+    for (p = (const unsigned char*)txt; *p != 0; p++) {
+        unsigned char c = *p;
+
+        if (c == '\\' || c == '(' || c == ')') {
+            _cmsIOPrintf(m, "\\%c", c);
+        }
+        else if (c < 0x20 || c >= 0x7F) {
+            _cmsIOPrintf(m, "\\%03o", c);
+        }
+        else {
+            _cmsIOPrintf(m, "%c", c);
+        }
+    }
+}
+
 static
 void EmitHeader(cmsIOHANDLER* m, const char* Title, cmsHPROFILE hProfile)
 {
@@ -1048,7 +1074,10 @@ int WriteNamedColorCSA(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
                 continue;
 
         cmsDoTransform(xform, In, &Lab, 1);
-        _cmsIOPrintf(m, "  (%s) [ %.3f %.3f %.3f ]\n", ColorName, Lab.L, Lab.a, Lab.b);
+
+        _cmsIOPrintf(m, "  (");
+        EmitPSEscaped(m, ColorName);
+        _cmsIOPrintf(m, ") [ %.3f %.3f %.3f ]\n", Lab.L, Lab.a, Lab.b);
     }
 
     _cmsIOPrintf(m, ">>\n");
@@ -1483,7 +1512,10 @@ int WriteNamedColorCRD(cmsIOHANDLER* m, cmsHPROFILE hNamedColor, cmsUInt32Number
 
         cmsDoTransform(xform, In, Out, 1);
         BuildColorantList(Colorant, nColorant, Out);
-        _cmsIOPrintf(m, "  (%s) [ %s ]\n", ColorName, Colorant);
+
+        _cmsIOPrintf(m, "  (");
+        EmitPSEscaped(m, ColorName);
+        _cmsIOPrintf(m, ") [ %s ]\n", Colorant);
     }
 
     _cmsIOPrintf(m, "   >>");
diff --git a/src/java.desktop/share/native/liblcms/cmssamp.c b/src/java.desktop/share/native/liblcms/cmssamp.c
index c54a0d4ea723..7c8c93d9d52d 100644
--- a/src/java.desktop/share/native/liblcms/cmssamp.c
+++ b/src/java.desktop/share/native/liblcms/cmssamp.c
@@ -214,6 +214,50 @@ cmsBool BlackPointUsingPerceptualBlack(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfi
     return TRUE;
 }
 
+
+static
+cmsBool isInkColorspace(cmsColorSpaceSignature c)
+{
+    switch(c)
+    {
+    case cmsSigCmykData:
+    case cmsSigCmyData:
+    case cmsSigMCH1Data:
+    case cmsSigMCH2Data:
+    case cmsSigMCH3Data:
+    case cmsSigMCH4Data:
+    case cmsSigMCH5Data:
+    case cmsSigMCH6Data:
+    case cmsSigMCH7Data:
+    case cmsSigMCH8Data:
+    case cmsSigMCH9Data:
+    case cmsSigMCHAData:
+    case cmsSigMCHBData:
+    case cmsSigMCHCData:
+    case cmsSigMCHDData:
+    case cmsSigMCHEData:
+    case cmsSigMCHFData:
+    case cmsSig1colorData:
+    case cmsSig2colorData:
+    case cmsSig3colorData:
+    case cmsSig4colorData:
+    case cmsSig5colorData:
+    case cmsSig6colorData:
+    case cmsSig7colorData:
+    case cmsSig8colorData:
+    case cmsSig9colorData:
+    case cmsSig10colorData:
+    case cmsSig11colorData:
+    case cmsSig12colorData:
+    case cmsSig13colorData:
+    case cmsSig14colorData:
+    case cmsSig15colorData:
+            return TRUE;
+    default:
+        return FALSE;
+    }
+}
+
 // This function shouldn't exist at all -- there is such quantity of broken
 // profiles on black point tag, that we must somehow fix chromaticity to
 // avoid huge tint when doing Black point compensation. This function does
@@ -298,7 +342,7 @@ cmsBool CMSEXPORT cmsDetectBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROFILE hProfil
     // If output profile, discount ink-limiting and that's all
     if (Intent == INTENT_RELATIVE_COLORIMETRIC &&
         (cmsGetDeviceClass(hProfile) == cmsSigOutputClass) &&
-        (cmsGetColorSpace(hProfile)  == cmsSigCmykData))
+        (isInkColorspace(cmsGetColorSpace(hProfile))))
         return BlackPointUsingPerceptualBlack(BlackPoint, hProfile);
 
     // Nope, compute BP using current intent.
@@ -435,7 +479,7 @@ cmsBool CMSEXPORT cmsDetectDestinationBlackPoint(cmsCIEXYZ* BlackPoint, cmsHPROF
     if (!cmsIsCLUT(hProfile, Intent, LCMS_USED_AS_OUTPUT ) ||
         (ColorSpace != cmsSigGrayData &&
          ColorSpace != cmsSigRgbData  &&
-         ColorSpace != cmsSigCmykData)) {
+         !isInkColorspace(ColorSpace))) {
 
         // In this case, handle as input case
         return cmsDetectBlackPoint(BlackPoint, hProfile, Intent, dwFlags);
diff --git a/src/java.desktop/share/native/liblcms/cmstypes.c b/src/java.desktop/share/native/liblcms/cmstypes.c
index eab74940cd09..6ef3031aee09 100644
--- a/src/java.desktop/share/native/liblcms/cmstypes.c
+++ b/src/java.desktop/share/native/liblcms/cmstypes.c
@@ -6265,3 +6265,17 @@ cmsTagDescriptor* _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig
     return NULL;
 }
 
+cmsBool _cmsAvoidTypeCheckOnTags(cmsContext ContextID)
+{
+    _cmsTagLinkedList* pt;
+    _cmsTagPluginChunkType* TagPluginChunk = (_cmsTagPluginChunkType*)_cmsContextGetClientChunk(ContextID, TagPlugin);
+
+    for (pt = TagPluginChunk->Tag;
+        pt != NULL;
+        pt = pt->Next) {
+
+        if (pt->Signature == (cmsTagSignature)0) return TRUE;
+    }
+
+    return FALSE;
+}
diff --git a/src/java.desktop/share/native/liblcms/cmsvirt.c b/src/java.desktop/share/native/liblcms/cmsvirt.c
index 0dfc6e947a55..2b5cdf896f8b 100644
--- a/src/java.desktop/share/native/liblcms/cmsvirt.c
+++ b/src/java.desktop/share/native/liblcms/cmsvirt.c
@@ -1348,12 +1348,23 @@ cmsHPROFILE CMSEXPORT cmsTransform2DeviceLink(cmsHTRANSFORM hTransform, cmsFloat
     if (!cmsWriteTag(hProfile, DestinationTag, LUT)) goto Error;
 
 
-    if (xform -> InputColorant != NULL) {
+    // Colorant tables have special rules depening on deviceClass
+    if (xform -> InputColorant != NULL &&
+       (deviceClass == cmsSigLinkClass || deviceClass == cmsSigInputClass)) {
+
            if (!cmsWriteTag(hProfile, cmsSigColorantTableTag, xform->InputColorant)) goto Error;
     }
 
     if (xform -> OutputColorant != NULL) {
-           if (!cmsWriteTag(hProfile, cmsSigColorantTableOutTag, xform->OutputColorant)) goto Error;
+
+        if (deviceClass == cmsSigLinkClass) {
+
+            if (!cmsWriteTag(hProfile, cmsSigColorantTableOutTag, xform->OutputColorant)) goto Error;
+        }
+        else
+        {
+            if (!cmsWriteTag(hProfile, cmsSigColorantTableTag, xform->OutputColorant)) goto Error;
+        }
     }
 
     if ((deviceClass == cmsSigLinkClass) && (xform ->Sequence != NULL)) {
diff --git a/src/java.desktop/share/native/liblcms/cmsxform.c b/src/java.desktop/share/native/liblcms/cmsxform.c
index b5dd302b973a..397266551b97 100644
--- a/src/java.desktop/share/native/liblcms/cmsxform.c
+++ b/src/java.desktop/share/native/liblcms/cmsxform.c
@@ -528,7 +528,6 @@ void PrecalculatedXFORMGamutCheck(_cmsTRANSFORM* p,
     }
 }
 
-
 // No gamut check, Cache, 16 bits,
 static
 void CachedXFORM(_cmsTRANSFORM* p,
@@ -1471,6 +1470,22 @@ cmsUInt32Number CMSEXPORT cmsGetTransformOutputFormat(cmsHTRANSFORM hTransform)
     return xform->OutputFormat;
 }
 
+// Returns the optimized pipeline (Lut) inside a transform. Read-only; do not free.
+cmsPipeline* CMSEXPORT cmsGetTransformPipeline(cmsHTRANSFORM hTransform)
+{
+    _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
+    if (xform == NULL) return NULL;
+    return xform->Lut;
+}
+
+// Returns the gamut-check pipeline inside a transform. Read-only; do not free.
+cmsPipeline* CMSEXPORT cmsGetTransformGamutCheckPipeline(cmsHTRANSFORM hTransform)
+{
+    _cmsTRANSFORM* xform = (_cmsTRANSFORM*) hTransform;
+    if (xform == NULL) return NULL;
+    return xform->GamutCheck;
+}
+
 // For backwards compatibility
 cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
                                          cmsUInt32Number InputFormat,
@@ -1502,3 +1517,19 @@ cmsBool CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
     xform ->ToOutput     = ToOutput;
     return TRUE;
 }
+
+cmsNAMEDCOLORLIST* CMSEXPORT cmsGetTransformInputColorants(cmsHTRANSFORM hTransform)
+{
+    _cmsTRANSFORM* xform = (_cmsTRANSFORM*)hTransform;
+
+    if (xform == NULL) return NULL;
+    return xform->InputColorant;
+}
+
+cmsNAMEDCOLORLIST* CMSEXPORT cmsGetTransformOutputColorants(cmsHTRANSFORM hTransform)
+{
+    _cmsTRANSFORM* xform = (_cmsTRANSFORM*)hTransform;
+
+    if (xform == NULL) return NULL;
+    return xform->OutputColorant;
+}
diff --git a/src/java.desktop/share/native/liblcms/lcms2.h b/src/java.desktop/share/native/liblcms/lcms2.h
index 17a523847211..f05378ad95eb 100644
--- a/src/java.desktop/share/native/liblcms/lcms2.h
+++ b/src/java.desktop/share/native/liblcms/lcms2.h
@@ -52,7 +52,7 @@
 //
 //---------------------------------------------------------------------------------
 //
-// Version 2.18
+// Version 2.19
 //
 
 #ifndef _lcms2_H
@@ -66,6 +66,13 @@
 // "long long" type.
 // #define CMS_DONT_USE_INT64        1
 
+// Uncomment this one to enable large file support on file/stream I/O.
+// LittleCMS is still limited by ICC 32-bit offsets and sizes, so the
+// practical maximum remains 4 GiB minus profile overhead. Be careful
+// because such huge profiles have to be loaded into memory and that's
+// usually a very bad idea.
+// #define CMS_LARGE_FILE_SUPPORT    1
+
 // Uncomment this if your compiler doesn't work with fast floor function
 // #define CMS_DONT_USE_FAST_FLOOR 1
 
@@ -116,7 +123,7 @@ extern "C" {
 #endif
 
 // Version/release
-#define LCMS_VERSION        2180
+#define LCMS_VERSION        2190
 
 // I will give the chance of redefining basic types for compilers that are not fully C99 compliant
 #ifndef CMS_BASIC_TYPES_ALREADY_DEFINED
@@ -197,6 +204,9 @@ typedef double               cmsFloat64Number;
 #ifdef CMS_DONT_USE_INT64
     typedef cmsUInt32Number      cmsUInt64Number[2];
     typedef cmsInt32Number       cmsInt64Number[2];
+#   if defined(CMS_LARGE_FILE_SUPPORT)
+#      error "You need int64 for large file support"
+#   endif
 #endif
 
 // Derivative types
@@ -533,7 +543,13 @@ typedef enum {
     cmsSigLinkClass                         = 0x6C696E6B,  // 'link'
     cmsSigAbstractClass                     = 0x61627374,  // 'abst'
     cmsSigColorSpaceClass                   = 0x73706163,  // 'spac'
-    cmsSigNamedColorClass                   = 0x6e6d636c   // 'nmcl'
+    cmsSigNamedColorClass                   = 0x6e6d636c,  // 'nmcl'
+
+                                                            // iccMAX only
+    cmsSigColorEncodingSpaceClass           = 0x63656E63,  // 'cenc'
+    cmsSigMultiplexIdentificationClass      = 0x6D696420,  // 'mid '
+    cmsSigMultiplexLinkClass                = 0x6d6c6e6b,  // 'mlnk'
+    cmsSigMultiplexVisualizationClass       = 0x6d766973   // 'mvis'
 
 } cmsProfileClassSignature;
 
@@ -1107,8 +1123,12 @@ CMSAPI int               CMSEXPORT cmsGetEncodedCMMversion(void);
 // Support of non-standard functions --------------------------------------------------------------------------------------
 
 CMSAPI int               CMSEXPORT cmsstrcasecmp(const char* s1, const char* s2);
-CMSAPI long int          CMSEXPORT cmsfilelength(FILE* f);
 
+#ifdef CMS_LARGE_FILE_SUPPORT
+CMSAPI long long int     CMSEXPORT cmsfilelength(FILE* f);
+#else
+CMSAPI long int          CMSEXPORT cmsfilelength(FILE* f);
+#endif
 
 // Context handling --------------------------------------------------------------------------------------------------------
 
@@ -1531,6 +1551,7 @@ CMSAPI cmsHPROFILE       CMSEXPORT cmsCreateProfilePlaceholder(cmsContext Contex
 CMSAPI cmsContext        CMSEXPORT cmsGetProfileContextID(cmsHPROFILE hProfile);
 CMSAPI cmsInt32Number    CMSEXPORT cmsGetTagCount(cmsHPROFILE hProfile);
 CMSAPI cmsTagSignature   CMSEXPORT cmsGetTagSignature(cmsHPROFILE hProfile, cmsUInt32Number n);
+CMSAPI cmsBool           CMSEXPORT cmsGetTagOffsetAndSize(cmsHPROFILE hProfile, cmsUInt32Number n, cmsUInt32Number* offset, cmsUInt32Number* size);
 CMSAPI cmsBool           CMSEXPORT cmsIsTag(cmsHPROFILE hProfile, cmsTagSignature sig);
 
 // Read and write pre-formatted data
@@ -1554,6 +1575,8 @@ CMSAPI void              CMSEXPORT cmsGetHeaderAttributes(cmsHPROFILE hProfile,
 CMSAPI void              CMSEXPORT cmsGetHeaderProfileID(cmsHPROFILE hProfile, cmsUInt8Number* ProfileID);
 CMSAPI cmsBool           CMSEXPORT cmsGetHeaderCreationDateTime(cmsHPROFILE hProfile, struct tm *Dest);
 CMSAPI cmsUInt32Number   CMSEXPORT cmsGetHeaderRenderingIntent(cmsHPROFILE hProfile);
+CMSAPI cmsUInt32Number   CMSEXPORT cmsGetHeaderCMM(cmsHPROFILE hProfile);
+
 
 CMSAPI void              CMSEXPORT cmsSetHeaderFlags(cmsHPROFILE hProfile, cmsUInt32Number Flags);
 CMSAPI cmsUInt32Number   CMSEXPORT cmsGetHeaderManufacturer(cmsHPROFILE hProfile);
@@ -1896,6 +1919,13 @@ CMSAPI cmsContext       CMSEXPORT cmsGetTransformContextID(cmsHTRANSFORM hTransf
 CMSAPI cmsUInt32Number CMSEXPORT cmsGetTransformInputFormat(cmsHTRANSFORM hTransform);
 CMSAPI cmsUInt32Number CMSEXPORT cmsGetTransformOutputFormat(cmsHTRANSFORM hTransform);
 
+// Access the optimized pipeline and gamut-check pipeline inside a transform.
+CMSAPI cmsPipeline*    CMSEXPORT cmsGetTransformPipeline(cmsHTRANSFORM hTransform);
+CMSAPI cmsPipeline*    CMSEXPORT cmsGetTransformGamutCheckPipeline(cmsHTRANSFORM hTransform);
+// Grab colorants
+CMSAPI cmsNAMEDCOLORLIST* CMSEXPORT cmsGetTransformInputColorants(cmsHTRANSFORM hTransform);
+CMSAPI cmsNAMEDCOLORLIST* CMSEXPORT cmsGetTransformOutputColorants(cmsHTRANSFORM hTransform);
+
 // For backwards compatibility
 CMSAPI cmsBool          CMSEXPORT cmsChangeBuffersFormat(cmsHTRANSFORM hTransform,
                                                          cmsUInt32Number InputFormat,
diff --git a/src/java.desktop/share/native/liblcms/lcms2_internal.h b/src/java.desktop/share/native/liblcms/lcms2_internal.h
index 6bfe67e53501..073e497b1b85 100644
--- a/src/java.desktop/share/native/liblcms/lcms2_internal.h
+++ b/src/java.desktop/share/native/liblcms/lcms2_internal.h
@@ -887,6 +887,7 @@ int                  _cmsSearchTag(_cmsICCPROFILE* Icc, cmsTagSignature sig, cms
 cmsTagTypeHandler*   _cmsGetTagTypeHandler(cmsContext ContextID, cmsTagTypeSignature sig);
 cmsTagTypeSignature  _cmsGetTagTrueType(cmsHPROFILE hProfile, cmsTagSignature sig);
 cmsTagDescriptor*    _cmsGetTagDescriptor(cmsContext ContextID, cmsTagSignature sig);
+cmsBool              _cmsAvoidTypeCheckOnTags(cmsContext ContextID);
 
 // Error logging ---------------------------------------------------------------------------------------------------------
 
diff --git a/test/hotspot/gtest/gc/shenandoah/test_shenandoahMarkBitMap.cpp b/test/hotspot/gtest/gc/shenandoah/test_shenandoahMarkBitMap.cpp
index 3dbb7c621226..18cf3b3333f9 100644
--- a/test/hotspot/gtest/gc/shenandoah/test_shenandoahMarkBitMap.cpp
+++ b/test/hotspot/gtest/gc/shenandoah/test_shenandoahMarkBitMap.cpp
@@ -165,8 +165,8 @@ class ShenandoahMarkBitMapTest: public ::testing::Test {
 
   static bool run_test() {
     ShenandoahHeap* heap = ShenandoahHeap::heap();
-    size_t heap_size = heap->max_capacity();
-    size_t heap_size_words = heap_size / HeapWordSize;
+    size_t test_heap_size = MIN2(32 * M, heap->max_capacity());
+    size_t heap_size_words = test_heap_size / HeapWordSize;
     HeapWord* my_heap_memory = heap->base();
     HeapWord* end_of_my_heap = my_heap_memory + heap_size_words;
     MemRegion heap_descriptor(my_heap_memory, heap_size_words);
@@ -175,7 +175,7 @@ class ShenandoahMarkBitMapTest: public ::testing::Test {
     _assertion_failures = 0;
 
     size_t bitmap_page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
-    size_t bitmap_size_orig = ShenandoahMarkBitMap::compute_size(heap_size);
+    size_t bitmap_size_orig = ShenandoahMarkBitMap::compute_size(test_heap_size);
     size_t bitmap_size = align_up(bitmap_size_orig, bitmap_page_size);
     size_t bitmap_word_size = (bitmap_size + HeapWordSize - 1) / HeapWordSize;
 
diff --git a/test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java b/test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java
index 18f0e104ce05..fa6f3ab9b041 100644
--- a/test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java
+++ b/test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java
@@ -54,12 +54,12 @@
  * @summary Acceptance tests: collector can withstand allocation
  * @requires vm.gc.Shenandoah
  *
- * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * @run main/othervm/timeout=240 -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
  *      -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify
  *      TestAllocObjects
  *
- * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * @run main/othervm/timeout=480 -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
  *      -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify
  *      TestAllocObjects
diff --git a/test/hotspot/jtreg/gc/shenandoah/TestLargeObjectAlignment.java b/test/hotspot/jtreg/gc/shenandoah/TestLargeObjectAlignment.java
index 9e12a9108969..6eb0f36f1ae1 100644
--- a/test/hotspot/jtreg/gc/shenandoah/TestLargeObjectAlignment.java
+++ b/test/hotspot/jtreg/gc/shenandoah/TestLargeObjectAlignment.java
@@ -29,12 +29,13 @@
  * @key randomness
  * @requires vm.gc.Shenandoah
  * @requires vm.bits == "64"
+ * @requires os.maxMemory > 4G
  * @library /test/lib
  *
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -Xint                   TestLargeObjectAlignment
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -XX:-TieredCompilation  TestLargeObjectAlignment
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -XX:TieredStopAtLevel=1 TestLargeObjectAlignment
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -XX:TieredStopAtLevel=4 TestLargeObjectAlignment
+ * @run main/othervm -Xmx3g -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -Xint                   TestLargeObjectAlignment
+ * @run main/othervm -Xmx3g -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -XX:-TieredCompilation  TestLargeObjectAlignment
+ * @run main/othervm -Xmx3g -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -XX:TieredStopAtLevel=1 TestLargeObjectAlignment
+ * @run main/othervm -Xmx3g -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ObjectAlignmentInBytes=16 -XX:TieredStopAtLevel=4 TestLargeObjectAlignment
  */
 
 /*
@@ -43,14 +44,14 @@
  * @key randomness
  * @requires vm.gc.Shenandoah
  * @requires vm.bits == "64"
+ * @requires os.maxMemory > 4G
  * @library /test/lib
  *
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -XX:ObjectAlignmentInBytes=16 -Xint                   TestLargeObjectAlignment
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -XX:ObjectAlignmentInBytes=16 -XX:-TieredCompilation  TestLargeObjectAlignment
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -XX:ObjectAlignmentInBytes=16 -XX:TieredStopAtLevel=1 TestLargeObjectAlignment
- * @run main/othervm -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -XX:ObjectAlignmentInBytes=16 -XX:TieredStopAtLevel=4 TestLargeObjectAlignment
+ * @run main/othervm -Xmx3g -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -XX:ObjectAlignmentInBytes=16 -Xint                   TestLargeObjectAlignment
+ * @run main/othervm -Xmx3g -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -XX:ObjectAlignmentInBytes=16 -XX:-TieredCompilation  TestLargeObjectAlignment
+ * @run main/othervm -Xmx3g -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -XX:ObjectAlignmentInBytes=16 -XX:TieredStopAtLevel=1 TestLargeObjectAlignment
+ * @run main/othervm -Xmx3g -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational -XX:ObjectAlignmentInBytes=16 -XX:TieredStopAtLevel=4 TestLargeObjectAlignment
  */
-
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;
diff --git a/test/hotspot/jtreg/gc/shenandoah/TestSieveObjects.java b/test/hotspot/jtreg/gc/shenandoah/TestSieveObjects.java
index 37359b038b35..c3b09f5ab4c2 100644
--- a/test/hotspot/jtreg/gc/shenandoah/TestSieveObjects.java
+++ b/test/hotspot/jtreg/gc/shenandoah/TestSieveObjects.java
@@ -63,7 +63,7 @@
  *      -XX:+ShenandoahOOMDuringEvacALot
  *      TestSieveObjects
  *
- * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * @run main/othervm/timeout=240 -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
  *      -XX:+ShenandoahAllocFailureALot
  *      TestSieveObjects
@@ -103,7 +103,7 @@
  *      -XX:+ShenandoahOOMDuringEvacALot -XX:+ShenandoahVerify
  *      TestSieveObjects
  *
- * @run main/othervm -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * @run main/othervm/timeout=480 -Xmx1g -Xms1g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=adaptive -XX:ShenandoahGCMode=generational
  *      -XX:+ShenandoahAllocFailureALot -XX:+ShenandoahVerify
  *      TestSieveObjects
diff --git a/test/hotspot/jtreg/gc/shenandoah/generational/TestOldGrowthTriggers.java b/test/hotspot/jtreg/gc/shenandoah/generational/TestOldGrowthTriggers.java
index a72baddc5dc2..8c9f516f851b 100644
--- a/test/hotspot/jtreg/gc/shenandoah/generational/TestOldGrowthTriggers.java
+++ b/test/hotspot/jtreg/gc/shenandoah/generational/TestOldGrowthTriggers.java
@@ -27,6 +27,7 @@
  * @summary Test that growth of old-gen triggers old-gen marking
  * @key intermittent
  * @requires vm.gc.Shenandoah
+ * @requires vm.flagless
  * @library /test/lib
  * @run driver TestOldGrowthTriggers
  */
@@ -34,7 +35,6 @@
 import java.util.*;
 import java.math.BigInteger;
 
-import jdk.test.lib.Asserts;
 import jdk.test.lib.process.ProcessTools;
 import jdk.test.lib.process.OutputAnalyzer;
 
diff --git a/test/hotspot/jtreg/gc/shenandoah/jni/TestJNIGlobalRefs.java b/test/hotspot/jtreg/gc/shenandoah/jni/TestJNIGlobalRefs.java
index 6f211edf343d..d2a6269dddd4 100644
--- a/test/hotspot/jtreg/gc/shenandoah/jni/TestJNIGlobalRefs.java
+++ b/test/hotspot/jtreg/gc/shenandoah/jni/TestJNIGlobalRefs.java
@@ -27,7 +27,7 @@
  * @summary Test JNI Global Refs with Shenandoah
  * @requires vm.gc.Shenandoah
  *
- * @run main/othervm/native -Xmx1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * @run main/othervm/native/timeout=240 -Xmx1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
  *      -XX:+ShenandoahVerify
  *      TestJNIGlobalRefs
@@ -37,7 +37,7 @@
  * @summary Test JNI Global Refs with Shenandoah
  * @requires vm.gc.Shenandoah
  *
- * @run main/othervm/native -Xmx1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * @run main/othervm/native/timeout=240 -Xmx1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCHeuristics=aggressive
  *      TestJNIGlobalRefs
  */
@@ -46,7 +46,7 @@
  * @summary Test JNI Global Refs with Shenandoah
  * @requires vm.gc.Shenandoah
  *
- * @run main/othervm/native -Xmx1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * @run main/othervm/native/timeout=240 -Xmx1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational
  *      -XX:+ShenandoahVerify
  *      TestJNIGlobalRefs
@@ -56,7 +56,7 @@
  * @summary Test JNI Global Refs with Shenandoah
  * @requires vm.gc.Shenandoah
  *
- * @run main/othervm/native -Xmx1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
+ * @run main/othervm/native/timeout=240 -Xmx1g -Xlog:gc -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions
  *      -XX:+UseShenandoahGC -XX:ShenandoahGCMode=generational
  *      TestJNIGlobalRefs
  */
diff --git a/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java b/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java
index 1ae3b690b0d4..e5c3acaccac6 100644
--- a/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java
+++ b/test/hotspot/jtreg/gc/shenandoah/mxbeans/TestPauseNotifications.java
@@ -109,6 +109,8 @@ public class TestPauseNotifications {
 
     static final long HEAP_MB = 128;                           // adjust for test configuration above
     static final long TARGET_MB = Long.getLong("target", 2_000); // 2 Gb allocation
+    static final long STEP_MS = 1000;
+    static final int  SIZE = 100_000;
 
     static volatile Object sink;
 
@@ -160,24 +162,21 @@ public void handleNotification(Notification n, Object o) {
             ((NotificationEmitter) bean).addNotificationListener(listener, null, null);
         }
 
-        final int size = 100_000;
-        long count = TARGET_MB * 1024 * 1024 / (16 + 4 * size);
-
+        final long count = TARGET_MB * 1024 * 1024 / (16 + 4 * SIZE);
         for (int c = 0; c < count; c++) {
-            sink = new int[size];
+            sink = new int[SIZE];
         }
 
         // Look at test timeout to figure out how long we can wait without breaking into timeout.
         // Default to 1/4 of the remaining time in 1s steps.
-        final long STEP_MS = 1000;
-        long spentTimeNanos = System.nanoTime() - startTimeNanos;
-        long maxTries = (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) - (spentTimeNanos / 1_000_000L)) / STEP_MS / 4;
+        final long spentTimeNanos = System.nanoTime() - startTimeNanos;
+        final long maxTries = (Utils.adjustTimeout(Utils.DEFAULT_TEST_TIMEOUT) - (spentTimeNanos / 1_000_000L)) / STEP_MS / 4;
 
         long actualPauses = 0;
         long actualCycles = 0;
 
         // Wait until enough notifications are accrued to match minimum boundary.
-        long minExpected = 10;
+        final long minExpected = 10;
 
         long tries = 0;
         while (tries++ < maxTries) {
@@ -186,13 +185,20 @@ public void handleNotification(Notification n, Object o) {
             if (minExpected <= actualPauses && minExpected <= actualCycles) {
                 // Wait a little bit to catch the lingering notifications.
                 Thread.sleep(5000);
-                actualPauses = pausesCount.get();
-                actualCycles = cyclesCount.get();
                 break;
             }
             Thread.sleep(STEP_MS);
         }
 
+        for (GarbageCollectorMXBean bean : ManagementFactory.getGarbageCollectorMXBeans()) {
+            ((NotificationEmitter) bean).removeNotificationListener(listener);
+        }
+
+        actualPauses = pausesCount.get();
+        actualCycles = cyclesCount.get();
+        long actualPauseDuration = pausesDuration.get();
+        long actualCycleDuration = cyclesDuration.get();
+
         {
             String msg = "Pauses expected = [" + minExpected + "; +inf], actual = " + actualPauses;
             if (minExpected <= actualPauses) {
@@ -212,11 +218,7 @@ public void handleNotification(Notification n, Object o) {
         }
 
         {
-            long actualPauseDuration = pausesDuration.get();
-            long actualCycleDuration = cyclesDuration.get();
-
             String msg = "Pauses duration (" + actualPauseDuration + ") is expected to be not larger than cycles duration (" + actualCycleDuration + ")";
-
             if (actualPauseDuration <= actualCycleDuration) {
                 System.out.println(msg);
             } else {
diff --git a/test/hotspot/jtreg/gc/shenandoah/options/TestGenerationalHeuristics.java b/test/hotspot/jtreg/gc/shenandoah/options/TestGenerationalHeuristics.java
new file mode 100644
index 000000000000..822c38063479
--- /dev/null
+++ b/test/hotspot/jtreg/gc/shenandoah/options/TestGenerationalHeuristics.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/*
+ * @test id=generational
+ * @bug 8381871
+ * @summary Test that ShenandoahGCHeuristics is always adaptive in generational mode
+ * @requires vm.gc.Shenandoah
+ * @library /test/lib
+ * @run driver TestGenerationalHeuristics
+ */
+
+import jdk.test.lib.process.ProcessTools;
+import jdk.test.lib.process.OutputAnalyzer;
+
+public class TestGenerationalHeuristics {
+    public static void main(String[] args) throws Exception {
+        {
+            OutputAnalyzer output = ProcessTools.executeLimitedTestJava(
+                "-XX:+UseShenandoahGC",
+                "-XX:ShenandoahGCMode=generational",
+                "-XX:ShenandoahGCHeuristics=adaptive",
+                "-XX:+PrintFlagsFinal",
+                "-version");
+            output.shouldMatch("ShenandoahGCHeuristics(.*)= adaptive ");
+            output.shouldHaveExitValue(0);
+        }
+
+        {
+            OutputAnalyzer output = ProcessTools.executeLimitedTestJava(
+                "-XX:+UseShenandoahGC",
+                "-XX:ShenandoahGCMode=generational",
+                "-XX:ShenandoahGCHeuristics=static",
+                "-XX:+PrintFlagsFinal",
+                "-version");
+            output.shouldMatch("ShenandoahGCHeuristics(.*)= adaptive ");
+            output.shouldHaveExitValue(0);
+        }
+
+        {
+            OutputAnalyzer output = ProcessTools.executeLimitedTestJava(
+                "-XX:+UseShenandoahGC",
+                "-XX:ShenandoahGCMode=generational",
+                "-XX:ShenandoahGCHeuristics=aggressive",
+                "-XX:+PrintFlagsFinal",
+                "-version");
+            output.shouldMatch("ShenandoahGCHeuristics(.*)= adaptive ");
+            output.shouldHaveExitValue(0);
+        }
+
+        {
+            OutputAnalyzer output = ProcessTools.executeLimitedTestJava(
+                "-XX:+UseShenandoahGC",
+                "-XX:ShenandoahGCMode=generational",
+                "-XX:ShenandoahGCHeuristics=compact",
+                "-XX:+PrintFlagsFinal",
+                "-version");
+            output.shouldMatch("ShenandoahGCHeuristics(.*)= adaptive ");
+            output.shouldHaveExitValue(0);
+        }
+    }
+
+}
diff --git a/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java b/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java
index 302bf7cdc73b..9c7d1b5532a4 100644
--- a/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java
+++ b/test/hotspot/jtreg/runtime/Metaspace/DefineClass.java
@@ -193,7 +193,7 @@ private static int getStringIndex(String needle, byte[] buf) {
 
     private static int getStringIndex(String needle, byte[] buf, int offset) {
         outer:
-        for (int i = offset; i < buf.length - offset - needle.length(); i++) {
+        for (int i = offset; i <= buf.length - needle.length(); i++) {
             for (int j = 0; j < needle.length(); j++) {
                 if (buf[i + j] != (byte)needle.charAt(j)) continue outer;
             }
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/RedefineCriticalClasses.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/RedefineCriticalClasses.java
new file mode 100644
index 000000000000..c4753ee38785
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/RedefineCriticalClasses.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+
+/*
+ * @test
+ * @summary AOT training run should fail if critical classes have been redefined by JVMTI
+ * @bug 8380409
+ * @requires vm.cds.supports.aot.class.linking
+ * @library /test/lib
+ * @run driver RedefineClassHelper
+ * @build RedefineCriticalClasses
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar RedefineCriticalClassesApp
+ * @run driver RedefineCriticalClasses
+ */
+
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.helpers.ClassFileInstaller;
+import jdk.test.lib.process.ProcessTools;
+
+public class RedefineCriticalClasses {
+    public static void main(String... args) throws Exception {
+        ArrayList processArgs = new ArrayList<>();
+
+        // redefineagent.jar is created by "@run driver RedefineClassHelper"
+        processArgs.add("-javaagent:redefineagent.jar");
+
+        processArgs.add("-XX:AOTMode=record");
+        processArgs.add("-XX:AOTConfiguration=app.aotconfig");
+        processArgs.add("-Xlog:aot,cds");
+        processArgs.add("-cp");
+        processArgs.add("app.jar");
+        processArgs.add("RedefineCriticalClassesApp");
+
+        ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(processArgs);
+        CDSTestUtils.executeAndLog(pb, "train")
+            .shouldContain("Redefined: class java.lang.Class")
+            .shouldContain("Skipping java/lang/Class: Has been redefined")
+            .shouldContain("Critical class java.lang.Class has been excluded. AOT configuration file cannot be written")
+            .shouldHaveExitValue(1);
+    }
+}
+
+class RedefineCriticalClassesApp {
+    public static void main(String[] args) throws Exception {
+        // Use RedefineClassHelper (loaded from redefineagent.jar into the boot class loader)
+        // to redefine java/lang/Class, using the exact same bytecodes as from the JDK.
+        // The JVM will mark it as having been redefined by JVMTI and will exclude it from the
+        // AOT configuration file.
+
+        URL url = new URL("jrt:/java.base/java/lang/Class.class");
+        try (InputStream in = url.openConnection().getInputStream()) {
+            byte[] b = in.readAllBytes();
+            System.out.println("Length = " + b.length);
+            RedefineClassHelper.redefineClass(Class.class, b);
+            System.out.println("Redefined: " + Class.class);
+        }
+    }
+}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/TransformCriticalClasses.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/TransformCriticalClasses.java
new file mode 100644
index 000000000000..9f25d58e01f8
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/TransformCriticalClasses.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+
+/*
+ * @test
+ * @summary AOT training run should fail if critical classes have been transformed by JVMTI
+ *          with ClassFileLoadHook
+ * @bug 8380409
+ * @requires vm.cds.supports.aot.class.linking
+ * @library /test/lib
+ * @build TransformCriticalClasses
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar TransformCriticalClassesApp
+ * @run main/othervm/native TransformCriticalClasses
+ */
+
+import java.util.ArrayList;
+import jdk.test.lib.cds.CDSTestUtils;
+import jdk.test.lib.helpers.ClassFileInstaller;
+import jdk.test.lib.process.ProcessTools;
+
+public class TransformCriticalClasses {
+    public static void main(String... args) throws Exception {
+        ArrayList processArgs = new ArrayList<>();
+
+        // Tell the native agent SimpleClassFileLoadHook to do an dummy transformation
+        // of java/lang/Class. This class will be defined using the exact same bytecodes
+        // as from the JDK, but the JVM will mark it as having been transformed by JVMTI
+        // and will exclude it from the AOT configuration file.
+        processArgs.add("-agentlib:SimpleClassFileLoadHook=-early,java/lang/Class,xxxxxx,xxxxxx");
+
+        processArgs.add("-XX:AOTMode=record");
+        processArgs.add("-XX:AOTConfiguration=app.aotconfig");
+        processArgs.add("-Xlog:aot,cds");
+        processArgs.add("-cp");
+        processArgs.add("app.jar");
+        processArgs.add("TransformCriticalClassesApp");
+
+        ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(processArgs);
+        CDSTestUtils.executeAndLog(pb, "train")
+            .shouldContain("Skipping java/lang/Class: From ClassFileLoadHook")
+            .shouldContain("Critical class java.lang.Class has been excluded. AOT configuration file cannot be written")
+            .shouldHaveExitValue(1);
+    }
+}
+
+class TransformCriticalClassesApp {
+    public static void main(String[] args) {
+        System.out.println("HelloWorld");
+    }
+}
diff --git a/test/hotspot/jtreg/runtime/vthread/RedefineClass.java b/test/hotspot/jtreg/runtime/vthread/RedefineClass.java
index 33a9d52a5232..b17bb55701bc 100644
--- a/test/hotspot/jtreg/runtime/vthread/RedefineClass.java
+++ b/test/hotspot/jtreg/runtime/vthread/RedefineClass.java
@@ -120,7 +120,7 @@ private static int getStringIndex(String needle, byte[] buf) {
 
     private static int getStringIndex(String needle, byte[] buf, int offset) {
         outer:
-        for (int i = offset; i < buf.length - offset - needle.length(); i++) {
+        for (int i = offset; i <= buf.length - needle.length(); i++) {
             for (int j = 0; j < needle.length(); j++) {
                 if (buf[i + j] != (byte)needle.charAt(j)) continue outer;
             }
diff --git a/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/MyRecord.java b/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/MyRecord.java
new file mode 100644
index 000000000000..e0f4ecc50f54
--- /dev/null
+++ b/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/MyRecord.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2026, Datadog, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@MyTypeAnnotation
+public record MyRecord(@MyTypeUseAnnotation String filter) {
+    public static MyRecord parse(String param) {
+        if (param == null) {
+            throw new IllegalArgumentException("Filter cannot be null");
+        }
+        return new MyRecord(param);
+    }
+}
+
+@Target({ElementType.TYPE})
+@Retention(RetentionPolicy.RUNTIME)
+@interface MyTypeAnnotation {
+}
+
+@Target({ElementType.TYPE_USE})
+@Retention(RetentionPolicy.RUNTIME)
+@interface MyTypeUseAnnotation {
+}
diff --git a/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/TestRetransformRecord.java b/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/TestRetransformRecord.java
new file mode 100644
index 000000000000..e8f1ba176d1b
--- /dev/null
+++ b/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/TestRetransformRecord.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2026, Datadog, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8376185
+ * @summary Class retransformation on a record type annotation
+ * @comment This is will rewrite the constant pool and process
+ * @comment the type annotation
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * @modules java.compiler
+ *          java.instrument
+ * @compile ../NamedBuffer.java
+ * @compile altered/MyRecord.jcod
+ * @run driver jdk.test.lib.helpers.ClassFileInstaller MyRecord
+ * @compile MyRecord.java
+ * @run main RedefineClassHelper
+ * @run main/othervm -javaagent:redefineagent.jar -Xlog:redefine*=debug TestRetransformRecord
+ */
+
+/*
+ * This test is loading a record with type annotation first, then by
+ * calling retransformClasses, we inject a slightly different record classfile
+ * where just some constants from the constant pools were swapped.
+ * It triggers, during the retransformation, a rewrite of the constant pool
+ * calling VM_RedefineClasses::rewrite_cp_refs_in_record_attribute method.
+ */
+import java.io.File;
+import java.io.FileInputStream;
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.Instrumentation;
+import java.security.ProtectionDomain;
+
+public class TestRetransformRecord {
+    static final String SRC = System.getProperty("test.src");
+    static final String DEST = System.getProperty("test.classes");
+
+    public static void main(String[] args) throws Exception {
+        MyRecord.parse("foo");
+        File clsfile = new File("MyRecord.class");
+        byte[] buf = null;
+        try (FileInputStream str = new FileInputStream(clsfile)) {
+            buf = NamedBuffer.loadBufferFromStream(str);
+        }
+        Instrumentation inst = RedefineClassHelper.instrumentation;
+        inst.addTransformer(new IdentityTransformer("MyRecord", buf), true);
+        inst.retransformClasses(MyRecord.class);
+        System.out.println(MyRecord.parse("foo"));
+    }
+}
+
+class IdentityTransformer implements ClassFileTransformer {
+    private final String className;
+    private final byte[] buffer;
+
+    public IdentityTransformer(String className, byte[] buffer) {
+        this.className = className;
+        this.buffer = buffer;
+    }
+
+    @Override
+    public byte[] transform(ClassLoader loader,
+                            String classPath,
+                            Class classBeingRedefined,
+                            ProtectionDomain protectionDomain,
+                            byte[] classfileBuffer) {
+        if (classPath != null && classPath.equals(className.replace('.', '/'))) {
+            System.out.println("Transforming " + className);
+            return buffer;
+        }
+        return null;
+    }
+}
diff --git a/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/altered/MyRecord.jcod b/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/altered/MyRecord.jcod
new file mode 100644
index 000000000000..ef2d01c89ba4
--- /dev/null
+++ b/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/altered/MyRecord.jcod
@@ -0,0 +1,421 @@
+/*
+ * Copyright (c) 2026, Datadog, Inc. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * This is a jcod version of the MyRecord classfile. 
+ * Generated from runnning java -jar asmtools.jar jdec MyRecord.class
+ * Then slightly modified to trigger constant pool rewrite.
+ * Here the following modifications:
+ * - constants #10 and #11 were swapped
+ * - constants #14 and #34 were swapped
+ */
+class MyRecord {
+  0xCAFEBABE;
+  0;                                       // minor version
+  69;                                      // version
+  [] {                                     // Constant Pool
+    ;                                      // first element is empty
+    Method #2 #3;                          // #1
+    class #4;                              // #2
+    NameAndType #5 #6;                     // #3
+    Utf8 "java/lang/Record";               // #4
+    Utf8 "";                         // #5
+    Utf8 "()V";                            // #6
+    Field #8 #9;                           // #7
+    class #11;                             // #8
+    NameAndType #10 #12;                   // #9
+    Utf8 "filter";                         // #10
+    Utf8 "MyRecord";                       // #11
+    Utf8 "Ljava/lang/String;";             // #12
+    class #34;                             // #13
+    Utf8 "LMyTypeUseAnnotation;";          // #14
+    String #16;                            // #15
+    Utf8 "Filter cannot be null";          // #16
+    Method #13 #18;                        // #17
+    NameAndType #5 #19;                    // #18
+    Utf8 "(Ljava/lang/String;)V";          // #19
+    Method #8 #18;                         // #20
+    InvokeDynamic 0s #22;                  // #21
+    NameAndType #23 #24;                   // #22
+    Utf8 "toString";                       // #23
+    Utf8 "(LMyRecord;)Ljava/lang/String;";  // #24
+    InvokeDynamic 0s #26;                  // #25
+    NameAndType #27 #28;                   // #26
+    Utf8 "hashCode";                       // #27
+    Utf8 "(LMyRecord;)I";                  // #28
+    InvokeDynamic 0s #30;                  // #29
+    NameAndType #31 #32;                   // #30
+    Utf8 "equals";                         // #31
+    Utf8 "(LMyRecord;Ljava/lang/Object;)Z";  // #32
+    Utf8 "RuntimeVisibleTypeAnnotations";  // #33
+    Utf8 "java/lang/IllegalArgumentException";  // #34
+    Utf8 "Code";                           // #35
+    Utf8 "LineNumberTable";                // #36
+    Utf8 "LocalVariableTable";             // #37
+    Utf8 "this";                           // #38
+    Utf8 "LMyRecord;";                     // #39
+    Utf8 "MethodParameters";               // #40
+    Utf8 "parse";                          // #41
+    Utf8 "(Ljava/lang/String;)LMyRecord;";  // #42
+    Utf8 "param";                          // #43
+    Utf8 "StackMapTable";                  // #44
+    Utf8 "()Ljava/lang/String;";           // #45
+    Utf8 "()I";                            // #46
+    Utf8 "(Ljava/lang/Object;)Z";          // #47
+    Utf8 "o";                              // #48
+    Utf8 "Ljava/lang/Object;";             // #49
+    Utf8 "SourceFile";                     // #50
+    Utf8 "MyRecord.java";                  // #51
+    Utf8 "RuntimeVisibleAnnotations";      // #52
+    Utf8 "LMyTypeAnnotation;";             // #53
+    Utf8 "Record";                         // #54
+    Utf8 "BootstrapMethods";               // #55
+    String #10;                            // #56
+    MethodHandle 1b #7;                    // #57
+    MethodHandle 6b #59;                   // #58
+    Method #60 #61;                        // #59
+    class #62;                             // #60
+    NameAndType #63 #64;                   // #61
+    Utf8 "java/lang/runtime/ObjectMethods";  // #62
+    Utf8 "bootstrap";                      // #63
+    Utf8 "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/TypeDescriptor;Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/invoke/MethodHandle;)Ljava/lang/Object;";  // #64
+    Utf8 "InnerClasses";                   // #65
+    class #67;                             // #66
+    Utf8 "java/lang/invoke/MethodHandles$Lookup";  // #67
+    class #69;                             // #68
+    Utf8 "java/lang/invoke/MethodHandles";  // #69
+    Utf8 "Lookup";                         // #70
+  }
+
+  0x0031;                                  // access
+  #8;                                      // this_cpx
+  #2;                                      // super_cpx
+
+  [] {                                     // Interfaces
+  }                                        // end of Interfaces
+
+  [] {                                     // Fields
+    {                                      // field
+      0x0012;                              // access
+      #10;                                 // name_index
+      #12;                                 // descriptor_index
+      [] {                                 // Attributes
+        Attr(#33) {                        // RuntimeVisibleTypeAnnotations
+          [] {                             // annotations
+            {                              // type_annotation
+              0x13;                        // target_type: FIELD
+              []b {                        // type_paths
+              }
+              #14;
+              [] {                         // element_value_pairs
+              }                            // element_value_pairs
+            }                              // type_annotation
+          }
+        }                                  // end of RuntimeVisibleTypeAnnotations
+      }                                    // end of Attributes
+    }
+  }                                        // end of Fields
+
+  [] {                                     // Methods
+    {                                      // method
+      0x0001;                              // access
+      #5;                                  // name_index
+      #19;                                 // descriptor_index
+      [] {                                 // Attributes
+        Attr(#35) {                        // Code
+          2;                               // max_stack
+          2;                               // max_locals
+          Bytes[]{
+            0x2A 0xB7 0x00 0x01 0x2A 0x2B 0xB5 0x00 0x07 0xB1;
+          }
+          [] {                             // Traps
+          }                                // end of Traps
+          [] {                             // Attributes
+            Attr(#36) {                    // LineNumberTable
+              [] {                         // line_number_table
+                   0    7;
+              }
+            }                              // end of LineNumberTable
+            ;
+            Attr(#37) {                    // LocalVariableTable
+              [] {                         // LocalVariableTable
+                   0   10   38   39   0;
+                   0   10   11   12   1;
+              }
+            }                              // end of LocalVariableTable
+          }                                // end of Attributes
+        }                                  // end of Code
+        ;
+        Attr(#40) {                        // MethodParameters
+          []b {                            // MethodParameters
+            #10  0x0000;
+          }
+        }                                  // end of MethodParameters
+        ;
+        Attr(#33) {                        // RuntimeVisibleTypeAnnotations
+          [] {                             // annotations
+            {                              // type_annotation
+              0x16;                        // target_type: METHOD_FORMAL_PARAMETER
+              0x00;                        // parameter_index
+              []b {                        // type_paths
+              }
+              #14;
+              [] {                         // element_value_pairs
+              }                            // element_value_pairs
+            }                              // type_annotation
+          }
+        }                                  // end of RuntimeVisibleTypeAnnotations
+      }                                    // end of Attributes
+    }
+    ;
+    {                                      // method
+      0x0009;                              // access
+      #41;                                 // name_index
+      #42;                                 // descriptor_index
+      [] {                                 // Attributes
+        Attr(#35) {                        // Code
+          3;                               // max_stack
+          1;                               // max_locals
+          Bytes[]{
+            0x2A 0xC7 0x00 0x0D 0xBB 0x00 0x0D 0x59 0x12 0x0F 0xB7 0x00;
+            0x11 0xBF 0xBB 0x00 0x08 0x59 0x2A 0xB7 0x00 0x14 0xB0;
+          }
+          [] {                             // Traps
+          }                                // end of Traps
+          [] {                             // Attributes
+            Attr(#36) {                    // LineNumberTable
+              [] {                         // line_number_table
+                   0    9;
+                   4   10;
+                  14   12;
+              }
+            }                              // end of LineNumberTable
+            ;
+            Attr(#37) {                    // LocalVariableTable
+              [] {                         // LocalVariableTable
+                   0   23   43   12   0;
+              }
+            }                              // end of LocalVariableTable
+            ;
+            Attr(#44) {                    // StackMapTable
+              [] {                         // 
+                14b;                       // same_frame
+              }
+            }                              // end of StackMapTable
+          }                                // end of Attributes
+        }                                  // end of Code
+      }                                    // end of Attributes
+    }
+    ;
+    {                                      // method
+      0x0011;                              // access
+      #23;                                 // name_index
+      #45;                                 // descriptor_index
+      [] {                                 // Attributes
+        Attr(#35) {                        // Code
+          1;                               // max_stack
+          1;                               // max_locals
+          Bytes[]{
+            0x2A 0xBA 0x00 0x15 0x00 0x00 0xB0;
+          }
+          [] {                             // Traps
+          }                                // end of Traps
+          [] {                             // Attributes
+            Attr(#36) {                    // LineNumberTable
+              [] {                         // line_number_table
+                   0    6;
+              }
+            }                              // end of LineNumberTable
+            ;
+            Attr(#37) {                    // LocalVariableTable
+              [] {                         // LocalVariableTable
+                   0    7   38   39   0;
+              }
+            }                              // end of LocalVariableTable
+          }                                // end of Attributes
+        }                                  // end of Code
+      }                                    // end of Attributes
+    }
+    ;
+    {                                      // method
+      0x0011;                              // access
+      #27;                                 // name_index
+      #46;                                 // descriptor_index
+      [] {                                 // Attributes
+        Attr(#35) {                        // Code
+          1;                               // max_stack
+          1;                               // max_locals
+          Bytes[]{
+            0x2A 0xBA 0x00 0x19 0x00 0x00 0xAC;
+          }
+          [] {                             // Traps
+          }                                // end of Traps
+          [] {                             // Attributes
+            Attr(#36) {                    // LineNumberTable
+              [] {                         // line_number_table
+                   0    6;
+              }
+            }                              // end of LineNumberTable
+            ;
+            Attr(#37) {                    // LocalVariableTable
+              [] {                         // LocalVariableTable
+                   0    7   38   39   0;
+              }
+            }                              // end of LocalVariableTable
+          }                                // end of Attributes
+        }                                  // end of Code
+      }                                    // end of Attributes
+    }
+    ;
+    {                                      // method
+      0x0011;                              // access
+      #31;                                 // name_index
+      #47;                                 // descriptor_index
+      [] {                                 // Attributes
+        Attr(#35) {                        // Code
+          2;                               // max_stack
+          2;                               // max_locals
+          Bytes[]{
+            0x2A 0x2B 0xBA 0x00 0x1D 0x00 0x00 0xAC          }
+          [] {                             // Traps
+          }                                // end of Traps
+          [] {                             // Attributes
+            Attr(#36) {                    // LineNumberTable
+              [] {                         // line_number_table
+                   0    6;
+              }
+            }                              // end of LineNumberTable
+            ;
+            Attr(#37) {                    // LocalVariableTable
+              [] {                         // LocalVariableTable
+                   0    8   38   39   0;
+                   0    8   48   49   1;
+              }
+            }                              // end of LocalVariableTable
+          }                                // end of Attributes
+        }                                  // end of Code
+      }                                    // end of Attributes
+    }
+    ;
+    {                                      // method
+      0x0001;                              // access
+      #10;                                 // name_index
+      #45;                                 // descriptor_index
+      [] {                                 // Attributes
+        Attr(#35) {                        // Code
+          1;                               // max_stack
+          1;                               // max_locals
+          Bytes[]{
+            0x2A 0xB4 0x00 0x07 0xB0;
+          }
+          [] {                             // Traps
+          }                                // end of Traps
+          [] {                             // Attributes
+            Attr(#36) {                    // LineNumberTable
+              [] {                         // line_number_table
+                   0    6;
+              }
+            }                              // end of LineNumberTable
+            ;
+            Attr(#37) {                    // LocalVariableTable
+              [] {                         // LocalVariableTable
+                   0    5   38   39   0;
+              }
+            }                              // end of LocalVariableTable
+          }                                // end of Attributes
+        }                                  // end of Code
+        ;
+        Attr(#33) {                        // RuntimeVisibleTypeAnnotations
+          [] {                             // annotations
+            {                              // type_annotation
+              0x14;                        // target_type: METHOD_RETURN
+              []b {                        // type_paths
+              }
+              #14;
+              [] {                         // element_value_pairs
+              }                            // element_value_pairs
+            }                              // type_annotation
+          }
+        }                                  // end of RuntimeVisibleTypeAnnotations
+      }                                    // end of Attributes
+    }
+  }                                        // end of Methods
+
+  [] {                                     // Attributes
+    Attr(#50) {                            // SourceFile
+      #51;
+    }                                      // end of SourceFile
+    ;
+    Attr(#52) {                            // RuntimeVisibleAnnotations
+      [] {                                 // annotations
+        {                                  // annotation
+          #53;
+          [] {                             // element_value_pairs
+          }                                // element_value_pairs
+        }                                  // annotation
+      }
+    }                                      // end of RuntimeVisibleAnnotations
+    ;
+    Attr(#54) {                            // Record
+      [] {                                 // components
+        {                                  // component
+          #10;                             // name_index
+          #12;                             // descriptor_index
+          [] {                             // Attributes
+            Attr(#33) {                    // RuntimeVisibleTypeAnnotations
+              [] {                         // annotations
+                {                          // type_annotation
+                  0x13;                    // target_type: FIELD
+                  []b {                    // type_paths
+                  }
+                  #14;
+                  [] {                     // element_value_pairs
+                  }                        // element_value_pairs
+                }                          // type_annotation
+              }
+            }                              // end of RuntimeVisibleTypeAnnotations
+          }                                // end of Attributes
+        }
+      }
+    }                                      // end of Record
+    ;
+    Attr(#55) {                            // BootstrapMethods
+      [] {                                 // bootstrap_methods
+        {                                  // bootstrap_method
+          #58;                             // bootstrap_method_ref
+          [] {                             // bootstrap_arguments
+            #8;
+            #56;
+            #57;
+          }                                // bootstrap_arguments
+        }                                  // bootstrap_method
+      }
+    }                                      // end of BootstrapMethods
+    ;
+    Attr(#65) {                            // InnerClasses
+      [] {                                 // classes
+          #66   #68   #70  25;
+      }
+    }                                      // end of InnerClasses
+  }                                        // end of Attributes
+}
diff --git a/test/jdk/java/net/httpclient/ALPNProxyFailureTest.java b/test/jdk/java/net/httpclient/ALPNProxyFailureTest.java
index ca2e95b70feb..4dedfed97b12 100644
--- a/test/jdk/java/net/httpclient/ALPNProxyFailureTest.java
+++ b/test/jdk/java/net/httpclient/ALPNProxyFailureTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,14 +44,9 @@
 
 public class ALPNProxyFailureTest extends ALPNFailureTest {
 
-    static final SSLContext context;
+    private static final SSLContext context = SimpleSSLContext.findSSLContext();
     static {
-        try {
-            context = new SimpleSSLContext().get();
-            SSLContext.setDefault(context);
-        } catch (Exception x) {
-            throw new ExceptionInInitializerError(x);
-        }
+        SSLContext.setDefault(context);
     }
 
     public static void main(String[] args) throws Exception{
diff --git a/test/jdk/java/net/httpclient/AbstractNoBody.java b/test/jdk/java/net/httpclient/AbstractNoBody.java
index 603fe16d2165..9367cfb090de 100644
--- a/test/jdk/java/net/httpclient/AbstractNoBody.java
+++ b/test/jdk/java/net/httpclient/AbstractNoBody.java
@@ -53,7 +53,7 @@
 
 public abstract class AbstractNoBody implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;         // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;       // HTTPS/1.1
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -154,9 +154,6 @@ public void close() {
     public void setup() throws Exception {
         printStamp(START, "setup");
         HttpServerAdapters.enableServerLogging();
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
 
         // HTTP/1.1
         HttpTestHandler h1_fixedLengthNoBodyHandler = new FixedLengthNoBodyHandler();
diff --git a/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java b/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java
index 5cabe36093f8..4ca54557823c 100644
--- a/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java
+++ b/test/jdk/java/net/httpclient/AbstractThrowingPublishers.java
@@ -76,7 +76,7 @@
 
 public abstract class AbstractThrowingPublishers implements HttpServerAdapters {
 
-    static SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     static HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
     static HttpTestServer httpsTestServer;   // HTTPS/1.1
     static HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -693,10 +693,6 @@ public static void setup() throws Exception {
         System.out.println(now() + "setup");
         System.err.println(now() + "setup");
 
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/1.1
         HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler();
         HttpTestHandler h1_chunkHandler = new HTTP_ChunkedHandler();
diff --git a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java
index 50200c86b430..ab1378f4789d 100644
--- a/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java
+++ b/test/jdk/java/net/httpclient/AbstractThrowingPushPromises.java
@@ -93,7 +93,6 @@
 
 import org.junit.jupiter.api.Assumptions;
 import org.junit.jupiter.api.BeforeAll;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.TestInstance;
 import org.junit.jupiter.api.extension.BeforeEachCallback;
 import org.junit.jupiter.api.extension.ExtensionContext;
@@ -103,7 +102,7 @@
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
 public abstract class AbstractThrowingPushPromises implements HttpServerAdapters {
 
-    static SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     static HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
     static HttpTestServer https2TestServer;  // HTTP/2 ( h2  )
     static String http2URI_fixed;
@@ -732,10 +731,6 @@ public CompletionStage getBody() {
 
     @BeforeAll
     public static void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/2
         HttpTestHandler h2_fixedLengthHandler = new HTTP_FixedLengthHandler();
         HttpTestHandler h2_chunkedHandler = new HTTP_ChunkedHandler();
diff --git a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java
index 20d8a332263a..7511768de69c 100644
--- a/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java
+++ b/test/jdk/java/net/httpclient/AbstractThrowingSubscribers.java
@@ -76,7 +76,7 @@
 
 public abstract class AbstractThrowingSubscribers implements HttpServerAdapters {
 
-    static SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     static HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
     static HttpTestServer httpsTestServer;   // HTTPS/1.1
     static HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -759,10 +759,6 @@ public static void setup() throws Exception {
         System.out.println(now() + "setup");
         System.err.println(now() + "setup");
 
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/1.1
         HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler();
         HttpTestHandler h1_chunkHandler = new HTTP_ChunkedHandler();
diff --git a/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java b/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java
index a879525b4b4b..ca5dfd8e59a5 100644
--- a/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java
+++ b/test/jdk/java/net/httpclient/AggregateRequestBodyTest.java
@@ -90,7 +90,7 @@
 
 public class AggregateRequestBodyTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer http1TestServer;   // HTTP/1.1 ( http )
     HttpTestServer https1TestServer;  // HTTPS/1.1 ( https  )
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -831,10 +831,6 @@ public void test(String uri, boolean sameClient) throws Exception {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         HttpTestHandler handler = new HttpTestEchoHandler();
         http1TestServer = HttpTestServer.create(HTTP_1_1);
         http1TestServer.addHandler(handler, "/http1/echo/");
diff --git a/test/jdk/java/net/httpclient/AsFileDownloadTest.java b/test/jdk/java/net/httpclient/AsFileDownloadTest.java
index 1ec267776968..8cb03428c757 100644
--- a/test/jdk/java/net/httpclient/AsFileDownloadTest.java
+++ b/test/jdk/java/net/httpclient/AsFileDownloadTest.java
@@ -80,7 +80,7 @@
  */
 public class AsFileDownloadTest {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpServer httpTestServer;         // HTTP/1.1    [ 4 servers ]
     HttpsServer httpsTestServer;       // HTTPS/1.1
     Http2TestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -317,10 +317,6 @@ public void setup() throws Exception {
         //ch.setLevel(Level.ALL);
         //logger.addHandler(ch);
 
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
         httpTestServer = HttpServer.create(sa, 0);
         httpTestServer.createContext("/http1/afdt", new Http1FileDispoHandler());
diff --git a/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java b/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java
index 7e7709c033cf..cef189412ca5 100644
--- a/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java
+++ b/test/jdk/java/net/httpclient/AsyncExecutorShutdown.java
@@ -94,7 +94,7 @@ public class AsyncExecutorShutdown implements HttpServerAdapters {
     }
     static final Random RANDOM = RandomFactory.getRandom();
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;        // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;       // HTTPS/1.1
     HttpTestServer http2TestServer;       // HTTP/2 ( h2c )
@@ -314,9 +314,6 @@ void testSequential(String uriString) throws Exception {
     @BeforeTest
     public void setup() throws Exception {
         out.println("\n**** Setup ****\n");
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
 
         httpTestServer = HttpTestServer.create(HTTP_1_1);
         httpTestServer.addHandler(new ServerRequestHandler(), "/http1/exec/");
diff --git a/test/jdk/java/net/httpclient/AsyncShutdownNow.java b/test/jdk/java/net/httpclient/AsyncShutdownNow.java
index 39c82735248f..09057ec4be7b 100644
--- a/test/jdk/java/net/httpclient/AsyncShutdownNow.java
+++ b/test/jdk/java/net/httpclient/AsyncShutdownNow.java
@@ -91,7 +91,7 @@ public class AsyncShutdownNow implements HttpServerAdapters {
     static final Random RANDOM = RandomFactory.getRandom();
 
     ExecutorService readerService;
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;        // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;       // HTTPS/1.1
     HttpTestServer http2TestServer;       // HTTP/2 ( h2c )
@@ -343,9 +343,6 @@ void testSequential(String uriString) throws Exception {
     @BeforeTest
     public void setup() throws Exception {
         out.println("\n**** Setup ****\n");
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
         readerService = Executors.newCachedThreadPool();
 
         httpTestServer = HttpTestServer.create(HTTP_1_1);
diff --git a/test/jdk/java/net/httpclient/AuthFilterCacheTest.java b/test/jdk/java/net/httpclient/AuthFilterCacheTest.java
index e819f96d9473..32c6b19de06f 100644
--- a/test/jdk/java/net/httpclient/AuthFilterCacheTest.java
+++ b/test/jdk/java/net/httpclient/AuthFilterCacheTest.java
@@ -65,15 +65,10 @@ public class AuthFilterCacheTest implements HttpServerAdapters {
     static final int REQUEST_COUNT = 5;
     static final int URI_COUNT = 6;
     static final CyclicBarrier barrier = new CyclicBarrier(REQUEST_COUNT * URI_COUNT);
-    static final SSLContext context;
+    private static final SSLContext context = jdk.test.lib.net.SimpleSSLContext.findSSLContext();
 
     static {
-        try {
-            context = new jdk.test.lib.net.SimpleSSLContext().get();
-            SSLContext.setDefault(context);
-        } catch (Exception x) {
-            throw new ExceptionInInitializerError(x);
-        }
+        SSLContext.setDefault(context);
     }
 
     HttpTestServer http1Server;
diff --git a/test/jdk/java/net/httpclient/BasicAuthTest.java b/test/jdk/java/net/httpclient/BasicAuthTest.java
index e0aec3b19b75..816f657b727f 100644
--- a/test/jdk/java/net/httpclient/BasicAuthTest.java
+++ b/test/jdk/java/net/httpclient/BasicAuthTest.java
@@ -68,7 +68,7 @@ public static void test(Version version, boolean secure) throws Exception {
 
         ExecutorService e = Executors.newCachedThreadPool();
         Handler h = new Handler();
-        SSLContext sslContext = secure ? new SimpleSSLContext().get() : null;
+        SSLContext sslContext = secure ? SimpleSSLContext.findSSLContext() : null;
         HttpTestServer server = HttpTestServer.create(version, sslContext, e);
         HttpTestContext serverContext = server.addHandler(h,"/test/");
         ServerAuth sa = new ServerAuth("foo realm");
diff --git a/test/jdk/java/net/httpclient/BasicRedirectTest.java b/test/jdk/java/net/httpclient/BasicRedirectTest.java
index 8ea1653b4d01..672a9eaaab2c 100644
--- a/test/jdk/java/net/httpclient/BasicRedirectTest.java
+++ b/test/jdk/java/net/httpclient/BasicRedirectTest.java
@@ -63,7 +63,7 @@
 
 public class BasicRedirectTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;        // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;       // HTTPS/1.1
     HttpTestServer http2TestServer;       // HTTP/2 ( h2c )
@@ -207,10 +207,6 @@ void testNegatives(String uriString,Redirect redirectPolicy) throws Exception {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         httpTestServer = HttpTestServer.create(HTTP_1_1);
         httpTestServer.addHandler(new BasicHttpRedirectHandler(), "/http1/same/");
         httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/same/redirect";
diff --git a/test/jdk/java/net/httpclient/CancelRequestTest.java b/test/jdk/java/net/httpclient/CancelRequestTest.java
index e2ffe905d388..fa63fa617f34 100644
--- a/test/jdk/java/net/httpclient/CancelRequestTest.java
+++ b/test/jdk/java/net/httpclient/CancelRequestTest.java
@@ -90,7 +90,7 @@ public class CancelRequestTest implements HttpServerAdapters {
 
     private static final Random random = RandomFactory.getRandom();
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -592,10 +592,6 @@ public void testPostInterrupt(String uri, boolean sameClient)
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/1.1
         HttpTestHandler h1_chunkHandler = new HTTPSlowHandler();
         httpTestServer = HttpTestServer.create(HTTP_1_1);
diff --git a/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java b/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java
index e0199b18e681..d9f13c969eac 100644
--- a/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java
+++ b/test/jdk/java/net/httpclient/CancelStreamedBodyTest.java
@@ -92,7 +92,7 @@
 
 public class CancelStreamedBodyTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -339,10 +339,6 @@ public void testInputStream(String uri, boolean sameClient)
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/1.1
         HttpTestHandler h1_chunkHandler = new HTTPSlowHandler();
         httpTestServer = HttpTestServer.create(HTTP_1_1);
diff --git a/test/jdk/java/net/httpclient/CancelledResponse.java b/test/jdk/java/net/httpclient/CancelledResponse.java
index f69bf066ba2a..7e87fb8963f9 100644
--- a/test/jdk/java/net/httpclient/CancelledResponse.java
+++ b/test/jdk/java/net/httpclient/CancelledResponse.java
@@ -91,11 +91,10 @@ static String response(String body, boolean serverKeepalive) {
 
     static final ReferenceTracker TRACKER = ReferenceTracker.INSTANCE;
     final ServerSocketFactory factory;
-    final SSLContext context;
+    private static final SSLContext context = SimpleSSLContext.findSSLContext();
     final boolean useSSL;
     CancelledResponse(boolean useSSL) throws IOException {
         this.useSSL = useSSL;
-        context = new SimpleSSLContext().get();
         SSLContext.setDefault(context);
         factory = useSSL ? SSLServerSocketFactory.getDefault()
                          : ServerSocketFactory.getDefault();
diff --git a/test/jdk/java/net/httpclient/CancelledResponse2.java b/test/jdk/java/net/httpclient/CancelledResponse2.java
index 263620acf81d..a1839a4a6716 100644
--- a/test/jdk/java/net/httpclient/CancelledResponse2.java
+++ b/test/jdk/java/net/httpclient/CancelledResponse2.java
@@ -68,7 +68,7 @@ public class CancelledResponse2 {
 
     HttpTestServer h2TestServer;
     URI h2TestServerURI;
-    private SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     private static final Random random = RandomFactory.getRandom();
     private static final int MAX_CLIENT_DELAY = 160;
 
@@ -113,7 +113,6 @@ public void test(Version version, URI uri) throws Exception {
 
     @BeforeTest
     public void setup() throws IOException {
-        sslContext = new SimpleSSLContext().get();
         h2TestServer = HttpTestServer.create(HTTP_2, sslContext);
         h2TestServer.addHandler(new CancelledResponseHandler(), "/h2");
         h2TestServerURI = URI.create("https://" + h2TestServer.serverAuthority() + "/h2");
diff --git a/test/jdk/java/net/httpclient/ConcurrentResponses.java b/test/jdk/java/net/httpclient/ConcurrentResponses.java
index c68ebd0975cf..ea474815a305 100644
--- a/test/jdk/java/net/httpclient/ConcurrentResponses.java
+++ b/test/jdk/java/net/httpclient/ConcurrentResponses.java
@@ -81,7 +81,7 @@
 
 public class ConcurrentResponses {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpServer httpTestServer;         // HTTP/1.1    [ 4 servers ]
     HttpsServer httpsTestServer;       // HTTPS/1.1
     Http2TestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -280,10 +280,6 @@ static String serverAuthority(HttpServer server) {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
         httpTestServer = HttpServer.create(sa, 0);
         httpTestServer.createContext("/http1/fixed", new Http1FixedHandler());
diff --git a/test/jdk/java/net/httpclient/ContentLengthHeaderTest.java b/test/jdk/java/net/httpclient/ContentLengthHeaderTest.java
index 0ff21c23a8f0..8b88e2d67165 100644
--- a/test/jdk/java/net/httpclient/ContentLengthHeaderTest.java
+++ b/test/jdk/java/net/httpclient/ContentLengthHeaderTest.java
@@ -70,7 +70,7 @@ public class ContentLengthHeaderTest implements HttpServerAdapters {
     static HttpTestServer testContentLengthServerH1;
     static HttpTestServer testContentLengthServerH2;
     static PrintStream testLog = System.err;
-    static SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
 
     HttpClient hc;
     URI testContentLengthURIH1;
@@ -78,7 +78,6 @@ public class ContentLengthHeaderTest implements HttpServerAdapters {
 
     @BeforeTest
     public void setup() throws IOException, URISyntaxException {
-        sslContext = new SimpleSSLContext().get();
         testContentLengthServerH1 = HttpTestServer.create(HTTP_1_1);
         testContentLengthServerH2 = HttpTestServer.create(HTTP_2, sslContext);
 
diff --git a/test/jdk/java/net/httpclient/CookieHeaderTest.java b/test/jdk/java/net/httpclient/CookieHeaderTest.java
index b39a23371abf..feca75e827e4 100644
--- a/test/jdk/java/net/httpclient/CookieHeaderTest.java
+++ b/test/jdk/java/net/httpclient/CookieHeaderTest.java
@@ -81,7 +81,7 @@
 
 public class CookieHeaderTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;        // HTTP/1.1    [ 6 servers ]
     HttpTestServer httpsTestServer;       // HTTPS/1.1
     HttpTestServer http2TestServer;       // HTTP/2 ( h2c )
@@ -179,10 +179,6 @@ void test(String uriString, HttpClient.Version version) throws Exception {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         httpTestServer = HttpTestServer.create(HTTP_1_1);
         httpTestServer.addHandler(new CookieValidationHandler(), "/http1/cookie/");
         httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/cookie/retry";
diff --git a/test/jdk/java/net/httpclient/CustomRequestPublisher.java b/test/jdk/java/net/httpclient/CustomRequestPublisher.java
index 140a3a98ec4b..027447c92ced 100644
--- a/test/jdk/java/net/httpclient/CustomRequestPublisher.java
+++ b/test/jdk/java/net/httpclient/CustomRequestPublisher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,7 +65,7 @@
 
 public class CustomRequestPublisher implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;    // HTTP/1.1        [ 4 servers ]
     HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -304,10 +304,6 @@ public void cancel() {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
         httpTestServer = HttpTestServer.create(HTTP_1_1);
         httpTestServer.addHandler(new HttpTestEchoHandler(), "/http1/echo");
diff --git a/test/jdk/java/net/httpclient/CustomResponseSubscriber.java b/test/jdk/java/net/httpclient/CustomResponseSubscriber.java
index be71278a4503..2e061472bf26 100644
--- a/test/jdk/java/net/httpclient/CustomResponseSubscriber.java
+++ b/test/jdk/java/net/httpclient/CustomResponseSubscriber.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -70,7 +70,7 @@
 
 public class CustomResponseSubscriber {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpServer httpTestServer;         // HTTP/1.1    [ 4 servers ]
     HttpsServer httpsTestServer;       // HTTPS/1.1
     Http2TestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -187,10 +187,6 @@ static String serverAuthority(HttpServer server) {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/1.1
         HttpHandler h1_fixedLengthHandler = new HTTP1_FixedLengthHandler();
         HttpHandler h1_chunkHandler = new HTTP1_ChunkedHandler();
diff --git a/test/jdk/java/net/httpclient/DependentActionsTest.java b/test/jdk/java/net/httpclient/DependentActionsTest.java
index c1e9025fe4b7..863e42522e69 100644
--- a/test/jdk/java/net/httpclient/DependentActionsTest.java
+++ b/test/jdk/java/net/httpclient/DependentActionsTest.java
@@ -94,7 +94,7 @@
 
 public class DependentActionsTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -573,10 +573,6 @@ public CompletionStage getBody() {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/1.1
         HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler();
         HttpTestHandler h1_chunkHandler = new HTTP_ChunkedHandler();
diff --git a/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java b/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java
index e47f4be46f75..6f9bc37afb2a 100644
--- a/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java
+++ b/test/jdk/java/net/httpclient/DependentPromiseActionsTest.java
@@ -93,7 +93,7 @@
 
 public class DependentPromiseActionsTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
     HttpTestServer https2TestServer;  // HTTP/2 ( h2  )
     String http2URI_fixed;
@@ -665,10 +665,6 @@ public CompletionStage getBody() {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/2
         HttpTestHandler h2_fixedLengthHandler = new HTTP_FixedLengthHandler();
         HttpTestHandler h2_chunkedHandler = new HTTP_ChunkedHandler();
diff --git a/test/jdk/java/net/httpclient/DigestEchoClient.java b/test/jdk/java/net/httpclient/DigestEchoClient.java
index 0aa70a265869..96b7fd4745cb 100644
--- a/test/jdk/java/net/httpclient/DigestEchoClient.java
+++ b/test/jdk/java/net/httpclient/DigestEchoClient.java
@@ -162,14 +162,9 @@ public static void stop() {
 
     static final AtomicInteger NC = new AtomicInteger();
     static final Random random = new Random();
-    static final SSLContext context;
+    private static final SSLContext context = SimpleSSLContext.findSSLContext();
     static {
-        try {
-            context = new SimpleSSLContext().get();
-            SSLContext.setDefault(context);
-        } catch (Exception x) {
-            throw new ExceptionInInitializerError(x);
-        }
+        SSLContext.setDefault(context);
     }
     static final List BOOLEANS = List.of(true, false);
 
diff --git a/test/jdk/java/net/httpclient/EmptyAuthenticate.java b/test/jdk/java/net/httpclient/EmptyAuthenticate.java
index ca5c41594e80..8bd4ba471b6f 100644
--- a/test/jdk/java/net/httpclient/EmptyAuthenticate.java
+++ b/test/jdk/java/net/httpclient/EmptyAuthenticate.java
@@ -56,18 +56,10 @@
 
 class EmptyAuthenticate {
 
-    private static final SSLContext SSL_CONTEXT = createSslContext();
+    private static final SSLContext SSL_CONTEXT = SimpleSSLContext.findSSLContext();
 
     private static final String WWW_AUTH_HEADER_NAME = "WWW-Authenticate";
 
-    private static SSLContext createSslContext() {
-        try {
-            return new SimpleSSLContext().get();
-        } catch (IOException exception) {
-            throw new RuntimeException(exception);
-        }
-    }
-
     @ParameterizedTest
     @MethodSource("args")
     void test(Version version, boolean secure) throws Exception {
diff --git a/test/jdk/java/net/httpclient/EncodedCharsInURI.java b/test/jdk/java/net/httpclient/EncodedCharsInURI.java
index bcda1f325390..b026310fe1ac 100644
--- a/test/jdk/java/net/httpclient/EncodedCharsInURI.java
+++ b/test/jdk/java/net/httpclient/EncodedCharsInURI.java
@@ -85,7 +85,7 @@
 
 public class EncodedCharsInURI implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -272,10 +272,6 @@ public void testEncodedChars(String uri, boolean sameClient)
     public void setup() throws Exception {
         out.println(now() + "begin setup");
 
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/1.1
         HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler();
         HttpTestHandler h1_chunkHandler = new HTTP_ChunkedHandler();
diff --git a/test/jdk/java/net/httpclient/EscapedOctetsInURI.java b/test/jdk/java/net/httpclient/EscapedOctetsInURI.java
index 8a17cea78c42..a5ba2f168f46 100644
--- a/test/jdk/java/net/httpclient/EscapedOctetsInURI.java
+++ b/test/jdk/java/net/httpclient/EscapedOctetsInURI.java
@@ -66,7 +66,7 @@
 
 public class EscapedOctetsInURI implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -226,10 +226,6 @@ void testAsync(String uriString, boolean sameClient) throws Exception {
     public void setup() throws Exception {
         out.println(now() + "begin setup");
 
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
         httpTestServer = HttpTestServer.create(HTTP_1_1);
         httpTestServer.addHandler(new HttpASCIIUriStringHandler(), "/http1/get");
diff --git a/test/jdk/java/net/httpclient/ExecutorShutdown.java b/test/jdk/java/net/httpclient/ExecutorShutdown.java
index e829daa556b8..107c68199a58 100644
--- a/test/jdk/java/net/httpclient/ExecutorShutdown.java
+++ b/test/jdk/java/net/httpclient/ExecutorShutdown.java
@@ -90,7 +90,7 @@ public class ExecutorShutdown implements HttpServerAdapters {
     }
     static final Random RANDOM = RandomFactory.getRandom();
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;        // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;       // HTTPS/1.1
     HttpTestServer http2TestServer;       // HTTP/2 ( h2c )
@@ -277,10 +277,6 @@ void testSequential(String uriString) throws Exception {
     @BeforeTest
     public void setup() throws Exception {
         out.println("\n**** Setup ****\n");
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         httpTestServer = HttpTestServer.create(HTTP_1_1);
         httpTestServer.addHandler(new ServerRequestHandler(), "/http1/exec/");
         httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/exec/retry";
diff --git a/test/jdk/java/net/httpclient/ExpectContinue.java b/test/jdk/java/net/httpclient/ExpectContinue.java
index 43c657814138..a2d928e6f411 100644
--- a/test/jdk/java/net/httpclient/ExpectContinue.java
+++ b/test/jdk/java/net/httpclient/ExpectContinue.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,7 +60,7 @@
 
 public class ExpectContinue {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpServer httpTestServer;         // HTTP/1.1    [ 2 servers ]
     HttpsServer httpsTestServer;       // HTTPS/1.1
     String httpURI;
@@ -139,10 +139,6 @@ static String serverAuthority(HttpServer server) {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
         httpTestServer = HttpServer.create(sa, 0);
         httpTestServer.createContext("/http1/ec", new Http1ExpectContinueHandler());
diff --git a/test/jdk/java/net/httpclient/FilePublisherTest.java b/test/jdk/java/net/httpclient/FilePublisherTest.java
index 8bb679a2e749..77e7e566aa60 100644
--- a/test/jdk/java/net/httpclient/FilePublisherTest.java
+++ b/test/jdk/java/net/httpclient/FilePublisherTest.java
@@ -63,7 +63,7 @@
 import static org.testng.Assert.assertEquals;
 
 public class FilePublisherTest implements HttpServerAdapters {
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpServerAdapters.HttpTestServer httpTestServer;    // HTTP/1.1      [ 4 servers ]
     HttpServerAdapters.HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpServerAdapters.HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -185,10 +185,6 @@ private void send(String uriString,
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         defaultFsPath = defaultFsFile();
         zipFs = newZipFs();
         zipFsPath = zipFsFile(zipFs);
diff --git a/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java b/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java
index 5d0935d72163..2e4e7b4d6ff9 100644
--- a/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java
+++ b/test/jdk/java/net/httpclient/FlowAdapterPublisherTest.java
@@ -66,7 +66,7 @@
 
 public class FlowAdapterPublisherTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;     // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;    // HTTPS/1.1
     HttpTestServer http2TestServer;    // HTTP/2 ( h2c )
@@ -358,10 +358,6 @@ public void cancel() {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         httpTestServer = HttpTestServer.create(Version.HTTP_1_1);
         httpTestServer.addHandler(new HttpEchoHandler(), "/http1/echo");
         httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/echo";
diff --git a/test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java b/test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java
index 8319204f5c2e..2e9ad532adc2 100644
--- a/test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java
+++ b/test/jdk/java/net/httpclient/FlowAdapterSubscriberTest.java
@@ -73,7 +73,7 @@
 
 public class FlowAdapterSubscriberTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;     // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;    // HTTPS/1.1
     HttpTestServer http2TestServer;    // HTTP/2 ( h2c )
@@ -616,10 +616,6 @@ static final  HttpResponse assert200ResponseCode(HttpResponse response)
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         httpTestServer = HttpTestServer.create(Version.HTTP_1_1);
         httpTestServer.addHandler(new HttpEchoHandler(), "/http1/echo");
         httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/echo";
diff --git a/test/jdk/java/net/httpclient/ForbiddenHeadTest.java b/test/jdk/java/net/httpclient/ForbiddenHeadTest.java
index 1498aa118b32..bccb141a1abf 100644
--- a/test/jdk/java/net/httpclient/ForbiddenHeadTest.java
+++ b/test/jdk/java/net/httpclient/ForbiddenHeadTest.java
@@ -84,11 +84,10 @@
 import static java.net.http.HttpClient.Version.HTTP_2;
 import static java.nio.charset.StandardCharsets.UTF_8;
 import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertNotNull;
 
 public class ForbiddenHeadTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;        // HTTP/1.1
     HttpTestServer httpsTestServer;       // HTTPS/1.1
     HttpTestServer http2TestServer;       // HTTP/2 ( h2c )
@@ -330,10 +329,6 @@ private void doTest(String uriString, int code, boolean async, HttpClient client
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         httpTestServer = HttpTestServer.create(HTTP_1_1);
         httpTestServer.addHandler(new UnauthorizedHandler(), "/http1/");
         httpTestServer.addHandler(new UnauthorizedHandler(), "/http2/proxy/");
diff --git a/test/jdk/java/net/httpclient/GZIPInputStreamTest.java b/test/jdk/java/net/httpclient/GZIPInputStreamTest.java
index 1215fc6c0a0b..5c77e3a55f62 100644
--- a/test/jdk/java/net/httpclient/GZIPInputStreamTest.java
+++ b/test/jdk/java/net/httpclient/GZIPInputStreamTest.java
@@ -72,7 +72,7 @@
 
 public class GZIPInputStreamTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -536,10 +536,6 @@ static String serverAuthority(HttpServer server) {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         HttpTestHandler plainHandler = new LoremIpsumPlainHandler();
         HttpTestHandler gzipHandler  = new LoremIpsumGZIPHandler();
 
diff --git a/test/jdk/java/net/httpclient/HeadTest.java b/test/jdk/java/net/httpclient/HeadTest.java
index 5b3b1671d437..4826046e9f2b 100644
--- a/test/jdk/java/net/httpclient/HeadTest.java
+++ b/test/jdk/java/net/httpclient/HeadTest.java
@@ -62,7 +62,7 @@
 
 public class HeadTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;        // HTTP/1.1
     HttpTestServer httpsTestServer;       // HTTPS/1.1
     HttpTestServer http2TestServer;       // HTTP/2 ( h2c )
@@ -148,10 +148,6 @@ private void doTest(HttpRequest request, int expResp) throws Exception {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
 
         httpTestServer = HttpTestServer.create(HTTP_1_1);
diff --git a/test/jdk/java/net/httpclient/HttpClientAuthRetryLimitTest.java b/test/jdk/java/net/httpclient/HttpClientAuthRetryLimitTest.java
index 818fd8c7a017..4cfee56e8555 100644
--- a/test/jdk/java/net/httpclient/HttpClientAuthRetryLimitTest.java
+++ b/test/jdk/java/net/httpclient/HttpClientAuthRetryLimitTest.java
@@ -56,15 +56,7 @@
 
 class HttpClientAuthRetryLimitTest implements HttpServerAdapters {
 
-    private static final SSLContext SSL_CONTEXT = createSslContext();
-
-    private static SSLContext createSslContext() {
-        try {
-            return new SimpleSSLContext().get();
-        } catch (IOException exception) {
-            throw new RuntimeException(exception);
-        }
-    }
+    private static final SSLContext SSL_CONTEXT = SimpleSSLContext.findSSLContext();
 
     // This is the system default value for jdk.httpclient.auth.retrylimit
     private static final int DEFAULT_RETRY_LIMIT = 3;
diff --git a/test/jdk/java/net/httpclient/HttpClientBuilderTest.java b/test/jdk/java/net/httpclient/HttpClientBuilderTest.java
index 451221c6e23e..2e3014387bb4 100644
--- a/test/jdk/java/net/httpclient/HttpClientBuilderTest.java
+++ b/test/jdk/java/net/httpclient/HttpClientBuilderTest.java
@@ -304,18 +304,18 @@ public void testSSLParameters() {
     @Test
     public void testSSLContext() throws Exception {
         HttpClient.Builder builder = HttpClient.newBuilder();
-        SSLContext a = (new SimpleSSLContext()).get();
+        SSLContext a = SimpleSSLContext.findSSLContext();
         builder.sslContext(a);
         try (var closer = closeable(builder)) {
             assertTrue(closer.build().sslContext() == a);
         }
-        SSLContext b = (new SimpleSSLContext()).get();
+        SSLContext b = SimpleSSLContext.findSSLContext();
         builder.sslContext(b);
         try (var closer = closeable(builder)) {
             assertTrue(closer.build().sslContext() == b);
         }
         assertThrows(NPE, () -> builder.sslContext(null));
-        SSLContext c = (new SimpleSSLContext()).get();
+        SSLContext c = SimpleSSLContext.findSSLContext();
         builder.sslContext(c);
         try (var closer = closeable(builder)) {
             assertTrue(closer.build().sslContext() == c);
diff --git a/test/jdk/java/net/httpclient/HttpClientClose.java b/test/jdk/java/net/httpclient/HttpClientClose.java
index 0425d27a25eb..287b9311d15c 100644
--- a/test/jdk/java/net/httpclient/HttpClientClose.java
+++ b/test/jdk/java/net/httpclient/HttpClientClose.java
@@ -95,7 +95,7 @@ public class HttpClientClose implements HttpServerAdapters {
     static final Random RANDOM = RandomFactory.getRandom();
 
     ExecutorService readerService;
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;        // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;       // HTTPS/1.1
     HttpTestServer http2TestServer;       // HTTP/2 ( h2c )
@@ -279,9 +279,6 @@ void testSequential(String uriString) throws Exception {
     @BeforeTest
     public void setup() throws Exception {
         out.println("\n**** Setup ****\n");
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
         readerService = Executors.newCachedThreadPool();
         httpTestServer = HttpTestServer.create(HTTP_1_1);
         httpTestServer.addHandler(new ServerRequestHandler(), "/http1/exec/");
diff --git a/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java b/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java
index e9d5fe6bffe7..10cca6972319 100644
--- a/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java
+++ b/test/jdk/java/net/httpclient/HttpClientLocalAddrTest.java
@@ -69,7 +69,7 @@
  */
 public class HttpClientLocalAddrTest implements HttpServerAdapters {
 
-    private static SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     private static HttpServerAdapters.HttpTestServer http1_1_Server;
     private static URI httpURI;
     private static HttpServerAdapters.HttpTestServer https_1_1_Server;
@@ -83,9 +83,6 @@ public class HttpClientLocalAddrTest implements HttpServerAdapters {
     // start various HTTP/HTTPS servers that will be invoked against in the tests
     @BeforeClass
     public static void beforeClass() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        Assert.assertNotNull(sslContext, "Unexpected null sslContext");
-
         HttpServerAdapters.HttpTestHandler handler = (exchange) -> {
             // the handler receives a request and sends back a 200 response with the
             // response body containing the raw IP address (in byte[] form) of the client from whom
diff --git a/test/jdk/java/net/httpclient/HttpClientSNITest.java b/test/jdk/java/net/httpclient/HttpClientSNITest.java
index 095508fd849f..1f7377f745da 100644
--- a/test/jdk/java/net/httpclient/HttpClientSNITest.java
+++ b/test/jdk/java/net/httpclient/HttpClientSNITest.java
@@ -95,8 +95,7 @@ public void handle(final HttpTestExchange exch) throws IOException {
     @ParameterizedTest
     @ValueSource(booleans = {false, true})
     void testRequestToIPLiteralHost(final boolean sniConfiguredOnClient) throws Exception {
-        final SSLContext sslContext = new SimpleSSLContext().get();
-        assertNotNull(sslContext, "could not create a SSLContext");
+        final SSLContext sslContext = SimpleSSLContext.findSSLContext();
         final String expectedSNI = "non-dns-resolvable.foo.bar.localhost";
         final ServerNameMatcher matcher = new ServerNameMatcher(expectedSNI);
         final HttpTestServer server = createServer(matcher, sslContext);
@@ -149,8 +148,7 @@ void testRequestToIPLiteralHost(final boolean sniConfiguredOnClient) throws Exce
     @ParameterizedTest
     @ValueSource(booleans = {false, true})
     void testRequestResolvedHostName(final boolean sniConfiguredOnClient) throws Exception {
-        final SSLContext sslContext = new SimpleSSLContext().get();
-        assertNotNull(sslContext, "could not create a SSLContext");
+        final SSLContext sslContext = SimpleSSLContext.findSSLContext();
         final String resolvedHostName = InetAddress.getLoopbackAddress().getHostName();
         final String expectedSNI = resolvedHostName;
         final ServerNameMatcher matcher = new ServerNameMatcher(expectedSNI);
diff --git a/test/jdk/java/net/httpclient/HttpClientShutdown.java b/test/jdk/java/net/httpclient/HttpClientShutdown.java
index 3c77881c8aa9..bff0ef6e5f91 100644
--- a/test/jdk/java/net/httpclient/HttpClientShutdown.java
+++ b/test/jdk/java/net/httpclient/HttpClientShutdown.java
@@ -96,7 +96,7 @@ public class HttpClientShutdown implements HttpServerAdapters {
     static final Random RANDOM = RandomFactory.getRandom();
 
     ExecutorService readerService;
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;        // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;       // HTTPS/1.1
     HttpTestServer http2TestServer;       // HTTP/2 ( h2c )
@@ -413,9 +413,6 @@ void testSequential(String uriString) throws Exception {
     @BeforeTest
     public void setup() throws Exception {
         out.println("\n**** Setup ****\n");
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
         readerService = Executors.newCachedThreadPool();
 
         httpTestServer = HttpTestServer.create(HTTP_1_1);
diff --git a/test/jdk/java/net/httpclient/HttpGetInCancelledFuture.java b/test/jdk/java/net/httpclient/HttpGetInCancelledFuture.java
index baa64356fa74..1e7cf2ca5a54 100644
--- a/test/jdk/java/net/httpclient/HttpGetInCancelledFuture.java
+++ b/test/jdk/java/net/httpclient/HttpGetInCancelledFuture.java
@@ -84,11 +84,7 @@ public TestException(String message, Throwable cause) {
     HttpClient makeClient(URI uri, Version version, Executor executor) {
         var builder = HttpClient.newBuilder();
         if (uri.getScheme().equalsIgnoreCase("https")) {
-            try {
-                builder.sslContext(new SimpleSSLContext().get());
-            } catch (IOException io) {
-                throw new UncheckedIOException(io);
-            }
+            builder.sslContext(SimpleSSLContext.findSSLContext());
         }
         return builder.connectTimeout(Duration.ofSeconds(1))
                 .executor(executor)
diff --git a/test/jdk/java/net/httpclient/HttpRedirectTest.java b/test/jdk/java/net/httpclient/HttpRedirectTest.java
index dedcc36dda70..9c2f446c008f 100644
--- a/test/jdk/java/net/httpclient/HttpRedirectTest.java
+++ b/test/jdk/java/net/httpclient/HttpRedirectTest.java
@@ -77,14 +77,9 @@
 public class HttpRedirectTest implements HttpServerAdapters {
     static final String GET_RESPONSE_BODY = "Lorem ipsum dolor sit amet";
     static final String REQUEST_BODY = "Here it goes";
-    static final SSLContext context;
+    private static final SSLContext context = SimpleSSLContext.findSSLContext();
     static {
-        try {
-            context = new SimpleSSLContext().get();
-            SSLContext.setDefault(context);
-        } catch (Exception x) {
-            throw new ExceptionInInitializerError(x);
-        }
+        SSLContext.setDefault(context);
     }
 
     final AtomicLong requestCounter = new AtomicLong();
diff --git a/test/jdk/java/net/httpclient/HttpResponseConnectionLabelTest.java b/test/jdk/java/net/httpclient/HttpResponseConnectionLabelTest.java
index b6c13c51ee19..c7c4d2686d5f 100644
--- a/test/jdk/java/net/httpclient/HttpResponseConnectionLabelTest.java
+++ b/test/jdk/java/net/httpclient/HttpResponseConnectionLabelTest.java
@@ -81,7 +81,7 @@ class HttpResponseConnectionLabelTest {
 
     private static final String SERVER_ID_HEADER_NAME = "X-Server-Id";
 
-    private static final SSLContext SSL_CONTEXT = createSslContext();
+    private static final SSLContext SSL_CONTEXT = SimpleSSLContext.findSSLContext();
 
     // Start with a fresh client having no connections in the pool
     private final HttpClient client = HttpClient.newBuilder().sslContext(SSL_CONTEXT).proxy(NO_PROXY).build();
@@ -106,14 +106,6 @@ class HttpResponseConnectionLabelTest {
 
     private static final ServerRequestPair SEC_HTTPS2 = ServerRequestPair.of(Version.HTTP_2, true);
 
-    private static SSLContext createSslContext() {
-        try {
-            return new SimpleSSLContext().get();
-        } catch (IOException exception) {
-            throw new UncheckedIOException(exception);
-        }
-    }
-
     private record ServerRequestPair(
             HttpTestServer server,
             ExecutorService executor,
diff --git a/test/jdk/java/net/httpclient/HttpResponseLimitingTest.java b/test/jdk/java/net/httpclient/HttpResponseLimitingTest.java
index b87e7ea8e49d..8bf76dc3c3a9 100644
--- a/test/jdk/java/net/httpclient/HttpResponseLimitingTest.java
+++ b/test/jdk/java/net/httpclient/HttpResponseLimitingTest.java
@@ -99,15 +99,7 @@ class HttpResponseLimitingTest {
 
     private record ServerClientPair(HttpTestServer server, HttpClient client, HttpRequest request) {
 
-        private static final SSLContext SSL_CONTEXT = createSslContext();
-
-        private static SSLContext createSslContext() {
-            try {
-                return new SimpleSSLContext().get();
-            } catch (IOException exception) {
-                throw new UncheckedIOException(exception);
-            }
-        }
+        private static final SSLContext SSL_CONTEXT = SimpleSSLContext.findSSLContext();
 
         private ServerClientPair {
             try {
diff --git a/test/jdk/java/net/httpclient/HttpSlowServerTest.java b/test/jdk/java/net/httpclient/HttpSlowServerTest.java
index 85db9bba563b..abb17a156b90 100644
--- a/test/jdk/java/net/httpclient/HttpSlowServerTest.java
+++ b/test/jdk/java/net/httpclient/HttpSlowServerTest.java
@@ -81,14 +81,9 @@ public class HttpSlowServerTest implements HttpServerAdapters {
             "Excepteur sint occaecat cupidatat non proident."
     );
 
-    static final SSLContext context;
+    private static final SSLContext context = SimpleSSLContext.findSSLContext();
     static {
-        try {
-            context = new SimpleSSLContext().get();
-            SSLContext.setDefault(context);
-        } catch (Exception x) {
-            throw new ExceptionInInitializerError(x);
-        }
+        SSLContext.setDefault(context);
     }
 
     final AtomicLong requestCounter = new AtomicLong();
diff --git a/test/jdk/java/net/httpclient/HttpVersionsTest.java b/test/jdk/java/net/httpclient/HttpVersionsTest.java
index 00b0db1af4e8..a55c2727a005 100644
--- a/test/jdk/java/net/httpclient/HttpVersionsTest.java
+++ b/test/jdk/java/net/httpclient/HttpVersionsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -61,7 +61,7 @@
 
 public class HttpVersionsTest {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     Http2TestServer http2TestServer;
     Http2TestServer https2TestServer;
     String http2URI;
@@ -205,10 +205,6 @@ void testHttp1dot1Post(String uri, boolean sameClient) throws Exception {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         http2TestServer =  new Http2TestServer("localhost", false, 0, executor, 50, null, null, true);
         http2TestServer.addHandler(new Http2VerEchoHandler(), "/http2/vts");
         http2URI = "http://" + http2TestServer.serverAuthority() + "/http2/vts";
diff --git a/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java b/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java
index c6b2c323693e..c83abd9cf623 100644
--- a/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java
+++ b/test/jdk/java/net/httpclient/HttpsTunnelAuthTest.java
@@ -74,14 +74,9 @@ public class HttpsTunnelAuthTest implements HttpServerAdapters, AutoCloseable {
         "Excepteur sint occaecat cupidatat non proident."
     };
 
-    static final SSLContext context;
+    private static final SSLContext context = SimpleSSLContext.findSSLContext();
     static {
-        try {
-            context = new SimpleSSLContext().get();
-            SSLContext.setDefault(context);
-        } catch (Exception x) {
-            throw new ExceptionInInitializerError(x);
-        }
+        SSLContext.setDefault(context);
     }
 
     final String realm = "earth";
diff --git a/test/jdk/java/net/httpclient/HttpsTunnelTest.java b/test/jdk/java/net/httpclient/HttpsTunnelTest.java
index 86666539942a..bb0afacaacb9 100644
--- a/test/jdk/java/net/httpclient/HttpsTunnelTest.java
+++ b/test/jdk/java/net/httpclient/HttpsTunnelTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -82,14 +82,9 @@ public class HttpsTunnelTest implements HttpServerAdapters {
         "Excepteur sint occaecat cupidatat non proident."
     };
 
-    static final SSLContext context;
+    private static final SSLContext context = SimpleSSLContext.findSSLContext();
     static {
-        try {
-            context = new SimpleSSLContext().get();
-            SSLContext.setDefault(context);
-        } catch (Exception x) {
-            throw new ExceptionInInitializerError(x);
-        }
+        SSLContext.setDefault(context);
     }
 
     HttpsTunnelTest() {
diff --git a/test/jdk/java/net/httpclient/ISO_8859_1_Test.java b/test/jdk/java/net/httpclient/ISO_8859_1_Test.java
index e81b01304189..cd69a61d3be7 100644
--- a/test/jdk/java/net/httpclient/ISO_8859_1_Test.java
+++ b/test/jdk/java/net/httpclient/ISO_8859_1_Test.java
@@ -105,7 +105,7 @@
 
 public class ISO_8859_1_Test implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     DummyServer http1DummyServer;
     HttpServerAdapters.HttpTestServer http1TestServer;   // HTTP/1.1 ( http )
     HttpServerAdapters.HttpTestServer https1TestServer;  // HTTPS/1.1 ( https  )
@@ -404,10 +404,6 @@ public void handle(HttpTestExchange t) throws IOException {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         HttpServerAdapters.HttpTestHandler handler = new ISO88591Handler();
         InetSocketAddress loopback = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
 
diff --git a/test/jdk/java/net/httpclient/ImmutableFlowItems.java b/test/jdk/java/net/httpclient/ImmutableFlowItems.java
index b440ad646e8f..5cd2ddc0401c 100644
--- a/test/jdk/java/net/httpclient/ImmutableFlowItems.java
+++ b/test/jdk/java/net/httpclient/ImmutableFlowItems.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -69,7 +69,7 @@
 
 public class ImmutableFlowItems {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpServer httpTestServer;         // HTTP/1.1    [ 4 servers ]
     HttpsServer httpsTestServer;       // HTTPS/1.1
     Http2TestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -176,10 +176,6 @@ static String serverAuthority(HttpServer server) {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/1.1
         HttpHandler h1_fixedLengthHandler = new HTTP1_FixedLengthHandler();
         HttpHandler h1_chunkHandler = new HTTP1_ChunkedHandler();
diff --git a/test/jdk/java/net/httpclient/InvalidInputStreamSubscriptionRequest.java b/test/jdk/java/net/httpclient/InvalidInputStreamSubscriptionRequest.java
index 2f4f96e8b9bb..5fbd7354a68d 100644
--- a/test/jdk/java/net/httpclient/InvalidInputStreamSubscriptionRequest.java
+++ b/test/jdk/java/net/httpclient/InvalidInputStreamSubscriptionRequest.java
@@ -81,7 +81,7 @@
 
 public class InvalidInputStreamSubscriptionRequest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -441,10 +441,6 @@ static String serverAuthority(HttpServer server) {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/1.1
         HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler();
         HttpTestHandler h1_chunkHandler = new HTTP_VariableLengthHandler();
diff --git a/test/jdk/java/net/httpclient/InvalidSSLContextTest.java b/test/jdk/java/net/httpclient/InvalidSSLContextTest.java
index ca2ebbfb0389..be4d3297dd75 100644
--- a/test/jdk/java/net/httpclient/InvalidSSLContextTest.java
+++ b/test/jdk/java/net/httpclient/InvalidSSLContextTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -62,7 +62,7 @@
 
 public class InvalidSSLContextTest {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     volatile SSLServerSocket sslServerSocket;
     volatile String uri;
 
@@ -147,10 +147,6 @@ static void assertExceptionOrCause(Class clazz, Throwable t
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // server-side uses a different context to that of the client-side
         sslServerSocket = (SSLServerSocket)sslContext
                 .getServerSocketFactory()
diff --git a/test/jdk/java/net/httpclient/InvalidSubscriptionRequest.java b/test/jdk/java/net/httpclient/InvalidSubscriptionRequest.java
index 3cd7cb629ea1..1a1fc25e34b1 100644
--- a/test/jdk/java/net/httpclient/InvalidSubscriptionRequest.java
+++ b/test/jdk/java/net/httpclient/InvalidSubscriptionRequest.java
@@ -79,7 +79,7 @@
 
 public class InvalidSubscriptionRequest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -374,10 +374,6 @@ static String serverAuthority(HttpServer server) {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/1.1
         HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler();
         HttpTestHandler h1_chunkHandler = new HTTP_VariableLengthHandler();
diff --git a/test/jdk/java/net/httpclient/LargeResponseTest.java b/test/jdk/java/net/httpclient/LargeResponseTest.java
index bfc7c9ca5dbb..33f702423dbe 100644
--- a/test/jdk/java/net/httpclient/LargeResponseTest.java
+++ b/test/jdk/java/net/httpclient/LargeResponseTest.java
@@ -78,14 +78,9 @@ public class LargeResponseTest implements HttpServerAdapters {
         }
     }
 
-    static final SSLContext context;
+    private static final SSLContext context = SimpleSSLContext.findSSLContext();
     static {
-        try {
-            context = new SimpleSSLContext().get();
-            SSLContext.setDefault(context);
-        } catch (Exception x) {
-            throw new ExceptionInInitializerError(x);
-        }
+        SSLContext.setDefault(context);
     }
 
     final AtomicLong requestCounter = new AtomicLong();
diff --git a/test/jdk/java/net/httpclient/LightWeightHttpServer.java b/test/jdk/java/net/httpclient/LightWeightHttpServer.java
index c226b8455273..496aa2c57786 100644
--- a/test/jdk/java/net/httpclient/LightWeightHttpServer.java
+++ b/test/jdk/java/net/httpclient/LightWeightHttpServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -55,7 +55,7 @@
 
 public class LightWeightHttpServer {
 
-    static SSLContext ctx;
+    static final SSLContext ctx = SimpleSSLContext.findSSLContext();
     static HttpServer httpServer;
     static HttpsServer httpsServer;
     static ExecutorService executor;
@@ -111,7 +111,6 @@ public static void initServer() throws IOException {
         executor = Executors.newCachedThreadPool();
         httpServer.setExecutor(executor);
         httpsServer.setExecutor(executor);
-        ctx = new SimpleSSLContext().get();
         httpsServer.setHttpsConfigurator(new TestServerConfigurator(addr.getAddress(), ctx));
         httpServer.start();
         httpsServer.start();
diff --git a/test/jdk/java/net/httpclient/LineBodyHandlerTest.java b/test/jdk/java/net/httpclient/LineBodyHandlerTest.java
index 3271f21a1309..3424487afabd 100644
--- a/test/jdk/java/net/httpclient/LineBodyHandlerTest.java
+++ b/test/jdk/java/net/httpclient/LineBodyHandlerTest.java
@@ -89,7 +89,7 @@
 
 public class LineBodyHandlerTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;    // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -668,10 +668,6 @@ public Thread newThread(Runnable r) {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         httpTestServer = HttpTestServer.create(HTTP_1_1, null,
                 executorFor("HTTP/1.1 Server Thread"));
         httpTestServer.addHandler(new HttpTestEchoHandler(), "/http1/echo");
diff --git a/test/jdk/java/net/httpclient/ManyRequests.java b/test/jdk/java/net/httpclient/ManyRequests.java
index 493c2c3a5040..3290cd473ed2 100644
--- a/test/jdk/java/net/httpclient/ManyRequests.java
+++ b/test/jdk/java/net/httpclient/ManyRequests.java
@@ -102,7 +102,7 @@ public static void main(String[] args) throws Exception {
                          + " requests; delay=" + INSERT_DELAY
                          + ", chunks=" + CHUNK_SIZE
                          + ", XFixed=" + XFIXED);
-        SSLContext ctx = new SimpleSSLContext().get();
+        SSLContext ctx = SimpleSSLContext.findSSLContext();
 
         InetSocketAddress addr = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
         HttpsServer server = HttpsServer.create(addr, 0);
diff --git a/test/jdk/java/net/httpclient/ManyRequestsLegacy.java b/test/jdk/java/net/httpclient/ManyRequestsLegacy.java
index 010c04cc51de..989a8bd7054b 100644
--- a/test/jdk/java/net/httpclient/ManyRequestsLegacy.java
+++ b/test/jdk/java/net/httpclient/ManyRequestsLegacy.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -103,7 +103,7 @@ public static void main(String[] args) throws Exception {
                          + " requests; delay=" + INSERT_DELAY
                          + ", chunks=" + CHUNK_SIZE
                          + ", XFixed=" + XFIXED);
-        SSLContext ctx = new SimpleSSLContext().get();
+        SSLContext ctx = SimpleSSLContext.findSSLContext();
         SSLContext.setDefault(ctx);
         HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
                 public boolean verify(String hostname, SSLSession session) {
diff --git a/test/jdk/java/net/httpclient/MappingResponseSubscriber.java b/test/jdk/java/net/httpclient/MappingResponseSubscriber.java
index 6f5964970cc6..935347db48e1 100644
--- a/test/jdk/java/net/httpclient/MappingResponseSubscriber.java
+++ b/test/jdk/java/net/httpclient/MappingResponseSubscriber.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -76,7 +76,7 @@
 
 public class MappingResponseSubscriber {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpServer httpTestServer;         // HTTP/1.1    [ 4 servers ]
     HttpsServer httpsTestServer;       // HTTPS/1.1
     Http2TestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -216,10 +216,6 @@ static String serverAuthority(HttpServer server) {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         // HTTP/1.1
         HttpHandler h1_fixedLengthHandler = new HTTP1_FixedLengthHandler();
         HttpHandler h1_chunkHandler = new HTTP1_ChunkedHandler();
diff --git a/test/jdk/java/net/httpclient/MaxStreams.java b/test/jdk/java/net/httpclient/MaxStreams.java
index 25ec39ac4728..b25f931be9df 100644
--- a/test/jdk/java/net/httpclient/MaxStreams.java
+++ b/test/jdk/java/net/httpclient/MaxStreams.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -67,7 +67,7 @@ public class MaxStreams {
     Http2TestServer http2TestServer;   // HTTP/2 ( h2c )
     Http2TestServer https2TestServer;   // HTTP/2 ( h2 )
     final Http2FixedHandler handler = new Http2FixedHandler();
-    SSLContext ctx;
+    private static final SSLContext ctx = SimpleSSLContext.findSSLContext();
     String http2FixedURI;
     String https2FixedURI;
     ExecutorService exec;
@@ -163,7 +163,6 @@ void testAsString(String uri) throws Exception {
 
     @BeforeTest
     public void setup() throws Exception {
-        ctx = (new SimpleSSLContext()).get();
         exec = Executors.newCachedThreadPool();
 
         InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0);
diff --git a/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java b/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java
index 56a35119ae29..14854e3ebd1a 100644
--- a/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java
+++ b/test/jdk/java/net/httpclient/NonAsciiCharsInURI.java
@@ -64,7 +64,7 @@
 
 public class NonAsciiCharsInURI implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;         // HTTP/1.1    [ 4 servers ]
     HttpTestServer httpsTestServer;        // HTTPS/1.1
     HttpTestServer http2TestServer;        // HTTP/2 ( h2c )
@@ -238,10 +238,6 @@ void testAsync(String uriString, boolean sameClient) throws Exception {
     public void setup() throws Exception {
         out.println(now() + "begin setup");
 
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         HttpTestHandler handler = new HttpUriStringHandler();
         httpTestServer = HttpTestServer.create(HTTP_1_1);
         httpTestServer.addHandler(handler, "/http1/get");
diff --git a/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileDownloadTest.java b/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileDownloadTest.java
index f3bf5521f4bf..5e9b2e51a361 100644
--- a/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileDownloadTest.java
+++ b/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileDownloadTest.java
@@ -88,7 +88,7 @@ public class BodyHandlerOfFileDownloadTest implements HttpServerAdapters {
     static final String MSG = "msg";
     static final String contentDispositionValue = "attachment; filename=example.html";
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpServerAdapters.HttpTestServer httpTestServer;    // HTTP/1.1      [ 4 servers ]
     HttpServerAdapters.HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpServerAdapters.HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -190,10 +190,6 @@ public void testZipFs() {
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         defaultFsPath = defaultFsDir();
         zipFs = newZipFs();
         zipFsPath = zipFsDir(zipFs);
diff --git a/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileTest.java b/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileTest.java
index ee8a9c7dcbb4..d448c43fdf05 100644
--- a/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileTest.java
+++ b/test/jdk/java/net/httpclient/PathSubscriber/BodyHandlerOfFileTest.java
@@ -79,7 +79,7 @@
 public class BodyHandlerOfFileTest implements HttpServerAdapters {
     static final String MSG = "msg";
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpServerAdapters.HttpTestServer httpTestServer;    // HTTP/1.1      [ 4 servers ]
     HttpServerAdapters.HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpServerAdapters.HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -195,10 +195,6 @@ private void receive(String uriString,
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         defaultFsPath = defaultFsFile();
         zipFs = newZipFs();
         zipFsPath = zipFsFile(zipFs);
diff --git a/test/jdk/java/net/httpclient/PathSubscriber/BodySubscriberOfFileTest.java b/test/jdk/java/net/httpclient/PathSubscriber/BodySubscriberOfFileTest.java
index f2adc89ec174..fd5c7f6b01c0 100644
--- a/test/jdk/java/net/httpclient/PathSubscriber/BodySubscriberOfFileTest.java
+++ b/test/jdk/java/net/httpclient/PathSubscriber/BodySubscriberOfFileTest.java
@@ -84,7 +84,7 @@
 public class BodySubscriberOfFileTest implements HttpServerAdapters {
     static final String MSG = "msg";
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpServerAdapters.HttpTestServer httpTestServer;    // HTTP/1.1      [ 4 servers ]
     HttpServerAdapters.HttpTestServer httpsTestServer;   // HTTPS/1.1
     HttpServerAdapters.HttpTestServer http2TestServer;   // HTTP/2 ( h2c )
@@ -226,10 +226,6 @@ public void cancel() { }
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         defaultFsPath = defaultFsFile();
         zipFs = newZipFs();
         zipFsPath = zipFsFile(zipFs);
diff --git a/test/jdk/java/net/httpclient/ProxySelectorTest.java b/test/jdk/java/net/httpclient/ProxySelectorTest.java
index a5407801bcdc..bf63e5a77b56 100644
--- a/test/jdk/java/net/httpclient/ProxySelectorTest.java
+++ b/test/jdk/java/net/httpclient/ProxySelectorTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -86,7 +86,7 @@
 
 public class ProxySelectorTest implements HttpServerAdapters {
 
-    SSLContext sslContext;
+    private static final SSLContext sslContext = SimpleSSLContext.findSSLContext();
     HttpTestServer httpTestServer;            // HTTP/1.1
     HttpTestServer proxyHttpTestServer;       // HTTP/1.1
     HttpTestServer authProxyHttpTestServer;   // HTTP/1.1
@@ -320,10 +320,6 @@ private void doTest(Schemes scheme,
 
     @BeforeTest
     public void setup() throws Exception {
-        sslContext = new SimpleSSLContext().get();
-        if (sslContext == null)
-            throw new AssertionError("Unexpected null sslContext");
-
         httpTestServer = HttpTestServer.create(HTTP_1_1);
         httpTestServer.addHandler(new PlainServerHandler("plain-server"), "/http1/");
         httpURI = "http://" + httpTestServer.serverAuthority() + "/http1";
diff --git a/test/jdk/java/net/httpclient/ProxyTest.java b/test/jdk/java/net/httpclient/ProxyTest.java
index 8763e168a063..d42a5c40dc01 100644
--- a/test/jdk/java/net/httpclient/ProxyTest.java
+++ b/test/jdk/java/net/httpclient/ProxyTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -76,16 +76,12 @@
 public class ProxyTest {
 
     static {
-        try {
-            HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
-                    public boolean verify(String hostname, SSLSession session) {
-                        return true;
-                    }
-                });
-            SSLContext.setDefault(new SimpleSSLContext().get());
-        } catch (IOException ex) {
-            throw new ExceptionInInitializerError(ex);
-        }
+        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
+            public boolean verify(String hostname, SSLSession session) {
+                return true;
+            }
+        });
+        SSLContext.setDefault(SimpleSSLContext.findSSLContext());
     }
 
     static final String RESPONSE = "

Hello World!"; diff --git a/test/jdk/java/net/httpclient/RedirectMethodChange.java b/test/jdk/java/net/httpclient/RedirectMethodChange.java index ed1afb384e10..74b2f2ab4f19 100644 --- a/test/jdk/java/net/httpclient/RedirectMethodChange.java +++ b/test/jdk/java/net/httpclient/RedirectMethodChange.java @@ -58,7 +58,7 @@ public class RedirectMethodChange implements HttpServerAdapters { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpClient client; HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ] @@ -179,10 +179,6 @@ public void test(String uriString, @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - client = HttpClient.newBuilder() .followRedirects(HttpClient.Redirect.NORMAL) .sslContext(sslContext) diff --git a/test/jdk/java/net/httpclient/RedirectTimeoutTest.java b/test/jdk/java/net/httpclient/RedirectTimeoutTest.java index 88b8fd964b00..a7f3fd7d976b 100644 --- a/test/jdk/java/net/httpclient/RedirectTimeoutTest.java +++ b/test/jdk/java/net/httpclient/RedirectTimeoutTest.java @@ -171,4 +171,4 @@ public void handle(HttpTestExchange exchange) throws IOException { } } } -} \ No newline at end of file +} diff --git a/test/jdk/java/net/httpclient/RedirectWithCookie.java b/test/jdk/java/net/httpclient/RedirectWithCookie.java index 13dfe7666477..7bbdfd01e31e 100644 --- a/test/jdk/java/net/httpclient/RedirectWithCookie.java +++ b/test/jdk/java/net/httpclient/RedirectWithCookie.java @@ -64,7 +64,7 @@ public class RedirectWithCookie implements HttpServerAdapters { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ] HttpTestServer httpsTestServer; // HTTPS/1.1 HttpTestServer http2TestServer; // HTTP/2 ( h2c ) @@ -146,10 +146,6 @@ static void assertPreviousRedirectResponses(HttpRequest initialRequest, @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new CookieRedirectHandler(), "/http1/cookie/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/cookie/redirect"; diff --git a/test/jdk/java/net/httpclient/Response1xxTest.java b/test/jdk/java/net/httpclient/Response1xxTest.java index 57aed9407c29..f8c721a4f258 100644 --- a/test/jdk/java/net/httpclient/Response1xxTest.java +++ b/test/jdk/java/net/httpclient/Response1xxTest.java @@ -69,7 +69,7 @@ public class Response1xxTest implements HttpServerAdapters { private String http2RequestURIBase; - private SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); private HttpTestServer https2Server; // h2 private String https2RequestURIBase; @@ -97,10 +97,6 @@ public void setup() throws Exception { http2Server.start(); System.out.println("Started HTTP2 server at " + http2Server.getAddress()); - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) { - throw new AssertionError("Unexpected null sslContext"); - } https2Server = HttpTestServer.create(HTTP_2, sslContext); https2Server.addHandler(new Http2Handler(), "/http2/101"); https2RequestURIBase = URIBuilder.newBuilder().scheme("https").loopback() diff --git a/test/jdk/java/net/httpclient/Response204V2Test.java b/test/jdk/java/net/httpclient/Response204V2Test.java index 610c312b6671..e76c4320a483 100644 --- a/test/jdk/java/net/httpclient/Response204V2Test.java +++ b/test/jdk/java/net/httpclient/Response204V2Test.java @@ -74,7 +74,7 @@ public class Response204V2Test implements HttpServerAdapters { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpTestServer http2TestServer; // HTTP/2 ( h2c ) HttpTestServer https2TestServer; // HTTP/2 ( h2 ) String http2URI; @@ -264,10 +264,6 @@ public void test(String uri, boolean sameClient) throws Exception { @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - // HTTP/2 HttpTestHandler handler204 = new Handler204(); diff --git a/test/jdk/java/net/httpclient/ResponseBodyBeforeError.java b/test/jdk/java/net/httpclient/ResponseBodyBeforeError.java index d1cffff72cfd..91c4ad3adec9 100644 --- a/test/jdk/java/net/httpclient/ResponseBodyBeforeError.java +++ b/test/jdk/java/net/httpclient/ResponseBodyBeforeError.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,7 @@ public class ResponseBodyBeforeError { String httpURIFixLen; String httpsURIFixLen; - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); static final String EXPECTED_RESPONSE_BODY = "

Heading

Some Text

"; @@ -538,9 +538,6 @@ static String serverAuthority(ReplyingServer server) { @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); SSLContext.setDefault(sslContext); variableLengthServer = new PlainVariableLengthServer(); diff --git a/test/jdk/java/net/httpclient/ResponsePublisher.java b/test/jdk/java/net/httpclient/ResponsePublisher.java index e8d76430946b..9dce7f3d4c2a 100644 --- a/test/jdk/java/net/httpclient/ResponsePublisher.java +++ b/test/jdk/java/net/httpclient/ResponsePublisher.java @@ -83,7 +83,7 @@ public class ResponsePublisher implements HttpServerAdapters { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ] HttpTestServer httpsTestServer; // HTTPS/1.1 HttpTestServer http2TestServer; // HTTP/2 ( h2c ) @@ -435,10 +435,6 @@ static String serverAuthority(HttpServer server) { @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - // HTTP/1.1 HttpTestHandler h1_fixedLengthHandler = new HTTP_FixedLengthHandler(); HttpTestHandler h1_chunkHandler = new HTTP_VariableLengthHandler(); diff --git a/test/jdk/java/net/httpclient/RetryWithCookie.java b/test/jdk/java/net/httpclient/RetryWithCookie.java index ec83fa5df89a..8f9d53201928 100644 --- a/test/jdk/java/net/httpclient/RetryWithCookie.java +++ b/test/jdk/java/net/httpclient/RetryWithCookie.java @@ -75,7 +75,7 @@ public class RetryWithCookie implements HttpServerAdapters { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ] HttpTestServer httpsTestServer; // HTTPS/1.1 HttpTestServer http2TestServer; // HTTP/2 ( h2c ) @@ -146,10 +146,6 @@ void test(String uriString) throws Exception { @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new CookieRetryHandler(), "/http1/cookie/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/cookie/retry"; diff --git a/test/jdk/java/net/httpclient/ServerCloseTest.java b/test/jdk/java/net/httpclient/ServerCloseTest.java index 10fb8ca94d1a..65eb6cfc5897 100644 --- a/test/jdk/java/net/httpclient/ServerCloseTest.java +++ b/test/jdk/java/net/httpclient/ServerCloseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,7 @@ public class ServerCloseTest implements HttpServerAdapters { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); DummyServer httpDummyServer; // HTTP/1.1 [ 2 servers ] DummyServer httpsDummyServer; // HTTPS/1.1 String httpDummy; @@ -226,10 +226,6 @@ public void testServerClose(String uri, boolean sameClient) { @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); // DummyServer diff --git a/test/jdk/java/net/httpclient/ShortResponseBody.java b/test/jdk/java/net/httpclient/ShortResponseBody.java index 88d1cde6761e..b4fd83585eee 100644 --- a/test/jdk/java/net/httpclient/ShortResponseBody.java +++ b/test/jdk/java/net/httpclient/ShortResponseBody.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,7 +82,7 @@ public abstract class ShortResponseBody { String httpsURIVarLen; String httpURIFixLen; - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); SSLParameters sslParameters; HttpClient client; int numberOfRequests; @@ -657,9 +657,6 @@ static String serverAuthority(Server server) { @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); SSLContext.setDefault(sslContext); sslParameters = new SSLParameters(); diff --git a/test/jdk/java/net/httpclient/ShutdownNow.java b/test/jdk/java/net/httpclient/ShutdownNow.java index 045876597a2d..fdcf7458d87e 100644 --- a/test/jdk/java/net/httpclient/ShutdownNow.java +++ b/test/jdk/java/net/httpclient/ShutdownNow.java @@ -85,7 +85,7 @@ public class ShutdownNow implements HttpServerAdapters { } static final Random RANDOM = RandomFactory.getRandom(); - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ] HttpTestServer httpsTestServer; // HTTPS/1.1 HttpTestServer http2TestServer; // HTTP/2 ( h2c ) @@ -286,10 +286,6 @@ void testSequential(String uriString) throws Exception { @BeforeTest public void setup() throws Exception { out.println("\n**** Setup ****\n"); - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new ServerRequestHandler(), "/http1/exec/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/exec/retry"; diff --git a/test/jdk/java/net/httpclient/SmokeTest.java b/test/jdk/java/net/httpclient/SmokeTest.java index 56294e8f02fc..8e7ac2b011df 100644 --- a/test/jdk/java/net/httpclient/SmokeTest.java +++ b/test/jdk/java/net/httpclient/SmokeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -118,7 +118,7 @@ * in docs directory. */ public class SmokeTest { - static SSLContext ctx; + private static final SSLContext ctx = SimpleSSLContext.findSSLContext(); static SSLParameters sslparams; static HttpServer s1 ; static HttpsServer s2; @@ -805,7 +805,6 @@ static void initServer() throws Exception { executor = Executors.newCachedThreadPool(); s1.setExecutor(executor); s2.setExecutor(executor); - ctx = new SimpleSSLContext().get(); sslparams = ctx.getDefaultSSLParameters(); //sslparams.setProtocols(new String[]{"TLSv1.2"}); s2.setHttpsConfigurator(new Configurator(ctx)); diff --git a/test/jdk/java/net/httpclient/SpecialHeadersTest.java b/test/jdk/java/net/httpclient/SpecialHeadersTest.java index 37cb47a6872f..99d597f2021e 100644 --- a/test/jdk/java/net/httpclient/SpecialHeadersTest.java +++ b/test/jdk/java/net/httpclient/SpecialHeadersTest.java @@ -99,7 +99,7 @@ public class SpecialHeadersTest implements HttpServerAdapters { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ] HttpTestServer httpsTestServer; // HTTPS/1.1 HttpTestServer http2TestServer; // HTTP/2 ( h2c ) @@ -554,9 +554,6 @@ static String serverAuthority(HttpTestServer server) { @BeforeTest public void setup() throws Exception { out.println("--- Starting setup " + now()); - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); HttpTestHandler handler = new HttpUriStringHandler(); httpTestServer = HttpTestServer.create(HTTP_1_1); diff --git a/test/jdk/java/net/httpclient/SplitResponse.java b/test/jdk/java/net/httpclient/SplitResponse.java index 48f958047b71..1ea3d7d6a258 100644 --- a/test/jdk/java/net/httpclient/SplitResponse.java +++ b/test/jdk/java/net/httpclient/SplitResponse.java @@ -95,11 +95,10 @@ static String response(String body, boolean serverKeepalive) { }; final ServerSocketFactory factory; - final SSLContext context; + private static final SSLContext context = SimpleSSLContext.findSSLContext(); final boolean useSSL; - SplitResponse(boolean useSSL) throws IOException { + SplitResponse(boolean useSSL) { this.useSSL = useSSL; - context = new SimpleSSLContext().get(); SSLContext.setDefault(context); factory = useSSL ? SSLServerSocketFactory.getDefault() : ServerSocketFactory.getDefault(); diff --git a/test/jdk/java/net/httpclient/StreamingBody.java b/test/jdk/java/net/httpclient/StreamingBody.java index 7943968d239e..1af14c1eb856 100644 --- a/test/jdk/java/net/httpclient/StreamingBody.java +++ b/test/jdk/java/net/httpclient/StreamingBody.java @@ -62,7 +62,7 @@ public class StreamingBody implements HttpServerAdapters { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpTestServer httpTestServer; // HTTP/1.1 [ 4 servers ] HttpTestServer httpsTestServer; // HTTPS/1.1 HttpTestServer http2TestServer; // HTTP/2 ( h2c ) @@ -114,10 +114,6 @@ void test(String uriString) throws Exception { @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new MessageHandler(), "/http1/streamingbody/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/streamingbody/w"; diff --git a/test/jdk/java/net/httpclient/TimeoutBasic.java b/test/jdk/java/net/httpclient/TimeoutBasic.java index cdaedf062198..f44a4b9394ce 100644 --- a/test/jdk/java/net/httpclient/TimeoutBasic.java +++ b/test/jdk/java/net/httpclient/TimeoutBasic.java @@ -72,11 +72,7 @@ public class TimeoutBasic { static final List SCHEMES = List.of("https", "http"); static { - try { - SSLContext.setDefault(new SimpleSSLContext().get()); - } catch (IOException x) { - throw new ExceptionInInitializerError(x); - } + SSLContext.setDefault(SimpleSSLContext.findSSLContext()); } public static void main(String[] args) throws Exception { diff --git a/test/jdk/java/net/httpclient/TlsContextTest.java b/test/jdk/java/net/httpclient/TlsContextTest.java index 707a2e2d7c73..e15b38177b5e 100644 --- a/test/jdk/java/net/httpclient/TlsContextTest.java +++ b/test/jdk/java/net/httpclient/TlsContextTest.java @@ -72,7 +72,7 @@ public void setUp() throws Exception { // Re-enable TLSv1 and TLSv1.1 since test depends on them SecurityUtils.removeFromDisabledTlsAlgs("TLSv1", "TLSv1.1"); - server = SimpleSSLContext.getContext("TLS"); + server = SimpleSSLContext.findSSLContext("TLS"); final ExecutorService executor = Executors.newCachedThreadPool(); https2Server = HttpTestServer.of( new Http2TestServer("localhost", true, 0, executor, 50, null, server, true)); @@ -85,10 +85,10 @@ public void setUp() throws Exception { @DataProvider(name = "scenarios") public Object[][] scenarios() throws Exception { return new Object[][]{ - { SimpleSSLContext.getContext("TLS"), HTTP_2, "TLSv1.3" }, - { SimpleSSLContext.getContext("TLSv1.2"), HTTP_2, "TLSv1.2" }, - { SimpleSSLContext.getContext("TLSv1.1"), HTTP_1_1, "TLSv1.1" }, - { SimpleSSLContext.getContext("TLSv1.1"), HTTP_2, "TLSv1.1" }, + { SimpleSSLContext.findSSLContext("TLS"), HTTP_2, "TLSv1.3" }, + { SimpleSSLContext.findSSLContext("TLSv1.2"), HTTP_2, "TLSv1.2" }, + { SimpleSSLContext.findSSLContext("TLSv1.1"), HTTP_1_1, "TLSv1.1" }, + { SimpleSSLContext.findSSLContext("TLSv1.1"), HTTP_2, "TLSv1.1" }, }; } diff --git a/test/jdk/java/net/httpclient/UnauthorizedTest.java b/test/jdk/java/net/httpclient/UnauthorizedTest.java index e2124f2a7ede..920e65dc3065 100644 --- a/test/jdk/java/net/httpclient/UnauthorizedTest.java +++ b/test/jdk/java/net/httpclient/UnauthorizedTest.java @@ -66,7 +66,7 @@ public class UnauthorizedTest implements HttpServerAdapters { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpTestServer httpTestServer; // HTTP/1.1 HttpTestServer httpsTestServer; // HTTPS/1.1 HttpTestServer http2TestServer; // HTTP/2 ( h2c ) @@ -186,10 +186,6 @@ void test(String uriString, int code, boolean async, WeakReference c @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new UnauthorizedHandler(), "/http1/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1"; diff --git a/test/jdk/java/net/httpclient/UnknownBodyLengthTest.java b/test/jdk/java/net/httpclient/UnknownBodyLengthTest.java index cb3d083669bf..6c7fabb7f00b 100644 --- a/test/jdk/java/net/httpclient/UnknownBodyLengthTest.java +++ b/test/jdk/java/net/httpclient/UnknownBodyLengthTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,7 @@ public class UnknownBodyLengthTest { static final byte[] BUF = new byte[32 * 10234 + 2]; - volatile SSLContext ctx; + private static final SSLContext ctx = SimpleSSLContext.findSSLContext(); volatile ServerSocketFactory factory; volatile String clientURL; volatile int port; @@ -67,7 +67,6 @@ public class UnknownBodyLengthTest { final List acceptedList = new CopyOnWriteArrayList<>(); UnknownBodyLengthTest(boolean useSSL) throws Exception { - ctx = new SimpleSSLContext().get(); SSLContext.setDefault(ctx); factory = useSSL ? SSLServerSocketFactory.getDefault() : ServerSocketFactory.getDefault(); diff --git a/test/jdk/java/net/httpclient/UserAuthWithAuthenticator.java b/test/jdk/java/net/httpclient/UserAuthWithAuthenticator.java index 97be90f85877..12afc5068047 100644 --- a/test/jdk/java/net/httpclient/UserAuthWithAuthenticator.java +++ b/test/jdk/java/net/httpclient/UserAuthWithAuthenticator.java @@ -106,7 +106,7 @@ static void h2Test(final boolean useHeader, boolean rightPassword) throws Except HttpClient client = null; ExecutorService ex=null; try { - ctx = new SimpleSSLContext().get(); + ctx = SimpleSSLContext.findSSLContext(); ex = Executors.newCachedThreadPool(); InetAddress addr = InetAddress.getLoopbackAddress(); diff --git a/test/jdk/java/net/httpclient/UserCookieTest.java b/test/jdk/java/net/httpclient/UserCookieTest.java index b8de5f979553..d48b27aae7eb 100644 --- a/test/jdk/java/net/httpclient/UserCookieTest.java +++ b/test/jdk/java/net/httpclient/UserCookieTest.java @@ -85,7 +85,7 @@ public class UserCookieTest implements HttpServerAdapters { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpTestServer httpTestServer; // HTTP/1.1 [ 6 servers ] HttpTestServer httpsTestServer; // HTTPS/1.1 HttpTestServer http2TestServer; // HTTP/2 ( h2c ) @@ -190,10 +190,6 @@ void test(String uriString, HttpClient.Version version) throws Exception { @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - httpTestServer = HttpTestServer.create(HTTP_1_1); httpTestServer.addHandler(new CookieValidationHandler(), "/http1/cookie/"); httpURI = "http://" + httpTestServer.serverAuthority() + "/http1/cookie/retry"; diff --git a/test/jdk/java/net/httpclient/http2/BadHeadersTest.java b/test/jdk/java/net/httpclient/http2/BadHeadersTest.java index 4ee95678acb9..3bb800311789 100644 --- a/test/jdk/java/net/httpclient/http2/BadHeadersTest.java +++ b/test/jdk/java/net/httpclient/http2/BadHeadersTest.java @@ -87,7 +87,7 @@ public class BadHeadersTest { of(entry("hello", "world!"), entry(":status", "200")) // Pseudo header is not the first one ); - private static SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); private static Http2TestServer http2TestServer; // HTTP/2 ( h2c ) private static Http2TestServer https2TestServer; // HTTP/2 ( h2 ) private static String http2URI; @@ -242,10 +242,6 @@ static void assertDetailMessage(Throwable throwable, int iterationIndex) { @BeforeAll static void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - http2TestServer = new Http2TestServer("localhost", false, 0); http2TestServer.addHandler(new Http2EchoHandler(), "/http2/echo"); int port = http2TestServer.getAddress().getPort(); diff --git a/test/jdk/java/net/httpclient/http2/BasicTest.java b/test/jdk/java/net/httpclient/http2/BasicTest.java index 0c64be84926c..58ab191fc6f1 100644 --- a/test/jdk/java/net/httpclient/http2/BasicTest.java +++ b/test/jdk/java/net/httpclient/http2/BasicTest.java @@ -70,14 +70,12 @@ public class BasicTest { static HttpClient client = null; static ExecutorService clientExec; static ExecutorService serverExec; - static SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); static String pingURIString, httpURIString, httpsURIString; static void initialize() throws Exception { try { - SimpleSSLContext sslct = new SimpleSSLContext(); - sslContext = sslct.get(); client = getClient(); httpServer = new Http2TestServer(false, 0, serverExec, sslContext); httpServer.addHandler(new Http2EchoHandler(), "/"); diff --git a/test/jdk/java/net/httpclient/http2/ConnectionFlowControlTest.java b/test/jdk/java/net/httpclient/http2/ConnectionFlowControlTest.java index 767d31f13e56..1b9396effbb6 100644 --- a/test/jdk/java/net/httpclient/http2/ConnectionFlowControlTest.java +++ b/test/jdk/java/net/httpclient/http2/ConnectionFlowControlTest.java @@ -74,7 +74,7 @@ public class ConnectionFlowControlTest { - private static SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); private static HttpTestServer http2TestServer; // HTTP/2 ( h2c ) private static HttpTestServer https2TestServer; // HTTP/2 ( h2 ) private static String http2URI; @@ -240,10 +240,6 @@ static void assertDetailMessage(Throwable throwable, int iterationIndex) { @BeforeAll static void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - var http2TestServerLocal = new Http2TestServer("localhost", false, 0); http2TestServerLocal.addHandler(new Http2TestHandler(), "/http2/"); http2TestServer = HttpTestServer.of(http2TestServerLocal); diff --git a/test/jdk/java/net/httpclient/http2/ConnectionReuseTest.java b/test/jdk/java/net/httpclient/http2/ConnectionReuseTest.java index 24e7dded842e..360eabaee2b6 100644 --- a/test/jdk/java/net/httpclient/http2/ConnectionReuseTest.java +++ b/test/jdk/java/net/httpclient/http2/ConnectionReuseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,7 @@ */ public class ConnectionReuseTest { - private static SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); private static HttpTestServer http2_Server; // h2 server over HTTP private static HttpTestServer https2_Server; // h2 server over HTTPS @@ -80,8 +80,6 @@ public static void beforeAll() throws Exception { // if IPv6 isn't supported on this host Assumptions.assumeTrue(IPSupport.hasIPv6(), "Skipping tests - IPv6 is not supported"); } - sslContext = new SimpleSSLContext().get(); - assertNotNull(sslContext, "Unexpected null sslContext"); http2_Server = HttpTestServer.create(HTTP_2); http2_Server.addHandler(new Handler(), "/"); diff --git a/test/jdk/java/net/httpclient/http2/ContinuationFrameTest.java b/test/jdk/java/net/httpclient/http2/ContinuationFrameTest.java index 22b7f414126d..9c76df298c26 100644 --- a/test/jdk/java/net/httpclient/http2/ContinuationFrameTest.java +++ b/test/jdk/java/net/httpclient/http2/ContinuationFrameTest.java @@ -69,7 +69,7 @@ public class ContinuationFrameTest { - private static SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); private static Http2TestServer http2TestServer; // HTTP/2 ( h2c ) private static Http2TestServer https2TestServer; // HTTP/2 ( h2 ) private static String http2URI; @@ -197,10 +197,6 @@ void test(String uri, @BeforeAll static void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - http2TestServer = new Http2TestServer("localhost", false, 0); http2TestServer.addHandler(new Http2EchoHandler(), "/http2/echo"); http2TestServer.addHandler(new Http2NoBodyHandler(), "/http2/nobody"); diff --git a/test/jdk/java/net/httpclient/http2/ErrorTest.java b/test/jdk/java/net/httpclient/http2/ErrorTest.java index 061fd5cd350c..16735ec230f4 100644 --- a/test/jdk/java/net/httpclient/http2/ErrorTest.java +++ b/test/jdk/java/net/httpclient/http2/ErrorTest.java @@ -69,7 +69,7 @@ public class ErrorTest { //@Test(timeOut=5000) @Test public void test() throws Exception { - SSLContext sslContext = (new SimpleSSLContext()).get(); + SSLContext sslContext = SimpleSSLContext.findSSLContext(); ExecutorService exec = Executors.newCachedThreadPool(); HttpClient client = HttpClient.newBuilder() .executor(exec) @@ -80,7 +80,7 @@ public void test() throws Exception { Http2TestServer httpsServer = null; try { - SSLContext serverContext = (new SimpleSSLContext()).get(); + SSLContext serverContext = SimpleSSLContext.findSSLContext(); SSLParameters p = serverContext.getSupportedSSLParameters(); p.setApplicationProtocols(new String[]{"h2"}); httpsServer = new Http2TestServer(true, diff --git a/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java b/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java index 68cfe826a0ec..0f807c33dff7 100644 --- a/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java +++ b/test/jdk/java/net/httpclient/http2/FixedThreadPoolTest.java @@ -62,14 +62,12 @@ public class FixedThreadPoolTest { static Http2TestServer httpServer, httpsServer; static HttpClient client = null; static ExecutorService exec; - static SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); static String httpURIString, httpsURIString; static void initialize() throws Exception { try { - SimpleSSLContext sslct = new SimpleSSLContext(); - sslContext = sslct.get(); client = getClient(); httpServer = new Http2TestServer(false, 0, exec, sslContext); httpServer.addHandler(new Http2EchoHandler(), "/"); diff --git a/test/jdk/java/net/httpclient/http2/H2GoAwayTest.java b/test/jdk/java/net/httpclient/http2/H2GoAwayTest.java index 755bb2e16cc1..cee04ca81d29 100644 --- a/test/jdk/java/net/httpclient/http2/H2GoAwayTest.java +++ b/test/jdk/java/net/httpclient/http2/H2GoAwayTest.java @@ -69,12 +69,10 @@ public class H2GoAwayTest { private static final String REQ_PATH = "/test"; private static HttpTestServer server; private static String REQ_URI_BASE; - private static SSLContext sslCtx; + private static final SSLContext sslCtx = SimpleSSLContext.findSSLContext(); @BeforeAll static void beforeAll() throws Exception { - sslCtx = new SimpleSSLContext().get(); - assertNotNull(sslCtx, "SSLContext couldn't be created"); server = HttpTestServer.create(HTTP_2, sslCtx); server.addHandler(new Handler(), REQ_PATH); server.start(); diff --git a/test/jdk/java/net/httpclient/http2/NoBodyTest.java b/test/jdk/java/net/httpclient/http2/NoBodyTest.java index 4dcd99e2c87a..3d30c54654a0 100644 --- a/test/jdk/java/net/httpclient/http2/NoBodyTest.java +++ b/test/jdk/java/net/httpclient/http2/NoBodyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,15 +57,13 @@ public class NoBodyTest { static HttpClient client = null; static ExecutorService clientExec; static ExecutorService serverExec; - static SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); static String TEST_STRING = "The quick brown fox jumps over the lazy dog "; static String httpURIString, httpsURIString; static void initialize() throws Exception { try { - SimpleSSLContext sslct = new SimpleSSLContext(); - sslContext = sslct.get(); client = getClient(); httpServer = new Http2TestServer(false, 0, serverExec, sslContext); httpServer.addHandler(new Handler(), "/"); diff --git a/test/jdk/java/net/httpclient/http2/ProxyTest2.java b/test/jdk/java/net/httpclient/http2/ProxyTest2.java index 733c21ffe68f..17b05b92527e 100644 --- a/test/jdk/java/net/httpclient/http2/ProxyTest2.java +++ b/test/jdk/java/net/httpclient/http2/ProxyTest2.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,16 +71,12 @@ public class ProxyTest2 { static { - try { - HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { - public boolean verify(String hostname, SSLSession session) { - return true; - } - }); - SSLContext.setDefault(new SimpleSSLContext().get()); - } catch (IOException ex) { - throw new ExceptionInInitializerError(ex); - } + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + public boolean verify(String hostname, SSLSession session) { + return true; + } + }); + SSLContext.setDefault(SimpleSSLContext.findSSLContext()); } static final String RESPONSE = "

Hello World!"; diff --git a/test/jdk/java/net/httpclient/http2/StreamFlowControlTest.java b/test/jdk/java/net/httpclient/http2/StreamFlowControlTest.java index 31cc58df2a8e..a6cb7160d843 100644 --- a/test/jdk/java/net/httpclient/http2/StreamFlowControlTest.java +++ b/test/jdk/java/net/httpclient/http2/StreamFlowControlTest.java @@ -76,7 +76,7 @@ public class StreamFlowControlTest { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpTestServer http2TestServer; // HTTP/2 ( h2c ) HttpTestServer https2TestServer; // HTTP/2 ( h2 ) String http2URI; @@ -255,10 +255,6 @@ static void assertDetailMessage(Throwable throwable, int iterationIndex) { @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - var http2TestServer = new Http2TestServer("localhost", false, 0); http2TestServer.addHandler(new Http2TestHandler(), "/http2/"); this.http2TestServer = HttpTestServer.of(http2TestServer); diff --git a/test/jdk/java/net/httpclient/http2/UserInfoTest.java b/test/jdk/java/net/httpclient/http2/UserInfoTest.java index 7dafda0c1f8e..e0b77df6d72b 100644 --- a/test/jdk/java/net/httpclient/http2/UserInfoTest.java +++ b/test/jdk/java/net/httpclient/http2/UserInfoTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,11 +55,10 @@ public class UserInfoTest { Http2TestServer server; int port; - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); @BeforeAll void before() throws Exception { - sslContext = new SimpleSSLContext().get(); server = createServer(sslContext); port = server.getAddress().getPort(); server.start(); diff --git a/test/jdk/java/net/httpclient/websocket/HandshakeUrlEncodingTest.java b/test/jdk/java/net/httpclient/websocket/HandshakeUrlEncodingTest.java index 5065563c9ec1..5ffa0b86873f 100644 --- a/test/jdk/java/net/httpclient/websocket/HandshakeUrlEncodingTest.java +++ b/test/jdk/java/net/httpclient/websocket/HandshakeUrlEncodingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,7 +67,7 @@ public class HandshakeUrlEncodingTest { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpServer httpTestServer; HttpsServer httpsTestServer; String httpURI; @@ -135,11 +135,6 @@ public void test(String uri, boolean sameClient) { @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - - InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); queryPart = "?&raw=abc+def/ghi=xyz&encoded=abc%2Bdef%2Fghi%3Dxyz"; httpTestServer = HttpServer.create(sa, 10); diff --git a/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java b/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java index 6a02b7749293..90db79dc8efc 100644 --- a/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java +++ b/test/jdk/java/net/httpclient/websocket/WSHandshakeExceptionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,7 +70,7 @@ public class WSHandshakeExceptionTest { - SSLContext sslContext; + private static final SSLContext sslContext = SimpleSSLContext.findSSLContext(); HttpServer httpTestServer; // HTTP/1.1 [ 2 servers ] HttpsServer httpsTestServer; // HTTPS/1.1 String httpURI; @@ -161,10 +161,6 @@ static void gc(long ms) { @BeforeTest public void setup() throws Exception { - sslContext = new SimpleSSLContext().get(); - if (sslContext == null) - throw new AssertionError("Unexpected null sslContext"); - // HTTP/1.1 InetSocketAddress sa = new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); httpTestServer = HttpServer.create(sa, 0); diff --git a/test/jdk/java/net/httpclient/websocket/WebSocketProxyTest.java b/test/jdk/java/net/httpclient/websocket/WebSocketProxyTest.java index 405edd270a42..46758b2fe6e1 100644 --- a/test/jdk/java/net/httpclient/websocket/WebSocketProxyTest.java +++ b/test/jdk/java/net/httpclient/websocket/WebSocketProxyTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -79,11 +79,7 @@ public class WebSocketProxyTest { private static final String PASSWORD = "xyz987"; static { - try { - SSLContext.setDefault(new SimpleSSLContext().get()); - } catch (IOException ex) { - throw new ExceptionInInitializerError(ex); - } + SSLContext.setDefault(SimpleSSLContext.findSSLContext()); } static class WSAuthenticator extends Authenticator { diff --git a/test/jdk/java/net/httpclient/whitebox/FlowTestDriver.java b/test/jdk/java/net/httpclient/whitebox/FlowTestDriver.java index aea81fb0a0be..0b59b21b76a4 100644 --- a/test/jdk/java/net/httpclient/whitebox/FlowTestDriver.java +++ b/test/jdk/java/net/httpclient/whitebox/FlowTestDriver.java @@ -23,6 +23,7 @@ /* * @test + * @compile/module=java.net.http ../../../../../../lib/jdk/test/lib/net/SimpleSSLContext.java * @modules java.net.http/jdk.internal.net.http * @run testng java.net.http/jdk.internal.net.http.FlowTest */ diff --git a/test/jdk/java/net/httpclient/whitebox/SSLEchoTubeTestDriver.java b/test/jdk/java/net/httpclient/whitebox/SSLEchoTubeTestDriver.java index 2ae82454cff3..d641513b298c 100644 --- a/test/jdk/java/net/httpclient/whitebox/SSLEchoTubeTestDriver.java +++ b/test/jdk/java/net/httpclient/whitebox/SSLEchoTubeTestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @compile/module=java.net.http ../../../../../../lib/jdk/test/lib/net/SimpleSSLContext.java * @modules java.net.http/jdk.internal.net.http * @run testng/othervm * -Djdk.internal.httpclient.debug=true diff --git a/test/jdk/java/net/httpclient/whitebox/SSLFlowDelegateTestDriver.java b/test/jdk/java/net/httpclient/whitebox/SSLFlowDelegateTestDriver.java index 083a291751f2..a49f53a844af 100644 --- a/test/jdk/java/net/httpclient/whitebox/SSLFlowDelegateTestDriver.java +++ b/test/jdk/java/net/httpclient/whitebox/SSLFlowDelegateTestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ * @bug 8308144 * @summary tests that the SSLFlowDelegate doesn't accumulate application data when the * downReader doesn't request any + * @compile/module=java.net.http ../../../../../../lib/jdk/test/lib/net/SimpleSSLContext.java * @modules java.net.http/jdk.internal.net.http * @run testng/othervm -Djdk.internal.httpclient.debug=true * -Djavax.net.debug=ssl:handshake diff --git a/test/jdk/java/net/httpclient/whitebox/SSLTubeTestDriver.java b/test/jdk/java/net/httpclient/whitebox/SSLTubeTestDriver.java index e4809b60355d..b1994777b149 100644 --- a/test/jdk/java/net/httpclient/whitebox/SSLTubeTestDriver.java +++ b/test/jdk/java/net/httpclient/whitebox/SSLTubeTestDriver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ /* * @test + * @compile/module=java.net.http ../../../../../../lib/jdk/test/lib/net/SimpleSSLContext.java * @modules java.net.http/jdk.internal.net.http * @run testng/othervm * -Djdk.internal.httpclient.debug=true diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AbstractSSLTubeTest.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AbstractSSLTubeTest.java index f1e54b477302..944f8ae08720 100644 --- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AbstractSSLTubeTest.java +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AbstractSSLTubeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -286,8 +286,8 @@ public String toString() { } } - protected static SSLEngine createSSLEngine(boolean client) throws IOException { - SSLContext context = (new SimpleSSLContext()).get(); + protected static SSLEngine createSSLEngine(boolean client) { + SSLContext context = SimpleSSLContextWhiteboxAdapter.findSSLContext(); SSLEngine engine = context.createSSLEngine(); SSLParameters params = context.getSupportedSSLParameters(); if (client) { diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/FlowTest.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/FlowTest.java index 7fa717639db1..3e9e967c061d 100644 --- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/FlowTest.java +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/FlowTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,7 @@ public FlowTest() throws IOException { executor = Executors.newCachedThreadPool(); srcPublisher = new SubmissionPublisher<>(executor, 20, this::handlePublisherException); - SSLContext ctx = (new SimpleSSLContext()).get(); + SSLContext ctx = SimpleSSLContextWhiteboxAdapter.findSSLContext(); SSLEngine engineClient = ctx.createSSLEngine(); SSLParameters params = ctx.getSupportedSSLParameters(); params.setApplicationProtocols(new String[]{"proto1", "proto2"}); // server will choose proto2 diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLFlowDelegateTest.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLFlowDelegateTest.java index 45af27a96a85..6b031bdfa584 100644 --- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLFlowDelegateTest.java +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLFlowDelegateTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,7 +71,6 @@ public class SSLFlowDelegateTest { private static final byte DATA_BYTE = (byte) random.nextInt(); private ExecutorService executor; - private SSLContext sslContext; private SSLParameters sslParams; private SSLServerSocket sslServerSocket; private SSLEngine clientEngine; @@ -80,18 +79,18 @@ public class SSLFlowDelegateTest { @BeforeTest public void beforeTest() throws Exception { this.executor = Executors.newCachedThreadPool(); - this.sslContext = new jdk.internal.net.http.SimpleSSLContext().get(); this.testCompletion = new CompletableFuture<>(); final SSLParameters sp = new SSLParameters(); sp.setApplicationProtocols(new String[]{ALPN}); this.sslParams = sp; - this.sslServerSocket = startServer(this.sslContext); + var sslContext = SimpleSSLContextWhiteboxAdapter.findSSLContext(); + this.sslServerSocket = startServer(sslContext); println(debugTag, "Server started at " + this.sslServerSocket.getInetAddress() + ":" + this.sslServerSocket.getLocalPort()); - this.clientEngine = createClientEngine(this.sslContext); + this.clientEngine = createClientEngine(sslContext); } @AfterTest diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLTubeTest.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLTubeTest.java index 114110344a40..ac6a235b8e2a 100644 --- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLTubeTest.java +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SSLTubeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,7 +61,7 @@ public void runWithSSLLoopackServer() throws IOException { /* Start of wiring */ /* Emulates an echo server */ SSLLoopbackSubscriber server = - new SSLLoopbackSubscriber((new SimpleSSLContext()).get(), + new SSLLoopbackSubscriber(SimpleSSLContextWhiteboxAdapter.findSSLContext(), sslExecutor, allBytesReceived); server.start(); diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContext.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContext.java deleted file mode 100644 index 00b261292fa6..000000000000 --- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContext.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.internal.net.http; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.util.StringTokenizer; - -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.TrustManagerFactory; - -/** - * Creates a simple usable SSLContext for SSLSocketFactory - * or a HttpsServer using a default keystore in the test tree. - */ -public class SimpleSSLContext { - - private final SSLContext ssl; - - /** - * Loads default keystore from SimpleSSLContext source directory - */ - public SimpleSSLContext() throws IOException { - String paths = System.getProperty("test.src.path"); - StringTokenizer st = new StringTokenizer(paths, File.pathSeparator); - SSLContext sslContext = null; - while (st.hasMoreTokens()) { - String path = st.nextToken(); - File f = new File(path, "../../../../../lib/jdk/test/lib/net/testkeys"); - if (f.exists()) { - try (FileInputStream fis = new FileInputStream(f)) { - sslContext = init(fis); - break; - } - } - } - ssl = sslContext; - } - - private SSLContext init(InputStream i) throws IOException { - try { - char[] passphrase = "passphrase".toCharArray(); - KeyStore ks = KeyStore.getInstance("PKCS12"); - ks.load(i, passphrase); - - KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX"); - kmf.init(ks, passphrase); - - TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX"); - tmf.init(ks); - - SSLContext ssl = SSLContext.getInstance("TLS"); - ssl.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); - return ssl; - } catch (KeyManagementException | KeyStoreException | - UnrecoverableKeyException | CertificateException | - NoSuchAlgorithmException e) { - throw new RuntimeException(e.getMessage()); - } - } - - public SSLContext get() { - return ssl; - } -} diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContextWhiteboxAdapter.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContextWhiteboxAdapter.java new file mode 100644 index 000000000000..8b22de543d38 --- /dev/null +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContextWhiteboxAdapter.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018, 2025, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.net.http; + +import jdk.test.lib.net.SimpleSSLContext; + +import javax.net.ssl.SSLContext; + +/** + * Adapter for {@link SimpleSSLContext} for whitebox tests. + */ +public final class SimpleSSLContextWhiteboxAdapter { + + private SimpleSSLContextWhiteboxAdapter() {} + + /** + * {@return a new {@link SSLContext} instance by searching for a key store + * file path, and loading the first found one} + * + * @throws RuntimeException if no key store file can be found or the found + * one cannot be loaded + */ + public static SSLContext findSSLContext() { + return SimpleSSLContext.findSSLContext("../../../../../lib/jdk/test/lib/net/testkeys", "TLS"); + } + +} diff --git a/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetGroupEvent.java b/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetGroupEvent.java index 29e1de24224c..8ece7bf12d78 100644 --- a/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetGroupEvent.java +++ b/test/jdk/jdk/jfr/event/gc/detailed/TestZRelocationSetGroupEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ * @requires vm.hasJFR & vm.gc.Z * @requires vm.flagless * @library /test/lib /test/jdk /test/hotspot/jtreg - * @run main/othervm -XX:+UseZGC -Xmx32M jdk.jfr.event.gc.detailed.TestZRelocationSetGroupEvent + * @run main/othervm -XX:+UseZGC -Xmx64M jdk.jfr.event.gc.detailed.TestZRelocationSetGroupEvent */ public class TestZRelocationSetGroupEvent { diff --git a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java index 8754f2c6e64a..4ce583680023 100644 --- a/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java +++ b/test/jdk/security/infra/java/security/cert/CertPathValidator/certification/CAInterop.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -543,6 +543,34 @@ * sectigotlsroote46 CRL */ +/* + * @test id=wisekeyglobalrootgbca + * @bug 8372351 + * @summary Interoperability tests with OISTE WISeKey Global Root GB CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop + * wisekeyglobalrootgbca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp + * -Dcom.sun.security.ocsp.useget=false CAInterop wisekeyglobalrootgbca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop + * wisekeyglobalrootgbca CRL + */ + +/* + * @test id=wisekeyglobalrootgcca + * @bug 8372351 + * @summary Interoperability tests with OISTE WISeKey Global Root GC CA + * @library /test/lib + * @build jtreg.SkippedException ValidatePathWithURL CAInterop + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp CAInterop + * wisekeyglobalrootgcca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath,ocsp + * -Dcom.sun.security.ocsp.useget=false CAInterop wisekeyglobalrootgcca OCSP + * @run main/othervm/manual -Djava.security.debug=certpath CAInterop + * wisekeyglobalrootgcca CRL + */ + /** * Collection of certificate validation tests for interoperability with external CAs. * These tests are marked as manual as they depend on external infrastructure and may fail @@ -721,6 +749,13 @@ private CATestURLs getTestURLs(String alias) { new CATestURLs("https://sectigopublicserverauthenticationroote46-ev.sectigo.com", "https://sectigopublicserverauthenticationroote46-ev.sectigo.com:444"); + case "wisekeyglobalrootgbca" -> + new CATestURLs("https://gbvalidssl.hightrusted.com", + "https://gbrevokedssl.hightrusted.com"); + case "wisekeyglobalrootgcca" -> + new CATestURLs("https://gcvalidssl.hightrusted.com", + "https://gcrevokedssl.hightrusted.com"); + default -> throw new RuntimeException("No test setup found for: " + alias); }; } diff --git a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java index 710505f59741..bf21194e432c 100644 --- a/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java +++ b/test/jdk/sun/security/lib/cacerts/VerifyCACerts.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ * 8223499 8225392 8232019 8234245 8233223 8225068 8225069 8243321 8243320 * 8243559 8225072 8258630 8259312 8256421 8225081 8225082 8225083 8245654 * 8305975 8304760 8307134 8295894 8314960 8317373 8317374 8318759 8319187 - * 8321408 8316138 8341057 8303770 8350498 8359170 8361212 + * 8321408 8316138 8341057 8303770 8350498 8359170 8361212 8372351 * @summary Check root CA entries in cacerts file */ import java.io.ByteArrayInputStream; @@ -48,13 +48,13 @@ public class VerifyCACerts { // The numbers of certs now. // SapMachine 2021-09-23: Additional certificate for SAP - private static final int COUNT = 110; + private static final int COUNT = 112; // SHA-256 of cacerts, can be generated with // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 // SapMachine 2021-09-23: Additional certificate for SAP private static final String CHECKSUM - = "01:D9:C2:AE:CC:BA:E5:AD:C7:E9:F2:F3:C2:12:09:0B:1E:7E:C4:C9:B7:62:39:1A:04:03:A7:C2:24:57:CD:AE"; + = "46:B4:9E:42:70:3A:8A:AA:28:88:21:EE:DA:1B:4A:9B:6F:0C:C6:5F:D4:58:31:F7:A5:DB:9E:1B:5E:43:A8:9D"; // Hex formatter to upper case with ":" delimiter private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase(); @@ -284,6 +284,10 @@ public class VerifyCACerts { "7E:76:26:0A:E6:9A:55:D3:F0:60:B0:FD:18:B2:A8:C0:14:43:C8:7B:60:79:10:30:C9:FA:0B:05:85:10:1A:38"); put("sectigocodesignroote46 [jdk]", "8F:63:71:D8:CC:5A:A7:CA:14:96:67:A9:8B:54:96:39:89:51:E4:31:9F:7A:FB:CC:6A:66:0D:67:3E:43:8D:0B"); + put("wisekeyglobalrootgbca [jdk]", + "6B:9C:08:E8:6E:B0:F7:67:CF:AD:65:CD:98:B6:21:49:E5:49:4A:67:F5:84:5E:7B:D1:ED:01:9F:27:B8:6B:D6"); + put("wisekeyglobalrootgcca [jdk]", + "85:60:F9:1C:36:24:DA:BA:95:70:B5:FE:A0:DB:E3:6F:F1:1A:83:23:BE:94:86:85:4F:B3:F3:4A:55:71:19:8D"); } }; diff --git a/test/jdk/sun/security/ssl/X509KeyManager/PreferredKey.java b/test/jdk/sun/security/ssl/X509KeyManager/PreferredKey.java index 5086463b5897..2b08732a31a6 100644 --- a/test/jdk/sun/security/ssl/X509KeyManager/PreferredKey.java +++ b/test/jdk/sun/security/ssl/X509KeyManager/PreferredKey.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,89 +21,91 @@ * questions. */ -// -// Security properties, once set, cannot revert to unset. To avoid -// conflicts with tests running in the same VM isolate this test by -// running it in otherVM mode. -// - /* * @test * @bug 6302644 * @summary X509KeyManager implementation for NewSunX509 doesn't return most * preferable key - * @run main/othervm PreferredKey + * @modules java.base/sun.security.x509 + * java.base/sun.security.util + * @library /test/lib */ -import java.io.*; -import java.net.*; -import java.security.*; -import javax.net.ssl.*; +import jdk.test.lib.Asserts; +import jdk.test.lib.security.CertificateBuilder; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.X509KeyManager; +import java.io.IOException; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.SecureRandom; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; public class PreferredKey { - /* - * ============================================================= - * Set the various variables needed for the tests, then - * specify what tests to run on each side. - */ + public static void main(String[] args) throws Exception { + X509KeyManager km = getKeyManager(); + + testPreferredKey(km, "RSA", new String[] {"RSA", "DSA"}); + testPreferredKey(km, "DSA", new String[] {"DSA", "RSA"}); + } - /* - * Where do we find the keystores? - */ - static String pathToStores = "../../../../javax/net/ssl/etc"; - static String keyStoreFile = "keystore"; - static String passwd = "passphrase"; + private static void testPreferredKey(X509KeyManager km, + String keyType, + String[] multiKeyTypes) { + String[] aliases = km.getClientAliases(keyType, null); + String alias = km.chooseClientAlias(multiKeyTypes, null, null); + Asserts.assertTrue(aliases != null && alias != null, + "Should return preferred alias"); - public static void main(String[] args) throws Exception { - // MD5 is used in this test case, don't disable MD5 algorithm. - Security.setProperty("jdk.certpath.disabledAlgorithms", - "MD2, RSA keySize < 1024"); - Security.setProperty("jdk.tls.disabledAlgorithms", - "SSLv3, RC4, DH keySize < 768"); + String algorithm = km.getPrivateKey(alias).getAlgorithm(); + Asserts.assertTrue(algorithm.equals(keyType) && algorithm.equals( + km.getPrivateKey(aliases[0]).getAlgorithm()), + "Failed to get the preferable key aliases"); + } - KeyStore ks; - KeyManagerFactory kmf; - X509KeyManager km; + private static X509KeyManager getKeyManager() throws Exception { + char[] passphrase = "passphrase".toCharArray(); - String keyFilename = - System.getProperty("test.src", ".") + "/" + pathToStores + - "/" + keyStoreFile; - char [] password = passwd.toCharArray(); + KeyPair rsaKey = KeyPairGenerator.getInstance("RSA").generateKeyPair(); + KeyPair dsaKey = KeyPairGenerator.getInstance("DSA").generateKeyPair(); - ks = KeyStore.getInstance(new File(keyFilename), password); - kmf = KeyManagerFactory.getInstance("NewSunX509"); - kmf.init(ks, password); - km = (X509KeyManager) kmf.getKeyManagers()[0]; + // create a key store + KeyStore ks = KeyStore.getInstance("PKCS12"); + ks.load(null, passphrase); - /* - * There should be both an rsa and a dsa entry in the - * keystore, otherwise the test will no work. - */ - String[] aliases = km.getClientAliases("RSA", null); - String alias = km.chooseClientAlias(new String[] {"RSA", "DSA"}, - null, null); + ks.setKeyEntry("dummyrsa", + rsaKey.getPrivate(), + passphrase, + new Certificate[]{createSelfSignedCert(rsaKey, + "SHA256withRSA")}); + ks.setKeyEntry("dummydsa", + dsaKey.getPrivate(), + passphrase, + new Certificate[]{createSelfSignedCert(dsaKey, + "SHA256withDSA")}); - // there're should both be null or nonnull - if (aliases != null || alias != null) { - String algorithm = km.getPrivateKey(alias).getAlgorithm(); - if (!algorithm.equals("RSA") || !algorithm.equals( - km.getPrivateKey(aliases[0]).getAlgorithm())) { - throw new Exception("Failed to get the preferable key aliases"); - } - } + KeyManagerFactory kmf = KeyManagerFactory.getInstance("NewSunX509"); + kmf.init(ks, passphrase); - aliases = km.getClientAliases("DSA", null); - alias = km.chooseClientAlias(new String[] {"DSA", "RSA"}, - null, null); + return (X509KeyManager) kmf.getKeyManagers()[0]; + } - // there're should both be null or nonnull - if (aliases != null || alias != null) { - String algorithm = km.getPrivateKey(alias).getAlgorithm(); - if (!algorithm.equals("DSA") || !algorithm.equals( - km.getPrivateKey(aliases[0]).getAlgorithm())) { - throw new Exception("Failed to get the preferable key aliases"); - } - } + private static X509Certificate createSelfSignedCert(KeyPair caKeys, + String keyAlg) + throws CertificateException, IOException { + return (new CertificateBuilder() + .setSubjectName("CN=dummy.example.com, OU=Dummy, " + + "O=Dummy, L=Cupertino, ST=CA, C=US") + .setPublicKey(caKeys.getPublic()) + .setOneHourValidity() + .setSerialNumber(BigInteger.valueOf( + new SecureRandom().nextLong(1000000) + 1)) + ).build(null, caKeys.getPrivate(), keyAlg); } } diff --git a/test/jdk/sun/security/ssl/X509KeyManager/SelectOneKeyOutOfMany.java b/test/jdk/sun/security/ssl/X509KeyManager/SelectOneKeyOutOfMany.java index f05c32b30795..78987736302b 100644 --- a/test/jdk/sun/security/ssl/X509KeyManager/SelectOneKeyOutOfMany.java +++ b/test/jdk/sun/security/ssl/X509KeyManager/SelectOneKeyOutOfMany.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2026, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,178 +24,145 @@ /* * @test * @bug 4387949 4302197 - * @summary Need to add Sockets and key arrays to the - * X509KeyManager.choose*Alias() methods & There's no mechanism - * to select one key out of many in a keystore - * - * chooseServerAlias method is reverted back to accept a single - * keytype as a parameter, please see RFE: 4501014 - * The part of the test on the server-side is changed to test - * passing in a single keytype parameter to chooseServerAlias method. - * - * @author Brad Wetmore + * @summary Verify X509KeyManager selects the correct RSA or DSA key + * @modules java.base/sun.security.x509 + * java.base/sun.security.util + * @library /test/lib */ -import java.io.*; -import java.net.*; -import java.security.*; -import javax.net.ssl.*; +import jdk.test.lib.Asserts; +import jdk.test.lib.security.CertificateBuilder; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.X509KeyManager; +import java.io.IOException; +import java.math.BigInteger; +import java.security.KeyPair; +import java.security.KeyPairGenerator; +import java.security.KeyStore; +import java.security.SecureRandom; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; +import java.util.Arrays; public class SelectOneKeyOutOfMany { + private static final String NOTHING = "nothing"; + private static final String RSA = "RSA"; + private static final String DSA = "DSA"; + private static final String RSA_ALIAS = "dummyrsa"; + private static final String DSA_ALIAS = "dummydsa"; - /* - * ============================================================= - * Set the various variables needed for the tests, then - * specify what tests to run on each side. - */ + public static void main(String[] args) throws Exception { + X509KeyManager km = getKeyManager(); - /* - * Where do we find the keystores? - */ - static String pathToStores = "../../../../javax/net/ssl/etc"; - static String keyStoreFile = "keystore"; - static String passwd = "passphrase"; + // String[] getClientAliases(String keyType, Principal[] issuers) + Asserts.assertNull(km.getClientAliases(NOTHING, null), + "getClientAliases shouldn't return alias for unknown type"); - public static void main(String[] args) throws Exception { - KeyStore ks; - KeyManagerFactory kmf; - X509KeyManager km; - - char[] passphrase = passwd.toCharArray(); - - String keyFilename = - System.getProperty("test.src", ".") + "/" + pathToStores + - "/" + keyStoreFile; - /* - * Setup the tests. - */ - kmf = KeyManagerFactory.getInstance("SunX509"); - ks = KeyStore.getInstance(new File(keyFilename), passphrase); + Asserts.assertTrue(Arrays.stream(km.getClientAliases(RSA, + null)).toList().contains(RSA_ALIAS), + "getClientAliases should return RSA alias: " + + Arrays.toString(km.getClientAliases(RSA, null))); + + Asserts.assertTrue(Arrays.stream(km.getClientAliases(DSA, + null)).toList().contains(DSA_ALIAS), + "getClientAliases should return DSA alias: " + + Arrays.toString(km.getClientAliases(DSA, null))); + + + // String[] getServerAliases(String keyType, Principal[] issuers) + Asserts.assertNull(km.getServerAliases(NOTHING, null), + "getServerAliases shouldn't return alias for unknown type"); + + Asserts.assertTrue(Arrays.stream(km.getServerAliases(RSA, + null)).toList().contains(RSA_ALIAS), + "getServerAliases should return RSA alias: " + + Arrays.toString(km.getServerAliases(RSA, null))); + + Asserts.assertTrue(Arrays.stream(km.getServerAliases(DSA, + null)).toList().contains(DSA_ALIAS), + "getServerAliases should return DSA alias: " + + Arrays.toString(km.getServerAliases(DSA, null))); + + + // String chooseClientAlias(String[] keyType, Principal[] issuers, Socket socket) + Asserts.assertNull(km.chooseClientAlias(new String[]{NOTHING}, + null, + null), + "chooseClientAlias shouldn't return alias for unknown type"); + + Asserts.assertEQ( + km.chooseClientAlias(new String[]{RSA}, null, null), + RSA_ALIAS, + "chooseClientAlias should return RSA alias"); + + Asserts.assertEQ( + km.chooseClientAlias(new String[]{DSA}, null, null), + DSA_ALIAS, + "chooseClientAlias should return DSA alias"); + + Asserts.assertEQ( + km.chooseClientAlias(new String[]{RSA, DSA}, null, null), + RSA_ALIAS, + "chooseClientAlias should return RSA alias"); + + Asserts.assertEQ( + km.chooseClientAlias(new String[]{DSA, RSA}, null, null), + DSA_ALIAS, + "chooseClientAlias should return DSA alias"); + + + // String chooseServerAlias(String keyType, Principal[] issuers, Socket socket) + Asserts.assertNull(km.chooseServerAlias(NOTHING, null, null), + "chooseServerAlias shouldn't return alias for unknown type"); + + Asserts.assertEQ(km.chooseServerAlias(RSA, null, null), + RSA_ALIAS, + "chooseServerAlias should return RSA alias"); + + Asserts.assertEQ(km.chooseServerAlias(DSA, null, null), + DSA_ALIAS, + "chooseServerAlias should return DSA alias"); + } + + private static X509KeyManager getKeyManager() throws Exception { + char[] passphrase = "passphrase".toCharArray(); + + KeyPair rsaKey = KeyPairGenerator.getInstance(RSA).generateKeyPair(); + KeyPair dsaKey = KeyPairGenerator.getInstance(DSA).generateKeyPair(); + + // create a key store + KeyStore ks = KeyStore.getInstance("PKCS12"); + ks.load(null, passphrase); + + ks.setKeyEntry(RSA_ALIAS, + rsaKey.getPrivate(), + passphrase, + new Certificate[]{createSelfSignedCert(rsaKey, + "SHA256withRSA")}); + ks.setKeyEntry(DSA_ALIAS, + dsaKey.getPrivate(), + passphrase, + new Certificate[]{createSelfSignedCert(dsaKey, + "SHA256withDSA")}); + + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); kmf.init(ks, passphrase); - km = (X509KeyManager) kmf.getKeyManagers()[0]; - - /* - * There should be one of each key type here. - */ - String [] nothing = new String [] { "nothing" }; - String [] rsa = new String [] { "RSA" }; - String [] dsa = new String [] { "DSA" }; - String [] rsaDsa = new String [] { "RSA", "DSA" }; - String [] dsaRsa = new String [] { "DSA", "RSA" }; - - String resultsRsaDsa, resultsDsaRsa; - String resultsRsa, resultsDsa; - String resultsNone; - - String [] resultArrayRSA; - String [] resultArrayDSA; - - /* - * Check get*Aliases for null returns - */ - if (km.getClientAliases("nothing", null) != null) - throw new Exception("km.getClientAliases(nothing) != null"); - System.out.println("km.getClientAlias(nothing) returning nulls"); - - if (km.getServerAliases("nothing", null) != null) - throw new Exception("km.getServerAliases(nothing) != null"); - System.out.println("km.getServerAlias(nothing) returning nulls"); - System.out.println("====="); - - System.out.println("Dumping Certs..."); - if ((resultArrayRSA = km.getServerAliases("RSA", null)) == null) - throw new Exception("km.getServerAliases(RSA) == null"); - for (int i = 0; i < resultArrayRSA.length; i++) { - System.out.println(" resultArrayRSA#" + i + ": " + - resultArrayRSA[i]); - } - - if ((resultArrayDSA = km.getServerAliases("DSA", null)) == null) - throw new Exception("km.getServerAliases(DSA) == null"); - for (int i = 0; i < resultArrayDSA.length; i++) { - System.out.println(" resultArrayDSA#" + i + ": " + - resultArrayDSA[i]); - } - System.out.println("====="); - - /* - * Check chooseClientAliases for null returns - */ - resultsNone = km.chooseClientAlias(nothing, null, null); - if (resultsNone != null) { - throw new Exception("km.chooseClientAlias(nothing) != null"); - } - System.out.println("km.ChooseClientAlias(nothing) passed"); - - /* - * Check chooseClientAlias for RSA keys. - */ - resultsRsa = km.chooseClientAlias(rsa, null, null); - if (resultsRsa == null) { - throw new Exception( - "km.chooseClientAlias(rsa, null, null) != null"); - } - System.out.println("km.chooseClientAlias(rsa) passed"); - - /* - * Check chooseClientAlias for DSA keys. - */ - resultsDsa = km.chooseClientAlias(dsa, null, null); - if (resultsDsa == null) { - throw new Exception( - "km.chooseClientAlias(dsa, null, null) != null"); - } - System.out.println("km.chooseClientAlias(dsa) passed"); - - /* - * There should be both an rsa and a dsa entry in the - * keystore. - * - * Check chooseClientAlias for RSA/DSA keys and be sure - * the ordering is correct. - */ - resultsRsaDsa = km.chooseClientAlias(rsaDsa, null, null); - if ((resultsRsaDsa == null) || (resultsRsaDsa != resultsRsa)) { - throw new Exception("km.chooseClientAlias(rsaDsa) failed"); - } - System.out.println("km.chooseClientAlias(rsaDsa) passed"); - - resultsDsaRsa = km.chooseClientAlias(dsaRsa, null, null); - if ((resultsDsaRsa == null) || (resultsDsaRsa != resultsDsa)) { - throw new Exception("km.chooseClientAlias(DsaRsa) failed"); - } - System.out.println("km.chooseClientAlias(DsaRsa) passed"); - - System.out.println("====="); - - /* - * Check chooseServerAliases for null returns - */ - resultsNone = km.chooseServerAlias("nothing", null, null); - if (resultsNone != null) { - throw new Exception("km.chooseServerAlias(\"nothing\") != null"); - } - System.out.println("km.ChooseServerAlias(\"nothing\") passed"); - - /* - * Check chooseServerAlias for RSA keys. - */ - resultsRsa = km.chooseServerAlias("RSA", null, null); - if (resultsRsa == null) { - throw new Exception( - "km.chooseServerAlias(\"RSA\", null, null) != null"); - } - System.out.println("km.chooseServerAlias(\"RSA\") passed"); - - /* - * Check chooseServerAlias for DSA keys. - */ - resultsDsa = km.chooseServerAlias("DSA", null, null); - if (resultsDsa == null) { - throw new Exception( - "km.chooseServerAlias(\"DSA\", null, null) != null"); - } - System.out.println("km.chooseServerAlias(\"DSA\") passed"); + return (X509KeyManager) kmf.getKeyManagers()[0]; + } + + private static X509Certificate createSelfSignedCert(KeyPair caKeys, + String keyAlg) + throws CertificateException, IOException { + return (new CertificateBuilder() + .setSubjectName("CN=dummy.example.com, OU=Dummy, " + + "O=Dummy, L=Cupertino, ST=CA, C=US") + .setPublicKey(caKeys.getPublic()) + .setOneHourValidity() + .setSerialNumber(BigInteger.valueOf( + new SecureRandom().nextLong(1000000) + 1)) + ).build(null, caKeys.getPrivate(), keyAlg); } } diff --git a/test/lib/RedefineClassHelper.java b/test/lib/RedefineClassHelper.java index ce27fb33f441..064778b3a2ab 100644 --- a/test/lib/RedefineClassHelper.java +++ b/test/lib/RedefineClassHelper.java @@ -107,7 +107,7 @@ public static byte[] replaceClassName(ClassLoader loader, String oldClassName, S * Main method to be invoked before test to create the redefineagent.jar */ public static void main(String[] args) throws Exception { - String manifest = "Premain-Class: RedefineClassHelper\nCan-Redefine-Classes: true\n"; + String manifest = "Premain-Class: RedefineClassHelper\nCan-Redefine-Classes: true\nCan-Retransform-Classes: true\n"; ClassFileInstaller.writeJar("redefineagent.jar", ClassFileInstaller.Manifest.fromString(manifest), "RedefineClassHelper"); } } diff --git a/test/lib/jdk/test/lib/process/ProcessTools.java b/test/lib/jdk/test/lib/process/ProcessTools.java index 7d03268cac47..5687fb50a317 100644 --- a/test/lib/jdk/test/lib/process/ProcessTools.java +++ b/test/lib/jdk/test/lib/process/ProcessTools.java @@ -547,7 +547,7 @@ public static ProcessBuilder createTestJavaProcessBuilder(String... command) { * "test.vm.opts" and "test.java.opts" and this method will * not do that. * - *

If you still chose to use + *

If you still choose to use * createLimitedTestJavaProcessBuilder() you should probably use * it in combination with @requires vm.flagless JTREG * anotation as to not waste energy and test resources. @@ -581,7 +581,7 @@ public static ProcessBuilder createLimitedTestJavaProcessBuilder(List co * "test.vm.opts" and "test.java.opts" and this method will * not do that. * - *

If you still chose to use + *

If you still choose to use * createLimitedTestJavaProcessBuilder() you should probably use * it in combination with @requires vm.flagless JTREG * anotation as to not waste energy and test resources.