From 9216ed79f46e46056cc288935239b5a8a3669286 Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Wed, 6 May 2026 07:04:07 +0000 Subject: [PATCH 01/34] 8378746: ZGC: jdk/jfr/event/gc/detailed/TestZRelocationSetGroupEvent.java intermittent OOME Backport-of: e22c95cd96f823f75e00396b9ce0701b0eb6c3d5 --- .../jfr/event/gc/detailed/TestZRelocationSetGroupEvent.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 { From 682c8b0d9eb2097d375240c7e8371d81d952a957 Mon Sep 17 00:00:00 2001 From: Roland Mesde Date: Wed, 6 May 2026 15:05:44 +0000 Subject: [PATCH 02/34] 8264851: Shenandoah: Rework control loop mechanics to use timed waits Reviewed-by: phh Backport-of: 92f2ab2e1b5a7c02ea6d3a3a07c7fbbfc725cdea --- .../gc/shenandoah/shenandoahControlThread.cpp | 27 ++++++++++++------- .../gc/shenandoah/shenandoahControlThread.hpp | 5 ++++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index bdd495a86853..ea8033178c05 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(Mutex::nosafepoint - 2, "ShenandoahGCRequest_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); From dabd73221fac08cf79ba92dbb7c2f3a850e6ee36 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 6 May 2026 19:30:46 +0000 Subject: [PATCH 03/34] 8383183: Shenandoah: Mangle trashed regions up to top instead of end Backport-of: b41edeb3e45c289042a8fc71301aef2a45fbe9b1 --- src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp index b959494ae99f..c27b568e7c5d 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp @@ -571,7 +571,7 @@ void ShenandoahHeapRegion::recycle_internal() { 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())); } make_empty(); From 89fc73f64744a824cd0fb1a29b9f8c6c8b956928 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 6 May 2026 19:31:16 +0000 Subject: [PATCH 04/34] 8335355: Shenandoah: Fix race condition in gc/shenandoah/mxbeans/TestPauseNotifications.java Backport-of: 35a499e3d95c62347fc9664e37c78ff1fc80ff42 --- .../mxbeans/TestPauseNotifications.java | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) 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 { From f54fe51fe57312c74e47f1bf191859f1989b4301 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 6 May 2026 19:33:18 +0000 Subject: [PATCH 05/34] 8373714: Shenandoah: Register heuristic penalties following a degenerated GC Backport-of: 385c4f8180d30c0e41b848eb4b2c1c8788211422 --- .../gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp | 4 ++-- .../gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp | 2 +- .../share/gc/shenandoah/heuristics/shenandoahHeuristics.cpp | 2 +- .../share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp | 2 +- .../gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp | 4 ++-- .../gc/shenandoah/heuristics/shenandoahOldHeuristics.hpp | 2 +- src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp | 4 ++++ 7 files changed, 12 insertions(+), 8 deletions(-) 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..75a2c4124b4d 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp @@ -77,7 +77,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; 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..fb8cfb363536 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp @@ -218,7 +218,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..bd8b0d787b87 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp @@ -721,10 +721,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/shenandoahDegeneratedGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp index 0f84d95d02a8..a986317e34ae 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp @@ -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(); } } From be0f9b745c42672513a0d003249c0a63a438635f Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 6 May 2026 19:33:45 +0000 Subject: [PATCH 06/34] 8380431: Shenandoah: Concurrent modification of stack-chunk objects during evacuation Backport-of: 4a9903bae4691947391942064624c44f5d26cab5 --- .../share/gc/shenandoah/shenandoahFullGC.cpp | 5 ++++- .../shenandoah/shenandoahGenerationalHeap.cpp | 17 +++++++++-------- .../share/gc/shenandoah/shenandoahHeap.cpp | 13 +++++++++++-- .../gc/shenandoah/shenandoahMark.inline.hpp | 7 +++---- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp index 557a3847bab6..91cf930a7ac3 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); } } }; 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/shenandoahMark.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp index c588a03fdf90..2fff89d2b12c 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); From 02c348f9e202f77214387863481298241a2657c0 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 6 May 2026 19:34:10 +0000 Subject: [PATCH 07/34] 8379021: Shenandoah: Speedup ShenandoahSimpleBitMapTest Backport-of: 30e569d206dbb87349927682f194f5ba1294e44d --- .../gtest/gc/shenandoah/test_shenandoahMarkBitMap.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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; From aae9cbe93bd98747620781ef5f8084d91dca2786 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 6 May 2026 19:34:51 +0000 Subject: [PATCH 08/34] 8378083: Mark shenandoah/generational/TestOldGrowthTriggers.java as flagless Backport-of: 7e9e64966b47c788c91f934b5fca5cd31ad465b3 --- .../gc/shenandoah/generational/TestOldGrowthTriggers.java | 2 +- test/lib/jdk/test/lib/process/ProcessTools.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) 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/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. From 7a76ea3b9038ea8d6c68f80397b9489f90b13e33 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 6 May 2026 19:36:45 +0000 Subject: [PATCH 09/34] 8365792: GenShen: assertion "Generations aren't reconciled" Backport-of: 6e4e966d9b71ec04618e19784b5a661f34595ef6 --- src/hotspot/share/gc/shenandoah/shenandoahAsserts.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) 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()); } From 8c1d62a36b41dd05225d1e5fe6aa37917ed63da4 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Wed, 6 May 2026 19:37:07 +0000 Subject: [PATCH 10/34] 8368681: Shenandoah: Add documentation comments for ShenandoahAllocationRate Backport-of: a3e41ea6c60eb278da93dbc2daf940f0dc9abd11 --- .../shenandoahAdaptiveHeuristics.hpp | 39 +++++++++++++++++++ .../gc/shenandoah/shenandoahGeneration.hpp | 5 +++ 2 files changed, 44 insertions(+) diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.hpp index 75a2c4124b4d..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; }; @@ -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/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); From ae3f1dbbf422ac621339484b7bd29034019209e7 Mon Sep 17 00:00:00 2001 From: Roland Mesde Date: Thu, 7 May 2026 13:37:11 +0000 Subject: [PATCH 11/34] 8374449: Shenandoah: Leaf locks used by Shenandoah need lower ranks Backport-of: 673cd6ed0c4ebbb301346e8e251d1674f363c0d8 --- .../share/gc/shenandoah/shenandoahControlThread.cpp | 2 +- src/hotspot/share/gc/shenandoah/shenandoahController.hpp | 7 +++++-- .../gc/shenandoah/shenandoahGenerationalControlThread.cpp | 2 +- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp index ea8033178c05..458b7ab99afc 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahControlThread.cpp @@ -44,7 +44,7 @@ ShenandoahControlThread::ShenandoahControlThread() : ShenandoahController(), _requested_gc_cause(GCCause::_no_cause_specified), _degen_point(ShenandoahGC::_degenerated_outside_cycle), - _control_lock(Mutex::nosafepoint - 2, "ShenandoahGCRequest_lock", true) { + _control_lock(CONTROL_LOCK_RANK, "ShenandoahControl_lock", true) { set_name("Shenandoah Control Thread"); create_and_start(); } 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/shenandoahGenerationalControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp index cd144cf05712..f4943cb3da29 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), From d20d19c8aa488c35b52d9aae8b2c4127acf3038b Mon Sep 17 00:00:00 2001 From: Roland Mesde Date: Fri, 8 May 2026 13:19:11 +0000 Subject: [PATCH 12/34] 8380409: JVM crashes when -XX:AOTMode=create uses app.aotconf generated with JVMTI agent Reviewed-by: phh Backport-of: 1e3fb444c5aa0038d123c0f43858c1c4c684d958 --- src/hotspot/share/cds/aotArtifactFinder.cpp | 27 +++++- src/hotspot/share/cds/aotArtifactFinder.hpp | 4 +- src/hotspot/share/cds/heapShared.cpp | 1 + .../aotCache/RedefineCriticalClasses.java | 83 +++++++++++++++++++ .../aotCache/TransformCriticalClasses.java | 72 ++++++++++++++++ 5 files changed, 185 insertions(+), 2 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotCache/RedefineCriticalClasses.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotCache/TransformCriticalClasses.java 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/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"); + } +} From faa4e5385a9096e2d713b23369e4832f5a6c05cb Mon Sep 17 00:00:00 2001 From: William Kemper Date: Fri, 8 May 2026 17:14:41 +0000 Subject: [PATCH 13/34] 8381871: GenShen: ShenandoahGCHeuristics flag not reset after ignoring non-adaptive value Backport-of: 5acbf8baea3f1a982bdba29b51c8531caa919748 --- .../gc/shenandoah/shenandoahArguments.cpp | 1 + .../options/TestGenerationalHeuristics.java | 84 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 test/hotspot/jtreg/gc/shenandoah/options/TestGenerationalHeuristics.java 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/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); + } + } + +} From 6e00cb2ceb449be9317208c0a04306d06fd93375 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Fri, 8 May 2026 17:15:18 +0000 Subject: [PATCH 14/34] 8367646: [GenShen] Control thread may overwrite gc cancellation cause set by mutator Backport-of: d6e2d4eb1f87016ab158b62c61c33c4bf92a0ed4 --- .../gc/shenandoah/shenandoahConcurrentGC.cpp | 2 +- .../gc/shenandoah/shenandoahDegeneratedGC.cpp | 2 +- .../share/gc/shenandoah/shenandoahFullGC.cpp | 2 +- .../shenandoahGenerationalControlThread.cpp | 3 +-- .../share/gc/shenandoah/shenandoahHeap.hpp | 11 +++++++--- .../gc/shenandoah/shenandoahHeap.inline.hpp | 20 ++++++++++++++----- 6 files changed, 27 insertions(+), 13 deletions(-) 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/shenandoahDegeneratedGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahDegeneratedGC.cpp index a986317e34ae..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()) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp index 91cf930a7ac3..b9455ebfeb0f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFullGC.cpp @@ -1168,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/shenandoahGenerationalControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp index f4943cb3da29..125c60b54460 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp @@ -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/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) { From ec2f03bfebb708db2fc08b52063b011a7dd58697 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Fri, 8 May 2026 17:15:53 +0000 Subject: [PATCH 15/34] 8380846: GenShen: Remove the experimental option to disable adaptive tenuring Backport-of: 4e7901576851ebe22b40349bf0e155b39ca6c34a --- .../gc/shenandoah/shenandoahAgeCensus.cpp | 28 ++++--------------- .../gc/shenandoah/shenandoahAgeCensus.hpp | 1 - .../gc/shenandoah/shenandoahGeneration.cpp | 2 +- .../gc/shenandoah/shenandoahMark.inline.hpp | 12 ++++---- .../gc/shenandoah/shenandoah_globals.hpp | 6 +--- 5 files changed, 12 insertions(+), 37 deletions(-) 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/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/shenandoahMark.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp index 2fff89d2b12c..09b872deadad 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahMark.inline.hpp @@ -117,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, \ From 391703e6b31455fa9c4e8b39d01b6642fa8b6beb Mon Sep 17 00:00:00 2001 From: William Kemper Date: Fri, 8 May 2026 17:16:32 +0000 Subject: [PATCH 16/34] 8382295: Shenandoah: wrong denominator in full gc summary Backport-of: 299973160d55f1318dd6c673267b4dcdefb64ac9 --- src/hotspot/share/gc/shenandoah/shenandoahCollectorPolicy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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)); From 963e328011218240abca74e84aab2a5a661fd41b Mon Sep 17 00:00:00 2001 From: William Kemper Date: Fri, 8 May 2026 17:17:13 +0000 Subject: [PATCH 17/34] 8361339: Test gc/shenandoah/TestLargeObjectAlignment.java#generational fails on macOS aarch64 with OOM: Java heap space Backport-of: e1c952608d61c6c74c3fa4d00789390f3a789de4 --- .../shenandoah/TestLargeObjectAlignment.java | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) 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; From b90d9660e8a7b365e0050a062a8d45fcb84a1b88 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Fri, 8 May 2026 17:17:48 +0000 Subject: [PATCH 18/34] 8366692: Several gc/shenandoah tests timed out Backport-of: 02dd21196ed27289a6fad92c4881af484ce9c258 --- test/hotspot/jtreg/gc/shenandoah/TestAllocObjects.java | 4 ++-- test/hotspot/jtreg/gc/shenandoah/TestSieveObjects.java | 4 ++-- .../jtreg/gc/shenandoah/jni/TestJNIGlobalRefs.java | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) 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/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/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 */ From 50dc6d1888828f05661516b859dc11047dc5fb6b Mon Sep 17 00:00:00 2001 From: William Kemper Date: Fri, 8 May 2026 17:18:17 +0000 Subject: [PATCH 19/34] 8353115: GenShen: mixed evacuation candidate regions need accurate live_data Backport-of: 72bf0bb6f6eaf61b3800d885733e23b7b42bf9c9 --- .../heuristics/shenandoahHeuristics.hpp | 7 +++++++ .../heuristics/shenandoahOldHeuristics.cpp | 15 +++++++++++++++ .../gc/shenandoah/shenandoahHeapRegion.cpp | 2 ++ .../gc/shenandoah/shenandoahHeapRegion.hpp | 11 +++++++++++ .../shenandoah/shenandoahHeapRegion.inline.hpp | 17 +++++++++++++++++ 5 files changed, 52 insertions(+) diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahHeuristics.hpp index fb8cfb363536..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; diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp index bd8b0d787b87..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++; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp index c27b568e7c5d..7184623eb3fc 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,6 +566,7 @@ void ShenandoahHeapRegion::recycle_internal() { assert(_recycling.is_set() && is_trash(), "Wrong state"); ShenandoahHeap* heap = ShenandoahHeap::heap(); + _mixed_candidate_garbage_words = 0; set_top(bottom()); clear_live_data(); reset_alloc_metadata(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp index 4c99364bc6ed..336f790529ca 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. @@ -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; } From 001212df8140452a58c88c21d1f02ff485d9b844 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Sun, 10 May 2026 14:01:44 +0000 Subject: [PATCH 20/34] 8383630: Fix iteration in tests doing class redefinition Backport-of: a2e271969da479ef28340d3e712e37ca1df2674a --- test/hotspot/jtreg/runtime/Metaspace/DefineClass.java | 2 +- test/hotspot/jtreg/runtime/vthread/RedefineClass.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/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; } From 34d1a3b9f8dfe5b900d5adf80ac4adbc0c0677fd Mon Sep 17 00:00:00 2001 From: Ralf Schmelter Date: Mon, 11 May 2026 08:33:19 +0000 Subject: [PATCH 21/34] 8378764: fileStream::fileSize() fails for >2GB files on Windows Backport-of: 1de03224b8d4924f052ef074d251621d58bf98e4 --- src/hotspot/os/posix/os_posix.cpp | 8 ++++++++ src/hotspot/os/windows/os_windows.cpp | 7 +++++++ src/hotspot/share/runtime/os.hpp | 2 ++ src/hotspot/share/utilities/ostream.cpp | 12 ++++++------ src/hotspot/share/utilities/ostream.hpp | 2 +- 5 files changed, 24 insertions(+), 7 deletions(-) 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/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(); }; From 4de604a62976d9796a787c20aa282eaa54f01920 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 11 May 2026 08:47:12 +0000 Subject: [PATCH 22/34] 8373515: Migrate "test/jdk/java/net/httpclient/" to null-safe "SimpleSSLContext" methods Reviewed-by: mdoerr Backport-of: 3a80c639d804a0697b8eb477fe4c96407709449b --- .../net/httpclient/ALPNProxyFailureTest.java | 11 +-- .../java/net/httpclient/AbstractNoBody.java | 5 +- .../AbstractThrowingPublishers.java | 6 +- .../AbstractThrowingPushPromises.java | 7 +- .../AbstractThrowingSubscribers.java | 6 +- .../httpclient/AggregateRequestBodyTest.java | 6 +- .../net/httpclient/AsFileDownloadTest.java | 6 +- .../net/httpclient/AsyncExecutorShutdown.java | 5 +- .../java/net/httpclient/AsyncShutdownNow.java | 5 +- .../net/httpclient/AuthFilterCacheTest.java | 9 +- .../java/net/httpclient/BasicAuthTest.java | 2 +- .../net/httpclient/BasicRedirectTest.java | 6 +- .../net/httpclient/CancelRequestTest.java | 6 +- .../httpclient/CancelStreamedBodyTest.java | 6 +- .../net/httpclient/CancelledResponse.java | 3 +- .../net/httpclient/CancelledResponse2.java | 3 +- .../net/httpclient/ConcurrentResponses.java | 6 +- .../httpclient/ContentLengthHeaderTest.java | 3 +- .../java/net/httpclient/CookieHeaderTest.java | 6 +- .../httpclient/CustomRequestPublisher.java | 8 +- .../httpclient/CustomResponseSubscriber.java | 8 +- .../net/httpclient/DependentActionsTest.java | 6 +- .../DependentPromiseActionsTest.java | 6 +- .../java/net/httpclient/DigestEchoClient.java | 9 +- .../net/httpclient/EmptyAuthenticate.java | 10 +- .../net/httpclient/EncodedCharsInURI.java | 6 +- .../net/httpclient/EscapedOctetsInURI.java | 6 +- .../java/net/httpclient/ExecutorShutdown.java | 6 +- .../java/net/httpclient/ExpectContinue.java | 8 +- .../net/httpclient/FilePublisherTest.java | 6 +- .../httpclient/FlowAdapterPublisherTest.java | 6 +- .../httpclient/FlowAdapterSubscriberTest.java | 6 +- .../net/httpclient/ForbiddenHeadTest.java | 7 +- .../net/httpclient/GZIPInputStreamTest.java | 6 +- test/jdk/java/net/httpclient/HeadTest.java | 6 +- .../HttpClientAuthRetryLimitTest.java | 10 +- .../net/httpclient/HttpClientBuilderTest.java | 6 +- .../java/net/httpclient/HttpClientClose.java | 5 +- .../httpclient/HttpClientLocalAddrTest.java | 5 +- .../net/httpclient/HttpClientSNITest.java | 6 +- .../net/httpclient/HttpClientShutdown.java | 5 +- .../httpclient/HttpGetInCancelledFuture.java | 6 +- .../java/net/httpclient/HttpRedirectTest.java | 9 +- .../HttpResponseConnectionLabelTest.java | 10 +- .../httpclient/HttpResponseLimitingTest.java | 10 +- .../net/httpclient/HttpSlowServerTest.java | 9 +- .../java/net/httpclient/HttpVersionsTest.java | 8 +- .../net/httpclient/HttpsTunnelAuthTest.java | 9 +- .../java/net/httpclient/HttpsTunnelTest.java | 11 +-- .../java/net/httpclient/ISO_8859_1_Test.java | 6 +- .../net/httpclient/ImmutableFlowItems.java | 8 +- ...InvalidInputStreamSubscriptionRequest.java | 6 +- .../net/httpclient/InvalidSSLContextTest.java | 8 +- .../InvalidSubscriptionRequest.java | 6 +- .../net/httpclient/LargeResponseTest.java | 9 +- .../net/httpclient/LightWeightHttpServer.java | 5 +- .../net/httpclient/LineBodyHandlerTest.java | 6 +- .../jdk/java/net/httpclient/ManyRequests.java | 2 +- .../net/httpclient/ManyRequestsLegacy.java | 4 +- .../httpclient/MappingResponseSubscriber.java | 8 +- test/jdk/java/net/httpclient/MaxStreams.java | 5 +- .../net/httpclient/NonAsciiCharsInURI.java | 6 +- .../BodyHandlerOfFileDownloadTest.java | 6 +- .../PathSubscriber/BodyHandlerOfFileTest.java | 6 +- .../BodySubscriberOfFileTest.java | 6 +- .../net/httpclient/ProxySelectorTest.java | 8 +- test/jdk/java/net/httpclient/ProxyTest.java | 18 ++-- .../net/httpclient/RedirectMethodChange.java | 6 +- .../net/httpclient/RedirectTimeoutTest.java | 2 +- .../net/httpclient/RedirectWithCookie.java | 6 +- .../java/net/httpclient/Response1xxTest.java | 6 +- .../net/httpclient/Response204V2Test.java | 6 +- .../httpclient/ResponseBodyBeforeError.java | 7 +- .../net/httpclient/ResponsePublisher.java | 6 +- .../java/net/httpclient/RetryWithCookie.java | 6 +- .../java/net/httpclient/ServerCloseTest.java | 8 +- .../net/httpclient/ShortResponseBody.java | 7 +- test/jdk/java/net/httpclient/ShutdownNow.java | 6 +- test/jdk/java/net/httpclient/SmokeTest.java | 5 +- .../net/httpclient/SpecialHeadersTest.java | 5 +- .../java/net/httpclient/SplitResponse.java | 5 +- .../java/net/httpclient/StreamingBody.java | 6 +- .../jdk/java/net/httpclient/TimeoutBasic.java | 6 +- .../java/net/httpclient/TlsContextTest.java | 10 +- .../java/net/httpclient/UnauthorizedTest.java | 6 +- .../net/httpclient/UnknownBodyLengthTest.java | 5 +- .../httpclient/UserAuthWithAuthenticator.java | 2 +- .../java/net/httpclient/UserCookieTest.java | 6 +- .../net/httpclient/http2/BadHeadersTest.java | 6 +- .../java/net/httpclient/http2/BasicTest.java | 4 +- .../http2/ConnectionFlowControlTest.java | 6 +- .../httpclient/http2/ConnectionReuseTest.java | 6 +- .../http2/ContinuationFrameTest.java | 6 +- .../java/net/httpclient/http2/ErrorTest.java | 4 +- .../httpclient/http2/FixedThreadPoolTest.java | 4 +- .../net/httpclient/http2/H2GoAwayTest.java | 4 +- .../java/net/httpclient/http2/NoBodyTest.java | 6 +- .../java/net/httpclient/http2/ProxyTest2.java | 18 ++-- .../http2/StreamFlowControlTest.java | 6 +- .../net/httpclient/http2/UserInfoTest.java | 5 +- .../websocket/HandshakeUrlEncodingTest.java | 9 +- .../websocket/WSHandshakeExceptionTest.java | 8 +- .../websocket/WebSocketProxyTest.java | 8 +- .../httpclient/whitebox/FlowTestDriver.java | 1 + .../whitebox/SSLEchoTubeTestDriver.java | 3 +- .../whitebox/SSLFlowDelegateTestDriver.java | 3 +- .../whitebox/SSLTubeTestDriver.java | 3 +- .../net/http/AbstractSSLTubeTest.java | 6 +- .../jdk/internal/net/http/FlowTest.java | 4 +- .../net/http/SSLFlowDelegateTest.java | 9 +- .../jdk/internal/net/http/SSLTubeTest.java | 4 +- .../internal/net/http/SimpleSSLContext.java | 95 ------------------- .../http/SimpleSSLContextWhiteboxAdapter.java | 48 ++++++++++ 113 files changed, 222 insertions(+), 625 deletions(-) delete mode 100644 test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContext.java create mode 100644 test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContextWhiteboxAdapter.java 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"); + } + +} From 1865c63c035e4bf51add8e87be4cfd993fe0b6db Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 11 May 2026 08:49:57 +0000 Subject: [PATCH 23/34] =?UTF-8?q?8377727:=20Ghost=20caret=20and=20focus=20?= =?UTF-8?q?appear=20in=20non=E2=80=91editable=20text=20fields?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport-of: 635c4b96187ed282a1f58c38c5c04fb8331e119d --- .../javax/swing/text/DefaultCaret.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) 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); From d37b1cc8e46f5b52758743115e621f220576dfde Mon Sep 17 00:00:00 2001 From: Xiaolong Peng Date: Tue, 12 May 2026 16:06:29 +0000 Subject: [PATCH 24/34] 8381382: Shenandoah: assert(capacity > 0) failed: free regions must have allocation capacity Reviewed-by: wkemper, kdnilsen, phh Backport-of: 01bfd427a322c6f92643c7920bbd1b1b35141a69 --- .../gc/shenandoah/shenandoahHeapRegion.cpp | 18 +++++++++++++----- .../gc/shenandoah/shenandoahHeapRegion.hpp | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp index 7184623eb3fc..2736376fe9a2 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.cpp @@ -567,7 +567,6 @@ void ShenandoahHeapRegion::recycle_internal() { ShenandoahHeap* heap = ShenandoahHeap::heap(); _mixed_candidate_garbage_words = 0; - set_top(bottom()); clear_live_data(); reset_alloc_metadata(); heap->marking_context()->reset_top_at_mark_start(this); @@ -575,14 +574,19 @@ void ShenandoahHeapRegion::recycle_internal() { if (ZapUnusedHeapArea) { 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()); @@ -602,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(); @@ -827,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 336f790529ca..20040eebafd8 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp @@ -217,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(); From abbda0b14d981ba3715349460f461041fa4ac792 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 12 May 2026 16:34:35 +0000 Subject: [PATCH 25/34] 8384158: GHA: Downgrade Windows GHA runners to windows-2022 temporarily Reviewed-by: andrew Backport-of: aedcac949a4cdfe1ea947587346251870941325f --- .github/workflows/build-windows.yml | 5 ++++- .github/workflows/main.yml | 4 +++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index a3091b94cef1..4a0e0c29a01b 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 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 09e6ed65a47d..809740a18f76 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -353,6 +353,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 }} @@ -366,6 +367,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' @@ -446,6 +448,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 From e14f5f07a18ccebae448aa17cd3a0da7be09ac2f Mon Sep 17 00:00:00 2001 From: Jean-Philippe Bempel Date: Wed, 13 May 2026 23:34:47 +0000 Subject: [PATCH 26/34] 8376185: NoSuchFieldError thrown after a record with type annotation retransformed Backport-of: 0c60c9ca1477a114a9c7095226d3a1e5d31600fb --- .../share/prims/jvmtiRedefineClasses.cpp | 4 +- .../RetransformRecordTypeAnn/MyRecord.java | 47 ++ .../TestRetransformRecord.java | 94 ++++ .../altered/MyRecord.jcod | 421 ++++++++++++++++++ test/lib/RedefineClassHelper.java | 2 +- 5 files changed, 566 insertions(+), 2 deletions(-) create mode 100644 test/jdk/java/lang/instrument/RetransformRecordTypeAnn/MyRecord.java create mode 100644 test/jdk/java/lang/instrument/RetransformRecordTypeAnn/TestRetransformRecord.java create mode 100644 test/jdk/java/lang/instrument/RetransformRecordTypeAnn/altered/MyRecord.jcod 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/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..88b4c038a39c --- /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/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"); } } From f7fa56e49d44bc7867f9f22bc6cfc080437760e0 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Fri, 15 May 2026 09:06:55 +0000 Subject: [PATCH 27/34] 8381205: GHA: Upgrade Node.js 20 to 24 Backport-of: 5755ce6a86a4c4ac6e374cbf073a64e97c72f103 --- .github/actions/build-jtreg/action.yml | 6 +++--- .github/actions/do-build/action.yml | 4 ++-- .github/actions/get-bootjdk/action.yml | 2 +- .github/actions/get-bundles/action.yml | 6 +++--- .github/actions/get-gtest/action.yml | 2 +- .github/actions/get-jtreg/action.yml | 2 +- .github/actions/get-msys2/action.yml | 2 +- .github/actions/upload-bundles/action.yml | 2 +- .github/workflows/build-alpine-linux.yml | 2 +- .github/workflows/build-cross-compile.yml | 4 ++-- .github/workflows/build-linux.yml | 2 +- .github/workflows/build-macos.yml | 2 +- .github/workflows/build-windows.yml | 2 +- .github/workflows/main.yml | 2 +- .github/workflows/test.yml | 6 +++--- 15 files changed, 23 insertions(+), 23 deletions(-) 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 ca5366f3d6c3..9c5e2674b141 100644 --- a/.github/actions/upload-bundles/action.yml +++ b/.github/actions/upload-bundles/action.yml @@ -87,7 +87,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 a39b342a248a..a9e14d06988d 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 e70937f57b68..377d30bacb2e 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 0680dea6bbea..904b6c0f809a 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 0a12df668e55..a449618d0157 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 4a0e0c29a01b..7a5a9e45838a 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -86,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 809740a18f76..b3a615aafb39 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -75,7 +75,7 @@ jobs: steps: - name: 'Checkout the scripts' - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: sparse-checkout: | .github 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' From 4c7fde58285d3b0aaf0baa5b39093443589f1d22 Mon Sep 17 00:00:00 2001 From: Christoph Langer Date: Fri, 15 May 2026 09:58:51 +0000 Subject: [PATCH 28/34] 8384540: [25u, 21u, 17u] Update GHA JDKs after Apr/26 updates Reviewed-by: mbaesken, sgehwolf --- make/conf/github-actions.conf | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/make/conf/github-actions.conf b/make/conf/github-actions.conf index 438e4b3ce8d0..16432a56ba28 100644 --- a/make/conf/github-actions.conf +++ b/make/conf/github-actions.conf @@ -29,21 +29,21 @@ GTEST_VERSION=1.14.0 JTREG_VERSION=8+2 LINUX_X64_BOOT_JDK_EXT=tar.gz -LINUX_X64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_linux-x64_bin.tar.gz -LINUX_X64_BOOT_JDK_SHA256=88b090fa80c6c1d084ec9a755233967458788e2c0777ae2e172230c5c692d7ef +LINUX_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.3%2B9/OpenJDK25U-jdk_x64_linux_hotspot_25.0.3_9.tar.gz +LINUX_X64_BOOT_JDK_SHA256=69264a7a211bf5029830d07bc3370f879769d62ebc5b5488e90c9343a2da0e1f ALPINE_LINUX_X64_BOOT_JDK_EXT=tar.gz -ALPINE_LINUX_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin24-binaries/releases/download/jdk-24%2B36/OpenJDK24U-jdk_x64_alpine-linux_hotspot_24_36.tar.gz -ALPINE_LINUX_X64_BOOT_JDK_SHA256=a642608f0da78344ee6812fb1490b8bc1d7ad5a18064c70994d6f330568c51cb +ALPINE_LINUX_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.3%2B9/OpenJDK25U-jdk_x64_alpine-linux_hotspot_25.0.3_9.tar.gz +ALPINE_LINUX_X64_BOOT_JDK_SHA256=51c2415b370aac7c3796b0c4663c8fcf91bc22d76f03df95b25fa5667cb5fdd8 MACOS_AARCH64_BOOT_JDK_EXT=tar.gz -MACOS_AARCH64_BOOT_JDK_URL=https://download.java.net/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_macos-aarch64_bin.tar.gz -MACOS_AARCH64_BOOT_JDK_SHA256=f7133238a12714a62c5ad2bd4da6741130be1a82512065da9ca23dee26b2d3d3 +MACOS_AARCH64_BOOT_JDK_URL=https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.3%2B9/OpenJDK25U-jdk_aarch64_mac_hotspot_25.0.3_9.tar.gz +MACOS_AARCH64_BOOT_JDK_SHA256=7baab4d69a15554e119b86ff78d40e3fdc28819b5b322955c913cebfe3f6a37c 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://download.java.net/java/GA/jdk24/1f9ff9062db4449d8ca828c504ffae90/36/GPL/openjdk-24_windows-x64_bin.zip -WINDOWS_X64_BOOT_JDK_SHA256=11d1d9f6ac272d5361c8a0bef01894364081c7fb1a6914c2ad2fc312ae83d63b +WINDOWS_X64_BOOT_JDK_URL=https://github.com/adoptium/temurin25-binaries/releases/download/jdk-25.0.3%2B9/OpenJDK25U-jdk_x64_windows_hotspot_25.0.3_9.zip +WINDOWS_X64_BOOT_JDK_SHA256=709312cd0420296d9b9de917fe6e28a5b979e875ee5ab91783fb79bcd5857235 From 19f1136632876441632a3b9a4ce0ae742a5dde37 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Fri, 15 May 2026 15:29:56 +0000 Subject: [PATCH 29/34] 8382395: Disable stringop-overflow in shenandoahGenerationalHeap.cpp Backport-of: 1f782b7a5209cdcde0d95adbe38ca6911e080c2b --- make/hotspot/lib/CompileJvm.gmk | 1 + 1 file changed, 1 insertion(+) 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, \ From 064cc920a5b039da6127ac5984db90063f54b9e5 Mon Sep 17 00:00:00 2001 From: Fei Yang Date: Sun, 17 May 2026 16:02:49 +0000 Subject: [PATCH 30/34] 8384223: RISC-V: entry_barrier_offset should consider UseZtso Backport-of: 776bb729e88ad88805b7ce093bcc02c3d185005c --- .../gc/shared/barrierSetAssembler_riscv.cpp | 16 +++++++----- .../gc/shared/barrierSetNMethod_riscv.cpp | 26 +++++++++---------- 2 files changed, 22 insertions(+), 20 deletions(-) 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; From 8c68029d0c17e7475af7ed355c91f89151d77961 Mon Sep 17 00:00:00 2001 From: Roland Mesde Date: Mon, 18 May 2026 16:33:56 +0000 Subject: [PATCH 31/34] 8372351: Add 2 WISeKey roots Backport-of: 6e0008b91f73f8f495027f29fe4cb13238b6caba --- .../share/data/cacerts/wisekeyglobalrootgbca | 29 +++++++++++++++ .../share/data/cacerts/wisekeyglobalrootgcca | 22 +++++++++++ .../certification/CAInterop.java | 37 ++++++++++++++++++- .../security/lib/cacerts/VerifyCACerts.java | 12 ++++-- 4 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 src/java.base/share/data/cacerts/wisekeyglobalrootgbca create mode 100644 src/java.base/share/data/cacerts/wisekeyglobalrootgcca 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/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 1d28c3494e78..c2c58b36c383 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; @@ -47,12 +47,12 @@ public class VerifyCACerts { + File.separator + "security" + File.separator + "cacerts"; // The numbers of certs now. - private static final int COUNT = 109; + private static final int COUNT = 111; // SHA-256 of cacerts, can be generated with // shasum -a 256 cacerts | sed -e 's/../&:/g' | tr '[:lower:]' '[:upper:]' | cut -c1-95 private static final String CHECKSUM - = "70:73:12:D3:E8:01:89:28:F5:3D:10:8E:45:34:F6:28:CB:BF:AD:18:19:6D:F1:A2:E7:28:84:30:0B:E1:A6:9F"; + = "26:75:A0:AA:6E:7C:15:8B:BC:CF:11:81:38:3E:E7:94:31:9E:36:2D:F9:A6:BC:88:E1:A5:F8:46:9A:4C:1D:D7"; // Hex formatter to upper case with ":" delimiter private static final HexFormat HEX = HexFormat.ofDelimiter(":").withUpperCase(); @@ -279,6 +279,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"); } }; From 54440e5fe7ee8c789e356aec220506c483a064de Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Tue, 19 May 2026 08:34:02 +0000 Subject: [PATCH 32/34] 8383354: Update LCMS to 2.19.1 Backport-of: bcbf5cf730ee9a51c52310a6dfc36cd22111fe87 --- src/java.desktop/share/legal/lcms.md | 3 +- .../share/native/liblcms/cmscgats.c | 42 ++- .../share/native/liblcms/cmserr.c | 55 +++- .../share/native/liblcms/cmsio0.c | 241 ++++++++++++------ .../share/native/liblcms/cmslut.c | 11 +- .../share/native/liblcms/cmsnamed.c | 16 +- .../share/native/liblcms/cmsopt.c | 12 +- .../share/native/liblcms/cmsps2.c | 36 ++- .../share/native/liblcms/cmssamp.c | 48 +++- .../share/native/liblcms/cmstypes.c | 14 + .../share/native/liblcms/cmsvirt.c | 15 +- .../share/native/liblcms/cmsxform.c | 33 ++- src/java.desktop/share/native/liblcms/lcms2.h | 38 ++- .../share/native/liblcms/lcms2_internal.h | 1 + 14 files changed, 452 insertions(+), 113 deletions(-) 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 ---------------------------------------------------------------------------------------------------------
 

From 300093b7f798731aada78c1fee7bd368bd8e4a71 Mon Sep 17 00:00:00 2001
From: sophia-guo 
Date: Tue, 19 May 2026 17:52:26 +0000
Subject: [PATCH 33/34] =?UTF-8?q?8382932:=20[25u]=20Test=20java/lang/instr?=
 =?UTF-8?q?ument/RetransformRecordTypeAnn/TestRetransformRecord.java?=
 =?UTF-8?q?=E2=80=8E=20fails=20with=20compilation=20error?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Reviewed-by: goetz
---
 .../RetransformRecordTypeAnn/altered/MyRecord.jcod   | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/altered/MyRecord.jcod b/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/altered/MyRecord.jcod
index 88b4c038a39c..ef2d01c89ba4 100644
--- a/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/altered/MyRecord.jcod
+++ b/test/jdk/java/lang/instrument/RetransformRecordTypeAnn/altered/MyRecord.jcod
@@ -36,18 +36,18 @@ class MyRecord {
   [] {                                     // Constant Pool
     ;                                      // first element is empty
     Method #2 #3;                          // #1
-    Class #4;                              // #2
+    class #4;                              // #2
     NameAndType #5 #6;                     // #3
     Utf8 "java/lang/Record";               // #4
     Utf8 "";                         // #5
     Utf8 "()V";                            // #6
     Field #8 #9;                           // #7
-    Class #11;                             // #8
+    class #11;                             // #8
     NameAndType #10 #12;                   // #9
     Utf8 "filter";                         // #10
     Utf8 "MyRecord";                       // #11
     Utf8 "Ljava/lang/String;";             // #12
-    Class #34;                             // #13
+    class #34;                             // #13
     Utf8 "LMyTypeUseAnnotation;";          // #14
     String #16;                            // #15
     Utf8 "Filter cannot be null";          // #16
@@ -94,15 +94,15 @@ class MyRecord {
     MethodHandle 1b #7;                    // #57
     MethodHandle 6b #59;                   // #58
     Method #60 #61;                        // #59
-    Class #62;                             // #60
+    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
+    class #67;                             // #66
     Utf8 "java/lang/invoke/MethodHandles$Lookup";  // #67
-    Class #69;                             // #68
+    class #69;                             // #68
     Utf8 "java/lang/invoke/MethodHandles";  // #69
     Utf8 "Lookup";                         // #70
   }

From 5e86a483248d98fe1c1663b7f49a1850ecd36c30 Mon Sep 17 00:00:00 2001
From: SendaoYan 
Date: Wed, 20 May 2026 06:45:22 +0000
Subject: [PATCH 34/34] 8384815: SelectOneKeyOutOfMany and PreferredKey fail
 after expired test certificate

Backport-of: 1fcd11f41d1b50fb14e38fafefa492a31b166863
---
 .../ssl/X509KeyManager/PreferredKey.java      | 134 ++++----
 .../X509KeyManager/SelectOneKeyOutOfMany.java | 297 ++++++++----------
 2 files changed, 200 insertions(+), 231 deletions(-)

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);
     }
 }