From f5187ebf7a4d4241f01612b62c514a1e4e272658 Mon Sep 17 00:00:00 2001 From: Stefan Karlsson Date: Mon, 15 Dec 2025 12:57:03 +0000 Subject: [PATCH 001/390] 8373599: Cleanup arguments.hpp includes Reviewed-by: coleenp, kbarrett --- .../compiler/compilerDefinitions.inline.hpp | 1 + .../share/runtime/abstract_vm_version.cpp | 1 + src/hotspot/share/runtime/arguments.cpp | 11 ++++++++++ src/hotspot/share/runtime/arguments.hpp | 21 +++++++----------- src/hotspot/share/runtime/java.cpp | 21 ++++++++++++++++++ src/hotspot/share/runtime/java.hpp | 22 +++++-------------- test/hotspot/gtest/runtime/test_arguments.cpp | 1 + 7 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/hotspot/share/compiler/compilerDefinitions.inline.hpp b/src/hotspot/share/compiler/compilerDefinitions.inline.hpp index 21bf80549f4..8bf70477cb3 100644 --- a/src/hotspot/share/compiler/compilerDefinitions.inline.hpp +++ b/src/hotspot/share/compiler/compilerDefinitions.inline.hpp @@ -29,6 +29,7 @@ #include "compiler/compiler_globals.hpp" #include "runtime/arguments.hpp" +#include "runtime/globals.hpp" inline bool CompilerConfig::is_interpreter_only() { return Arguments::is_interpreter_only() || TieredStopAtLevel == CompLevel_none; diff --git a/src/hotspot/share/runtime/abstract_vm_version.cpp b/src/hotspot/share/runtime/abstract_vm_version.cpp index 3860307f8df..54c8c917fb3 100644 --- a/src/hotspot/share/runtime/abstract_vm_version.cpp +++ b/src/hotspot/share/runtime/abstract_vm_version.cpp @@ -26,6 +26,7 @@ #include "compiler/compilerDefinitions.hpp" #include "jvm_io.h" #include "runtime/arguments.hpp" +#include "runtime/os.hpp" #include "runtime/vm_version.hpp" #include "utilities/globalDefinitions.hpp" diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index d4ba599fa9b..cf0a1ab9757 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -1092,6 +1092,13 @@ void Arguments::print_summary_on(outputStream* st) { st->cr(); } +void Arguments::set_jvm_flags_file(const char *value) { + if (_jvm_flags_file != nullptr) { + os::free(_jvm_flags_file); + } + _jvm_flags_file = os::strdup_check_oom(value); +} + void Arguments::print_jvm_flags_on(outputStream* st) { if (_num_jvm_flags > 0) { for (int i=0; i < _num_jvm_flags; i++) { @@ -2844,6 +2851,10 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, JVMFlagOrigin return JNI_OK; } +void Arguments::set_ext_dirs(char *value) { + _ext_dirs = os::strdup_check_oom(value); +} + void Arguments::add_patch_mod_prefix(const char* module_name, const char* path) { // For java.base check for duplicate --patch-module options being specified on the command line. // This check is only required for java.base, all other duplicate module specifications diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index 3d83959d76a..f2bcc21e123 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -25,18 +25,17 @@ #ifndef SHARE_RUNTIME_ARGUMENTS_HPP #define SHARE_RUNTIME_ARGUMENTS_HPP -#include "logging/logLevel.hpp" -#include "logging/logTag.hpp" +#include "jni.h" #include "memory/allocation.hpp" #include "memory/allStatic.hpp" -#include "runtime/globals.hpp" +#include "runtime/flags/jvmFlag.hpp" #include "runtime/java.hpp" -#include "runtime/os.hpp" -#include "utilities/debug.hpp" -#include "utilities/vmEnums.hpp" +#include "utilities/globalDefinitions.hpp" // Arguments parses the command line and recognizes options +template +class GrowableArray; class JVMFlag; // Invocation API hook typedefs (these should really be defined in jni.h) @@ -412,12 +411,8 @@ class Arguments : AllStatic { // convenient methods to get and set jvm_flags_file static const char* get_jvm_flags_file() { return _jvm_flags_file; } - static void set_jvm_flags_file(const char *value) { - if (_jvm_flags_file != nullptr) { - os::free(_jvm_flags_file); - } - _jvm_flags_file = os::strdup_check_oom(value); - } + static void set_jvm_flags_file(const char *value); + // convenient methods to obtain / print jvm_flags and jvm_args static const char* jvm_flags() { return build_resource_string(_jvm_flags_array, _num_jvm_flags); } static const char* jvm_args() { return build_resource_string(_jvm_args_array, _num_jvm_args); } @@ -479,7 +474,7 @@ class Arguments : AllStatic { static void set_dll_dir(const char *value) { _sun_boot_library_path->set_value(value); } static void set_java_home(const char *value) { _java_home->set_value(value); } static void set_library_path(const char *value) { _java_library_path->set_value(value); } - static void set_ext_dirs(char *value) { _ext_dirs = os::strdup_check_oom(value); } + static void set_ext_dirs(char *value); // Set up the underlying pieces of the boot class path static void add_patch_mod_prefix(const char *module_name, const char *path); diff --git a/src/hotspot/share/runtime/java.cpp b/src/hotspot/share/runtime/java.cpp index fb4abdac2ef..c49a9f5d4b8 100644 --- a/src/hotspot/share/runtime/java.cpp +++ b/src/hotspot/share/runtime/java.cpp @@ -71,6 +71,7 @@ #include "runtime/interfaceSupport.inline.hpp" #include "runtime/java.hpp" #include "runtime/javaThread.hpp" +#include "runtime/os.hpp" #include "runtime/sharedRuntime.hpp" #include "runtime/stubRoutines.hpp" #include "runtime/task.hpp" @@ -765,3 +766,23 @@ void JDK_Version::to_string(char* buffer, size_t buflen) const { } } } + +void JDK_Version::set_java_version(const char* version) { + _java_version = os::strdup(version); +} + +void JDK_Version::set_runtime_name(const char* name) { + _runtime_name = os::strdup(name); +} + +void JDK_Version::set_runtime_version(const char* version) { + _runtime_version = os::strdup(version); +} + +void JDK_Version::set_runtime_vendor_version(const char* vendor_version) { + _runtime_vendor_version = os::strdup(vendor_version); +} + +void JDK_Version::set_runtime_vendor_vm_bug_url(const char* vendor_vm_bug_url) { + _runtime_vendor_vm_bug_url = os::strdup(vendor_vm_bug_url); +} diff --git a/src/hotspot/share/runtime/java.hpp b/src/hotspot/share/runtime/java.hpp index 67cf3fb686a..f7f1fb5e892 100644 --- a/src/hotspot/share/runtime/java.hpp +++ b/src/hotspot/share/runtime/java.hpp @@ -25,7 +25,6 @@ #ifndef SHARE_RUNTIME_JAVA_HPP #define SHARE_RUNTIME_JAVA_HPP -#include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" class Handle; @@ -133,38 +132,27 @@ class JDK_Version { static const char* java_version() { return _java_version; } - static void set_java_version(const char* version) { - _java_version = os::strdup(version); - } + static void set_java_version(const char* version); static const char* runtime_name() { return _runtime_name; } - static void set_runtime_name(const char* name) { - _runtime_name = os::strdup(name); - } + static void set_runtime_name(const char* name); static const char* runtime_version() { return _runtime_version; } - static void set_runtime_version(const char* version) { - _runtime_version = os::strdup(version); - } + static void set_runtime_version(const char* version); static const char* runtime_vendor_version() { return _runtime_vendor_version; } - static void set_runtime_vendor_version(const char* vendor_version) { - _runtime_vendor_version = os::strdup(vendor_version); - } + static void set_runtime_vendor_version(const char* vendor_version); static const char* runtime_vendor_vm_bug_url() { return _runtime_vendor_vm_bug_url; } - static void set_runtime_vendor_vm_bug_url(const char* vendor_vm_bug_url) { - _runtime_vendor_vm_bug_url = os::strdup(vendor_vm_bug_url); - } - + static void set_runtime_vendor_vm_bug_url(const char* vendor_vm_bug_url); }; #endif // SHARE_RUNTIME_JAVA_HPP diff --git a/test/hotspot/gtest/runtime/test_arguments.cpp b/test/hotspot/gtest/runtime/test_arguments.cpp index 074636fea0d..17404f45be2 100644 --- a/test/hotspot/gtest/runtime/test_arguments.cpp +++ b/test/hotspot/gtest/runtime/test_arguments.cpp @@ -24,6 +24,7 @@ #include "jvm.h" #include "runtime/arguments.hpp" #include "runtime/flags/jvmFlag.hpp" +#include "runtime/os.hpp" #include "utilities/align.hpp" #include "utilities/globalDefinitions.hpp" From 1f47294cd336db34030ea16132490ab51310ace5 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Mon, 15 Dec 2025 13:36:12 +0000 Subject: [PATCH 002/390] 8287062: com/sun/jndi/ldap/LdapPoolTimeoutTest.java failed due to different timeout message Reviewed-by: aefimov --- .../sun/jndi/ldap/LdapPoolTimeoutTest.java | 91 +++++++++++-------- 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java b/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java index 294e0f5f1a8..b47433ca16f 100644 --- a/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java +++ b/test/jdk/com/sun/jndi/ldap/LdapPoolTimeoutTest.java @@ -35,6 +35,8 @@ import org.testng.annotations.Test; import javax.naming.Context; import javax.naming.NamingException; import javax.naming.directory.InitialDirContext; + +import java.net.SocketTimeoutException; import java.util.ArrayList; import java.util.Hashtable; import java.util.List; @@ -82,14 +84,10 @@ public class LdapPoolTimeoutTest { env.put(Context.PROVIDER_URL, "ldap://example.com:1234"); try { - futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); - futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); - futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); - futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); - futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); - futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); - futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); - futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + // launch a few concurrent connection attempts + for (int i = 0; i < 8; i++) { + futures.add(executorService.submit(() -> { attemptConnect(env); return null; })); + } } finally { executorService.shutdown(); } @@ -109,38 +107,55 @@ public class LdapPoolTimeoutTest { private static void attemptConnect(Hashtable env) throws Exception { try { - LdapTimeoutTest.assertCompletion(CONNECT_MILLIS - 1000, - 2 * CONNECT_MILLIS + TOLERANCE, - () -> new InitialDirContext(env)); - } catch (RuntimeException e) { - final String msg = e.getCause() == null ? e.getMessage() : e.getCause().getMessage(); - // assertCompletion may wrap a CommunicationException in an RTE - if (msg != null && - (msg.contains("Network is unreachable") - || msg.contains("No route to host") - || msg.contains("Connection timed out"))) { - // got the expected exception - System.out.println("Received expected RuntimeException message: " + msg); - } else { - // propagate the unexpected exception - throw e; - } - } catch (NamingException ex) { - final String msg = ex.getCause() == null ? ex.getMessage() : ex.getCause().getMessage(); - if (msg != null && - (msg.contains("Network is unreachable") - || msg.contains("Timed out waiting for lock") - || msg.contains("Connect timed out") - || msg.contains("Timeout exceeded while waiting for a connection"))) { - // got the expected exception - System.out.println("Received expected NamingException message: " + msg); - } else { - // propagate the unexpected exception - throw ex; - } + final InitialDirContext unexpectedCtx = + LdapTimeoutTest.assertCompletion(CONNECT_MILLIS - 1000, + 2 * CONNECT_MILLIS + TOLERANCE, + () -> new InitialDirContext(env)); + throw new RuntimeException("InitialDirContext construction was expected to fail," + + " but returned " + unexpectedCtx); } catch (Throwable t) { - throw new RuntimeException(t); + final NamingException namingEx = findNamingException(t); + if (namingEx != null) { + // found the NamingException, verify it's the right reason + if (namingEx.getCause() instanceof SocketTimeoutException ste) { + // got the expected exception + System.out.println("Received expected SocketTimeoutException: " + ste); + return; + } + // rely on the exception message to verify the expected exception + final String msg = namingEx.getCause() == null + ? namingEx.getMessage() + : namingEx.getCause().getMessage(); + if (msg != null && + (msg.contains("Network is unreachable") + || msg.contains("No route to host") + || msg.contains("Timed out waiting for lock") + || msg.contains("Connect timed out") + || msg.contains("Timeout exceeded while waiting for a connection"))) { + // got the expected exception + System.out.println("Received expected NamingException with message: " + msg); + return; + } + } + // unexpected exception, propagate it + if (t instanceof Exception e) { + throw e; + } else { + throw new Exception(t); + } } } + // Find and return the NamingException from the given Throwable. Returns null if none found. + private static NamingException findNamingException(final Throwable t) { + Throwable cause = t; + while (cause != null) { + if (cause instanceof NamingException ne) { + return ne; + } + cause = cause.getCause(); + } + return null; + } + } From 34f241317ecd7473cfb6dcc2e6e5cf3a40299e2c Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 15 Dec 2025 14:18:46 +0000 Subject: [PATCH 003/390] 8371503: RETAIN_IMAGE_AFTER_TEST do not work for some tests Reviewed-by: lmesnik, dholmes --- test/hotspot/jtreg/containers/docker/DockerBasicTest.java | 4 +--- test/hotspot/jtreg/containers/docker/ShareTmpDir.java | 4 +--- test/hotspot/jtreg/containers/docker/TestCPUAwareness.java | 4 +--- test/hotspot/jtreg/containers/docker/TestLimitsUpdating.java | 4 +--- test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java | 4 +--- test/hotspot/jtreg/containers/docker/TestPids.java | 4 +--- .../jdk/internal/platform/docker/TestDockerMemoryMetrics.java | 4 +--- .../internal/platform/docker/TestGetFreeSwapSpaceSize.java | 4 +--- test/jdk/jdk/internal/platform/docker/TestLimitsUpdating.java | 4 +--- test/jdk/jdk/internal/platform/docker/TestPidsLimit.java | 4 +--- test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java | 2 ++ 11 files changed, 12 insertions(+), 30 deletions(-) diff --git a/test/hotspot/jtreg/containers/docker/DockerBasicTest.java b/test/hotspot/jtreg/containers/docker/DockerBasicTest.java index e564cae9d8e..403f46f6ab4 100644 --- a/test/hotspot/jtreg/containers/docker/DockerBasicTest.java +++ b/test/hotspot/jtreg/containers/docker/DockerBasicTest.java @@ -54,9 +54,7 @@ public class DockerBasicTest { testHelloDocker(); testJavaVersionWithCgMounts(); } finally { - if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { - DockerTestUtils.removeDockerImage(imageNameAndTag); - } + DockerTestUtils.removeDockerImage(imageNameAndTag); } } diff --git a/test/hotspot/jtreg/containers/docker/ShareTmpDir.java b/test/hotspot/jtreg/containers/docker/ShareTmpDir.java index a84cdacefa1..b7f807d76a3 100644 --- a/test/hotspot/jtreg/containers/docker/ShareTmpDir.java +++ b/test/hotspot/jtreg/containers/docker/ShareTmpDir.java @@ -57,9 +57,7 @@ public class ShareTmpDir { try { test(); } finally { - if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { - DockerTestUtils.removeDockerImage(imageName); - } + DockerTestUtils.removeDockerImage(imageName); } } diff --git a/test/hotspot/jtreg/containers/docker/TestCPUAwareness.java b/test/hotspot/jtreg/containers/docker/TestCPUAwareness.java index 26f160ab27d..6b0a536e4d4 100644 --- a/test/hotspot/jtreg/containers/docker/TestCPUAwareness.java +++ b/test/hotspot/jtreg/containers/docker/TestCPUAwareness.java @@ -85,9 +85,7 @@ public class TestCPUAwareness { } } finally { - if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { - DockerTestUtils.removeDockerImage(imageName); - } + DockerTestUtils.removeDockerImage(imageName); } } diff --git a/test/hotspot/jtreg/containers/docker/TestLimitsUpdating.java b/test/hotspot/jtreg/containers/docker/TestLimitsUpdating.java index db8f4fd1826..32436cec1d7 100644 --- a/test/hotspot/jtreg/containers/docker/TestLimitsUpdating.java +++ b/test/hotspot/jtreg/containers/docker/TestLimitsUpdating.java @@ -63,9 +63,7 @@ public class TestLimitsUpdating { try { testLimitUpdates(); } finally { - if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { - DockerTestUtils.removeDockerImage(imageName); - } + DockerTestUtils.removeDockerImage(imageName); } } diff --git a/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java b/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java index 6034aefcd6e..522b2904c43 100644 --- a/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java +++ b/test/hotspot/jtreg/containers/docker/TestMemoryAwareness.java @@ -102,9 +102,7 @@ public class TestMemoryAwareness { testMetricsSwapExceedingPhysical(); testContainerMemExceedsPhysical(); } finally { - if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { - DockerTestUtils.removeDockerImage(imageName); - } + DockerTestUtils.removeDockerImage(imageName); } } diff --git a/test/hotspot/jtreg/containers/docker/TestPids.java b/test/hotspot/jtreg/containers/docker/TestPids.java index 0e39268184e..2bc5f8c03c2 100644 --- a/test/hotspot/jtreg/containers/docker/TestPids.java +++ b/test/hotspot/jtreg/containers/docker/TestPids.java @@ -63,9 +63,7 @@ public class TestPids { try { testPids(); } finally { - if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { - DockerTestUtils.removeDockerImage(imageName); - } + DockerTestUtils.removeDockerImage(imageName); } } diff --git a/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java b/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java index 818c2c04a1d..12f90d65516 100644 --- a/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java +++ b/test/jdk/jdk/internal/platform/docker/TestDockerMemoryMetrics.java @@ -81,9 +81,7 @@ public class TestDockerMemoryMetrics { testMemorySoftLimit("500m","200m"); } finally { - if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { - DockerTestUtils.removeDockerImage(imageName); - } + DockerTestUtils.removeDockerImage(imageName); } } diff --git a/test/jdk/jdk/internal/platform/docker/TestGetFreeSwapSpaceSize.java b/test/jdk/jdk/internal/platform/docker/TestGetFreeSwapSpaceSize.java index 1e5160330de..6e07d2e9ed5 100644 --- a/test/jdk/jdk/internal/platform/docker/TestGetFreeSwapSpaceSize.java +++ b/test/jdk/jdk/internal/platform/docker/TestGetFreeSwapSpaceSize.java @@ -53,9 +53,7 @@ public class TestGetFreeSwapSpaceSize { "150M", Integer.toString(0) ); } finally { - if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { - DockerTestUtils.removeDockerImage(imageName); - } + DockerTestUtils.removeDockerImage(imageName); } } diff --git a/test/jdk/jdk/internal/platform/docker/TestLimitsUpdating.java b/test/jdk/jdk/internal/platform/docker/TestLimitsUpdating.java index a3df580fed1..a42eee358c3 100644 --- a/test/jdk/jdk/internal/platform/docker/TestLimitsUpdating.java +++ b/test/jdk/jdk/internal/platform/docker/TestLimitsUpdating.java @@ -62,9 +62,7 @@ public class TestLimitsUpdating { try { testLimitUpdates(); } finally { - if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { - DockerTestUtils.removeDockerImage(imageName); - } + DockerTestUtils.removeDockerImage(imageName); } } diff --git a/test/jdk/jdk/internal/platform/docker/TestPidsLimit.java b/test/jdk/jdk/internal/platform/docker/TestPidsLimit.java index 87ecae7ee62..0313fcc582d 100644 --- a/test/jdk/jdk/internal/platform/docker/TestPidsLimit.java +++ b/test/jdk/jdk/internal/platform/docker/TestPidsLimit.java @@ -59,9 +59,7 @@ public class TestPidsLimit { testPidsLimit("2000"); testPidsLimit("Unlimited"); } finally { - if (!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { - DockerTestUtils.removeDockerImage(imageName); - } + DockerTestUtils.removeDockerImage(imageName); } } diff --git a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java index 22a8572af46..b013561be0b 100644 --- a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java +++ b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java @@ -291,7 +291,9 @@ public class DockerTestUtils { * @throws Exception */ public static void removeDockerImage(String imageNameAndTag) throws Exception { + if(!DockerTestUtils.RETAIN_IMAGE_AFTER_TEST) { execute(Container.ENGINE_COMMAND, "rmi", "--force", imageNameAndTag); + } } From ea6493c4e1de2bc9615beee389b2d335669dc542 Mon Sep 17 00:00:00 2001 From: William Kemper Date: Mon, 15 Dec 2025 15:52:01 +0000 Subject: [PATCH 004/390] 8373100: Genshen: Control thread can miss allocation failure notification Reviewed-by: ysr, kdnilsen, xpeng --- .../shenandoahGenerationalControlThread.cpp | 23 +++++++++---------- .../shenandoahGenerationalControlThread.hpp | 11 ++++----- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp index ece4150f577..dfb28fd9ebb 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.cpp @@ -96,8 +96,7 @@ void ShenandoahGenerationalControlThread::stop_service() { log_debug(gc, thread)("Stopping control thread"); MonitorLocker ml(&_control_lock, Mutex::_no_safepoint_check_flag); _heap->cancel_gc(GCCause::_shenandoah_stop_vm); - _requested_gc_cause = GCCause::_shenandoah_stop_vm; - notify_cancellation(ml, GCCause::_shenandoah_stop_vm); + notify_control_thread(ml, GCCause::_shenandoah_stop_vm); // We can't wait here because it may interfere with the active cycle's ability // to reach a safepoint (this runs on a java thread). } @@ -140,7 +139,8 @@ void ShenandoahGenerationalControlThread::check_for_request(ShenandoahGCRequest& } ShenandoahGenerationalControlThread::GCMode ShenandoahGenerationalControlThread::prepare_for_allocation_failure_gc(ShenandoahGCRequest &request) { - + // Important: not all paths update the request.generation. This is intentional. + // A degenerated cycle must use the same generation carried over from the previous request. if (_degen_point == ShenandoahGC::_degenerated_unset) { _degen_point = ShenandoahGC::_degenerated_outside_cycle; request.generation = _heap->young_generation(); @@ -633,9 +633,7 @@ void ShenandoahGenerationalControlThread::service_stw_degenerated_cycle(const Sh void ShenandoahGenerationalControlThread::request_gc(GCCause::Cause cause) { if (ShenandoahCollectorPolicy::is_allocation_failure(cause)) { - // GC should already be cancelled. Here we are just notifying the control thread to - // wake up and handle the cancellation request, so we don't need to set _requested_gc_cause. - notify_cancellation(cause); + notify_control_thread(cause); } else if (ShenandoahCollectorPolicy::should_handle_requested_gc(cause)) { handle_requested_gc(cause); } @@ -661,7 +659,7 @@ bool ShenandoahGenerationalControlThread::request_concurrent_gc(ShenandoahGenera log_info(gc)("Preempting old generation mark to allow %s GC", generation->name()); while (gc_mode() == servicing_old) { ShenandoahHeap::heap()->cancel_gc(GCCause::_shenandoah_concurrent_gc); - notify_cancellation(ml, GCCause::_shenandoah_concurrent_gc); + notify_control_thread(ml, GCCause::_shenandoah_concurrent_gc); ml.wait(); } return true; @@ -701,14 +699,15 @@ void ShenandoahGenerationalControlThread::notify_control_thread(MonitorLocker& m ml.notify(); } -void ShenandoahGenerationalControlThread::notify_cancellation(GCCause::Cause cause) { +void ShenandoahGenerationalControlThread::notify_control_thread(GCCause::Cause cause) { MonitorLocker ml(&_control_lock, Mutex::_no_safepoint_check_flag); - notify_cancellation(ml, cause); + notify_control_thread(ml, cause); } -void ShenandoahGenerationalControlThread::notify_cancellation(MonitorLocker& ml, GCCause::Cause cause) { - assert(_heap->cancelled_gc(), "GC should already be cancelled"); - log_debug(gc,thread)("Notify control (%s): %s", gc_mode_name(gc_mode()), GCCause::to_string(cause)); +void ShenandoahGenerationalControlThread::notify_control_thread(MonitorLocker& ml, GCCause::Cause cause) { + assert(_control_lock.is_locked(), "Request lock must be held here"); + log_debug(gc, thread)("Notify control (%s): %s", gc_mode_name(gc_mode()), GCCause::to_string(cause)); + _requested_gc_cause = cause; ml.notify(); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.hpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.hpp index b7dbedd5e84..13e69d25268 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalControlThread.hpp @@ -135,16 +135,13 @@ private: // Return printable name for the given gc mode. static const char* gc_mode_name(GCMode mode); - // Takes the request lock and updates the requested cause and generation, then notifies the control thread. - // The overloaded variant should be used when the _control_lock is already held. + // These notify the control thread after updating _requested_gc_cause and (optionally) _requested_generation. + // Updating the requested generation is not necessary for allocation failures nor when stopping the thread. + void notify_control_thread(GCCause::Cause cause); + void notify_control_thread(MonitorLocker& ml, GCCause::Cause cause); void notify_control_thread(GCCause::Cause cause, ShenandoahGeneration* generation); void notify_control_thread(MonitorLocker& ml, GCCause::Cause cause, ShenandoahGeneration* generation); - // Notifies the control thread, but does not update the requested cause or generation. - // The overloaded variant should be used when the _control_lock is already held. - void notify_cancellation(GCCause::Cause cause); - void notify_cancellation(MonitorLocker& ml, GCCause::Cause cause); - // Configure the heap to age objects and regions if the aging period has elapsed. void maybe_set_aging_cycle(); From ad29642d8f4e8e0fb1223b14b85ab7841d7b1b51 Mon Sep 17 00:00:00 2001 From: Roland Westrelin Date: Mon, 15 Dec 2025 16:18:44 +0000 Subject: [PATCH 005/390] 8351889: C2 crash: assertion failed: Base pointers must match (addp 344) Reviewed-by: rcastanedalo, epeter --- src/hotspot/share/opto/addnode.hpp | 7 ++ src/hotspot/share/opto/c2_globals.hpp | 3 +- src/hotspot/share/opto/cfgnode.cpp | 36 +++++++++ src/hotspot/share/opto/cfgnode.hpp | 2 + src/hotspot/share/opto/compile.cpp | 5 +- src/hotspot/share/opto/phaseX.cpp | 21 ++++- src/hotspot/share/opto/phaseX.hpp | 5 ++ .../flags/jvmFlagConstraintsCompiler.cpp | 2 +- .../c2/TestMismatchedAddPAfterMaxUnroll.java | 80 +++++++++++++++++++ .../compiler/c2/TestVerifyIterativeGVN.java | 6 +- 10 files changed, 156 insertions(+), 11 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/c2/TestMismatchedAddPAfterMaxUnroll.java diff --git a/src/hotspot/share/opto/addnode.hpp b/src/hotspot/share/opto/addnode.hpp index 28ed73121ed..1bbdae92e48 100644 --- a/src/hotspot/share/opto/addnode.hpp +++ b/src/hotspot/share/opto/addnode.hpp @@ -246,6 +246,13 @@ public: // Do not match base-ptr edge virtual uint match_edge(uint idx) const; + +#ifdef ASSERT + bool address_input_has_same_base() const { + Node *addp = in(Address); + return !addp->is_AddP() || addp->in(Base)->is_top() || addp->in(Base) == in(Base); + } +#endif }; //------------------------------OrINode---------------------------------------- diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp index 2b2b4db47b1..7fa3ca638c2 100644 --- a/src/hotspot/share/opto/c2_globals.hpp +++ b/src/hotspot/share/opto/c2_globals.hpp @@ -697,7 +697,8 @@ "Print progress during Iterative Global Value Numbering") \ \ develop(uint, VerifyIterativeGVN, 0, \ - "Verify Iterative Global Value Numbering =DCBA, with:" \ + "Verify Iterative Global Value Numbering =EDCBA, with:" \ + " E: verify node specific invariants" \ " D: verify Node::Identity did not miss opportunities" \ " C: verify Node::Ideal did not miss opportunities" \ " B: verify that type(n) == n->Value() after IGVN" \ diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp index 203aa69ce1b..07657dd0883 100644 --- a/src/hotspot/share/opto/cfgnode.cpp +++ b/src/hotspot/share/opto/cfgnode.cpp @@ -2096,6 +2096,20 @@ bool PhiNode::is_split_through_mergemem_terminating() const { return true; } +// Is one of the inputs a Cast that has not been processed by igvn yet? +bool PhiNode::wait_for_cast_input_igvn(const PhaseIterGVN* igvn) const { + for (uint i = 1, cnt = req(); i < cnt; ++i) { + Node* n = in(i); + while (n != nullptr && n->is_ConstraintCast()) { + if (igvn->_worklist.member(n)) { + return true; + } + n = n->in(1); + } + } + return false; +} + //------------------------------Ideal------------------------------------------ // Return a node which is more "ideal" than the current node. Must preserve // the CFG, but we can still strip out dead paths. @@ -2154,6 +2168,28 @@ Node *PhiNode::Ideal(PhaseGVN *phase, bool can_reshape) { // If there is a chance that the region can be optimized out do // not add a cast node that we can't remove yet. !wait_for_region_igvn(phase)) { + // If one of the inputs is a cast that has yet to be processed by igvn, delay processing of this node to give the + // inputs a chance to optimize and possibly end up with identical inputs (casts included). + // Say we have: + // (Phi region (Cast#1 c uin) (Cast#2 c uin)) + // and Cast#1 and Cast#2 have not had a chance to common yet + // if the unique_input() transformation below proceeds, then PhiNode::Ideal returns: + // (Cast#3 region uin) (1) + // If PhiNode::Ideal is delayed until Cast#1 and Cast#2 common, then it returns: + // (Cast#1 c uin) (2) + // + // In (1) the resulting cast is conservatively pinned at a later control and while Cast#3 and Cast#1/Cast#2 still + // have a chance to common, that requires proving that c dominates region in ConstraintCastNode::dominating_cast() + // which may not happen if control flow is too complicated and another pass of loop opts doesn't run. Delaying the + // transformation here should allow a more optimal result. + // Beyond the efficiency concern, there is a risk, if the casts are CastPPs, to end up with a chain of AddPs with + // different base inputs (but a unique uncasted base input). This breaks an invariant in the shape of address + // subtrees. + PhaseIterGVN* igvn = phase->is_IterGVN(); + if (wait_for_cast_input_igvn(igvn)) { + igvn->_worklist.push(this); + return nullptr; + } uncasted = true; uin = unique_input(phase, true); } diff --git a/src/hotspot/share/opto/cfgnode.hpp b/src/hotspot/share/opto/cfgnode.hpp index bc0b38e2f97..f3ccf23703f 100644 --- a/src/hotspot/share/opto/cfgnode.hpp +++ b/src/hotspot/share/opto/cfgnode.hpp @@ -182,6 +182,8 @@ class PhiNode : public TypeNode { bool is_split_through_mergemem_terminating() const; + bool wait_for_cast_input_igvn(const PhaseIterGVN* igvn) const; + public: // Node layout (parallels RegionNode): enum { Region, // Control input is the Phi's region. diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 621ba684da1..16f5be50805 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -3418,10 +3418,7 @@ void Compile::final_graph_reshaping_main_switch(Node* n, Final_Reshape_Counts& f case Op_AddP: { // Assert sane base pointers Node *addp = n->in(AddPNode::Address); - assert( !addp->is_AddP() || - addp->in(AddPNode::Base)->is_top() || // Top OK for allocation - addp->in(AddPNode::Base) == n->in(AddPNode::Base), - "Base pointers must match (addp %u)", addp->_idx ); + assert(n->as_AddP()->address_input_has_same_base(), "Base pointers must match (addp %u)", addp->_idx ); #ifdef _LP64 if ((UseCompressedOops || UseCompressedClassPointers) && addp->Opcode() == Op_ConP && diff --git a/src/hotspot/share/opto/phaseX.cpp b/src/hotspot/share/opto/phaseX.cpp index 4a0933b89f2..1e4cd42e09a 100644 --- a/src/hotspot/share/opto/phaseX.cpp +++ b/src/hotspot/share/opto/phaseX.cpp @@ -1076,7 +1076,8 @@ void PhaseIterGVN::verify_optimize() { if (is_verify_Value() || is_verify_Ideal() || - is_verify_Identity()) { + is_verify_Identity() || + is_verify_invariants()) { ResourceMark rm; Unique_Node_List worklist; bool failure = false; @@ -1088,6 +1089,7 @@ void PhaseIterGVN::verify_optimize() { if (is_verify_Ideal()) { failure |= verify_Ideal_for(n, false); } if (is_verify_Ideal()) { failure |= verify_Ideal_for(n, true); } if (is_verify_Identity()) { failure |= verify_Identity_for(n); } + if (is_verify_invariants()) { failure |= verify_node_invariants_for(n); } // traverse all inputs and outputs for (uint i = 0; i < n->req(); i++) { if (n->in(i) != nullptr) { @@ -1102,7 +1104,7 @@ void PhaseIterGVN::verify_optimize() { // We should either make sure that these nodes are properly added back to the IGVN worklist // in PhaseIterGVN::add_users_to_worklist to update them again or add an exception // in the verification code above if that is not possible for some reason (like Load nodes). - assert(!failure, "Missed optimization opportunity in PhaseIterGVN"); + assert(!failure, "Missed optimization opportunity/broken graph in PhaseIterGVN"); } verify_empty_worklist(nullptr); @@ -2058,6 +2060,21 @@ bool PhaseIterGVN::verify_Identity_for(Node* n) { tty->print_cr("%s", ss.as_string()); return true; } + +// Some other verifications that are not specific to a particular transformation. +bool PhaseIterGVN::verify_node_invariants_for(const Node* n) { + if (n->is_AddP()) { + if (!n->as_AddP()->address_input_has_same_base()) { + stringStream ss; // Print as a block without tty lock. + ss.cr(); + ss.print_cr("Base pointers must match for AddP chain:"); + n->dump_bfs(2, nullptr, "", &ss); + tty->print_cr("%s", ss.as_string()); + return true; + } + } + return false; +} #endif /** diff --git a/src/hotspot/share/opto/phaseX.hpp b/src/hotspot/share/opto/phaseX.hpp index 473231e6af5..3f75aab8980 100644 --- a/src/hotspot/share/opto/phaseX.hpp +++ b/src/hotspot/share/opto/phaseX.hpp @@ -493,6 +493,7 @@ public: bool verify_Value_for(Node* n, bool strict = false); bool verify_Ideal_for(Node* n, bool can_reshape); bool verify_Identity_for(Node* n); + bool verify_node_invariants_for(const Node* n); void verify_empty_worklist(Node* n); #endif @@ -616,6 +617,10 @@ public: // '-XX:VerifyIterativeGVN=1000' return ((VerifyIterativeGVN % 10000) / 1000) == 1; } + static bool is_verify_invariants() { + // '-XX:VerifyIterativeGVN=10000' + return ((VerifyIterativeGVN % 100000) / 10000) == 1; + } protected: // Sub-quadratic implementation of '-XX:VerifyIterativeGVN=1' (Use-Def verification). julong _verify_counter; diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.cpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.cpp index d0141c2e6cc..63d3424b3ed 100644 --- a/src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.cpp +++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintsCompiler.cpp @@ -306,7 +306,7 @@ JVMFlag::Error TypeProfileLevelConstraintFunc(uint value, bool verbose) { } JVMFlag::Error VerifyIterativeGVNConstraintFunc(uint value, bool verbose) { - const int max_modes = 4; + const int max_modes = 5; uint original_value = value; for (int i = 0; i < max_modes; i++) { if (value % 10 > 1) { diff --git a/test/hotspot/jtreg/compiler/c2/TestMismatchedAddPAfterMaxUnroll.java b/test/hotspot/jtreg/compiler/c2/TestMismatchedAddPAfterMaxUnroll.java new file mode 100644 index 00000000000..2dcafd2cf6a --- /dev/null +++ b/test/hotspot/jtreg/compiler/c2/TestMismatchedAddPAfterMaxUnroll.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2025, Red Hat, 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 8351889 + * @summary C2 crash: assertion failed: Base pointers must match (addp 344) + * @run main/othervm -XX:-BackgroundCompilation -XX:CompileOnly=TestMismatchedAddPAfterMaxUnroll::test1 + * -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:-UseLoopPredicate + * -XX:+StressIGVN -XX:StressSeed=383593806 -XX:VerifyIterativeGVN=10000 + * TestMismatchedAddPAfterMaxUnroll + * @run main/othervm -XX:-BackgroundCompilation -XX:CompileOnly=TestMismatchedAddPAfterMaxUnroll::test1 + * -XX:+UnlockDiagnosticVMOptions -XX:+IgnoreUnrecognizedVMOptions -XX:-UseLoopPredicate + * -XX:+StressIGVN -XX:VerifyIterativeGVN=10000 TestMismatchedAddPAfterMaxUnroll + * @run main/othervm TestMismatchedAddPAfterMaxUnroll + */ + +public class TestMismatchedAddPAfterMaxUnroll { + private static C[] arrayField = new C[4]; + + public static void main(String[] args) { + C c = new C(); + Object lock = new Object(); + for (int i = 0; i < 20_000; i++) { + arrayField[3] = null; + test1(3, c, arrayField, true, true, lock); + arrayField[3] = null; + test1(3, c, arrayField, true, false, lock); + arrayField[3] = null; + test1(3, c, arrayField, false, false, lock); + arrayField[3] = c; + test1(3, c, arrayField, false, false, lock); + } + } + + static class C { + + } + + private static void test1(int j, C c, C[] otherArray, boolean flag, boolean flag2, Object lock) { + C[] array = arrayField; + int i = 0; + for (;;) { + synchronized (lock) {} + if (array[j] == null) { + break; + } + otherArray[i] = c; + i++; + if (i >= 3) { + return; + } + } + if (flag) { + if (flag2) { + } + } + array[j] = c; + } +} diff --git a/test/hotspot/jtreg/compiler/c2/TestVerifyIterativeGVN.java b/test/hotspot/jtreg/compiler/c2/TestVerifyIterativeGVN.java index 83f3540226f..4b6215b25bd 100644 --- a/test/hotspot/jtreg/compiler/c2/TestVerifyIterativeGVN.java +++ b/test/hotspot/jtreg/compiler/c2/TestVerifyIterativeGVN.java @@ -23,11 +23,11 @@ /* * @test - * @bug 8238756 + * @bug 8238756 8351889 * @requires vm.debug == true & vm.flavor == "server" - * @summary Run with -Xcomp to test -XX:VerifyIterativeGVN=1111 in debug builds. + * @summary Run with -Xcomp to test -XX:VerifyIterativeGVN=11111 in debug builds. * - * @run main/othervm/timeout=300 -Xcomp -XX:VerifyIterativeGVN=1111 compiler.c2.TestVerifyIterativeGVN + * @run main/othervm/timeout=300 -Xcomp -XX:VerifyIterativeGVN=11111 compiler.c2.TestVerifyIterativeGVN */ package compiler.c2; From 45ee89c4c8e3d8bb418b8578fb361e7dc1c12be5 Mon Sep 17 00:00:00 2001 From: Chris Plummer Date: Mon, 15 Dec 2025 19:50:46 +0000 Subject: [PATCH 006/390] 8373297: Test com/sun/jdi/AfterThreadDeathTest.java failed with unexpected ObjectCollectedException Reviewed-by: kevinw, sspitsyn, amenkov, lmesnik --- test/jdk/com/sun/jdi/AfterThreadDeathTest.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/jdk/com/sun/jdi/AfterThreadDeathTest.java b/test/jdk/com/sun/jdi/AfterThreadDeathTest.java index 27904021442..25987de864c 100644 --- a/test/jdk/com/sun/jdi/AfterThreadDeathTest.java +++ b/test/jdk/com/sun/jdi/AfterThreadDeathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -93,6 +93,7 @@ public class AfterThreadDeathTest extends TestScaffold { println("Ok; got expected IllegalThreadStateException"); return; } catch (Exception ee) { + ee.printStackTrace(System.err); failure("FAILED: Did not get expected" + " IllegalThreadStateException" + " on a StepRequest.enable(). \n" @@ -133,6 +134,13 @@ public class AfterThreadDeathTest extends TestScaffold { mainThread = bpe.thread(); erm = vm().eventRequestManager(); + /* + * The "main" thread will be referenced during the ThreadDeathEvent, which + * uses SUSPEND_NONE, so the thread might get gc'd and cause an unexpected + * ObjectCollectedException. Disable it from collection to prevent problems. + */ + mainThread.disableCollection(); + /* * Set event requests */ From f52d49925f9c60814a0a34720d7443e748b35c25 Mon Sep 17 00:00:00 2001 From: Sergey Chernyshev Date: Mon, 15 Dec 2025 20:19:05 +0000 Subject: [PATCH 007/390] 8319589: Attach from root to a user java process not supported in Mac Reviewed-by: sspitsyn --- src/hotspot/os/bsd/os_bsd.cpp | 84 +++++++++++++++++ src/hotspot/os/bsd/os_bsd.hpp | 8 +- src/hotspot/os/posix/os_posix.cpp | 4 + src/hotspot/os/posix/os_posix.hpp | 3 + src/hotspot/os/posix/perfMemory_posix.cpp | 18 +++- .../sun/tools/attach/VirtualMachineImpl.java | 56 +++++++++--- .../native/libattach/VirtualMachineImpl.c | 26 +----- .../sun/jvmstat/PlatformSupportImpl.java | 91 +++++++++++++++++++ .../share/classes/module-info.java | 4 +- 9 files changed, 252 insertions(+), 42 deletions(-) create mode 100644 src/jdk.internal.jvmstat/macosx/classes/sun/jvmstat/PlatformSupportImpl.java diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index dc8f5187b5a..61de48bb7fa 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -861,6 +861,90 @@ pid_t os::Bsd::gettid() { } } +// Returns the uid of a process or -1 on error. +uid_t os::Bsd::get_process_uid(pid_t pid) { + struct kinfo_proc kp; + size_t size = sizeof kp; + int mib_kern[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid}; + if (sysctl(mib_kern, 4, &kp, &size, nullptr, 0) == 0) { + if (size > 0 && kp.kp_proc.p_pid == pid) { + return kp.kp_eproc.e_ucred.cr_uid; + } + } + return (uid_t)-1; +} + +// Returns true if the process is running as root. +bool os::Bsd::is_process_root(pid_t pid) { + uid_t uid = get_process_uid(pid); + return (uid != (uid_t)-1) ? os::Posix::is_root(uid) : false; +} + +#ifdef __APPLE__ + +// macOS has a secure per-user temporary directory. +// Root can attach to a non-root process, hence it needs +// to lookup /var/folders for the user specific temporary directory +// of the form /var/folders/*/*/T, that contains PERFDATA_NAME_user +// directory. +static const char VAR_FOLDERS[] = "/var/folders/"; +int os::Bsd::get_user_tmp_dir_macos(const char* user, int vmid, char* output_path, int output_size) { + + // read the var/folders directory + DIR* varfolders_dir = os::opendir(VAR_FOLDERS); + if (varfolders_dir != nullptr) { + + // var/folders directory contains 2-characters subdirectories (buckets) + struct dirent* bucket_de; + + // loop until the PERFDATA_NAME_user directory has been found + while ((bucket_de = os::readdir(varfolders_dir)) != nullptr) { + // skip over files and special "." and ".." + if (bucket_de->d_type != DT_DIR || bucket_de->d_name[0] == '.') { + continue; + } + // absolute path to the bucket + char bucket[PATH_MAX]; + int b = os::snprintf(bucket, PATH_MAX, "%s%s/", VAR_FOLDERS, bucket_de->d_name); + + // the total length of the absolute path must not exceed the buffer size + if (b >= PATH_MAX || b < 0) { + continue; + } + // each bucket contains next level subdirectories + DIR* bucket_dir = os::opendir(bucket); + if (bucket_dir == nullptr) { + continue; + } + // read each subdirectory, skipping over regular files + struct dirent* subbucket_de; + while ((subbucket_de = os::readdir(bucket_dir)) != nullptr) { + if (subbucket_de->d_type != DT_DIR || subbucket_de->d_name[0] == '.') { + continue; + } + // If the PERFDATA_NAME_user directory exists in the T subdirectory, + // this means the subdirectory is the temporary directory of the user. + char perfdata_path[PATH_MAX]; + int p = os::snprintf(perfdata_path, PATH_MAX, "%s%s/T/%s_%s/", bucket, subbucket_de->d_name, PERFDATA_NAME, user); + + // the total length must not exceed the output buffer size + if (p >= PATH_MAX || p < 0) { + continue; + } + // check if the subdirectory exists + if (os::file_exists(perfdata_path)) { + // the return value of snprintf is not checked for the second time + return os::snprintf(output_path, output_size, "%s%s/T", bucket, subbucket_de->d_name); + } + } + os::closedir(bucket_dir); + } + os::closedir(varfolders_dir); + } + return -1; +} +#endif + intx os::current_thread_id() { #ifdef __APPLE__ return (intx)os::Bsd::gettid(); diff --git a/src/hotspot/os/bsd/os_bsd.hpp b/src/hotspot/os/bsd/os_bsd.hpp index 82002917f39..da73211b9a7 100644 --- a/src/hotspot/os/bsd/os_bsd.hpp +++ b/src/hotspot/os/bsd/os_bsd.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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,6 +61,12 @@ class os::Bsd { static pthread_t main_thread(void) { return _main_thread; } static pid_t gettid(); + static uid_t get_process_uid(pid_t pid); + static bool is_process_root(pid_t pid); + +#ifdef __APPLE__ + static int get_user_tmp_dir_macos(const char* user, int vmid, char* output_buffer, int buffer_size); +#endif static intptr_t* ucontext_get_sp(const ucontext_t* uc); static intptr_t* ucontext_get_fp(const ucontext_t* uc); diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index ef52b946cc6..07e1920c62d 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -1352,6 +1352,10 @@ bool os::Posix::is_root(uid_t uid){ return ROOT_UID == uid; } +bool os::Posix::is_current_user_root(){ + return is_root(geteuid()); +} + bool os::Posix::matches_effective_uid_or_root(uid_t uid) { return is_root(uid) || geteuid() == uid; } diff --git a/src/hotspot/os/posix/os_posix.hpp b/src/hotspot/os/posix/os_posix.hpp index 4b8b75ea07e..424d737cf42 100644 --- a/src/hotspot/os/posix/os_posix.hpp +++ b/src/hotspot/os/posix/os_posix.hpp @@ -76,6 +76,9 @@ public: // Returns true if given uid is root. static bool is_root(uid_t uid); + // Returns true if the current user is root. + static bool is_current_user_root(); + // Returns true if given uid is effective or root uid. static bool matches_effective_uid_or_root(uid_t uid); diff --git a/src/hotspot/os/posix/perfMemory_posix.cpp b/src/hotspot/os/posix/perfMemory_posix.cpp index 2cc0263d291..39bfc72a486 100644 --- a/src/hotspot/os/posix/perfMemory_posix.cpp +++ b/src/hotspot/os/posix/perfMemory_posix.cpp @@ -40,6 +40,9 @@ #if defined(LINUX) #include "os_linux.hpp" #endif +#if defined(BSD) +#include "os_bsd.hpp" +#endif # include # include @@ -142,6 +145,18 @@ static char* get_user_tmp_dir(const char* user, int vmid, int nspid) { jio_snprintf(buffer, TMP_BUFFER_LEN, "/proc/%d/root%s", vmid, tmpdir); tmpdir = buffer; } +#endif +#ifdef __APPLE__ + char buffer[PATH_MAX] = {0}; + // Check if the current user is root and the target VM is running as non-root. + // Otherwise the output of os::get_temp_directory() is used. + // + if (os::Posix::is_current_user_root() && !os::Bsd::is_process_root(vmid)) { + int path_size = os::Bsd::get_user_tmp_dir_macos(user, vmid, buffer, sizeof buffer); + if (path_size > 0 && (size_t)path_size < sizeof buffer) { + tmpdir = buffer; + } + } #endif const char* perfdir = PERFDATA_NAME; size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3; @@ -1138,7 +1153,8 @@ static void mmap_attach_shared(int vmid, char** addr, size_t* sizep, TRAPS) { // for linux, determine if vmid is for a containerized process int nspid = LINUX_ONLY(os::Linux::get_namespace_pid(vmid)) NOT_LINUX(-1); - const char* luser = get_user_name(vmid, &nspid, CHECK); + const char* luser = NOT_MACOS(get_user_name(vmid, &nspid, CHECK)) + MACOS_ONLY(get_user_name(os::Bsd::get_process_uid(vmid))); if (luser == nullptr) { THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), diff --git a/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java index 5c786db1366..a7a348affe3 100644 --- a/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java @@ -28,9 +28,13 @@ import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.spi.AttachProvider; +import sun.jvmstat.PlatformSupport; + import java.io.InputStream; import java.io.IOException; import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; import static java.nio.charset.StandardCharsets.UTF_8; @@ -39,14 +43,17 @@ import static java.nio.charset.StandardCharsets.UTF_8; */ @SuppressWarnings("restricted") public class VirtualMachineImpl extends HotSpotVirtualMachine { - // "tmpdir" is used as a global well-known location for the files - // .java_pid. and .attach_pid. It is important that this - // location is the same for all processes, otherwise the tools - // will not be able to find all Hotspot processes. - // This is intentionally not the same as java.io.tmpdir, since - // the latter can be changed by the user. - // Any changes to this needs to be synchronized with HotSpot. - private static final String tmpdir; + + /** + * HotSpot PerfData file prefix + */ + private static final String HSPERFDATA_PREFIX = "hsperfdata_"; + + /** + * Use platform specific methods for looking up temporary directories. + */ + private static final PlatformSupport platformSupport = PlatformSupport.getInstance(); + String socket_path; private OperationProperties props = new OperationProperties(VERSION_1); // updated in ctor @@ -67,10 +74,12 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { // Find the socket file. If not found then we attempt to start the // attach mechanism in the target VM by sending it a QUIT signal. // Then we attempt to find the socket file again. - File socket_file = new File(tmpdir, ".java_pid" + pid); + // In macOS the socket file is located in per-user temp directory. + String tempdir = getTempDirFromPid(pid); + File socket_file = new File(tempdir, ".java_pid" + pid); socket_path = socket_file.getPath(); if (!socket_file.exists()) { - File f = createAttachFile(pid); + File f = createAttachFile(tempdir, pid); try { checkCatchesAndSendQuitTo(pid, false); @@ -211,12 +220,34 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { } } - private File createAttachFile(int pid) throws IOException { + private File createAttachFile(String tmpdir, int pid) throws IOException { File f = new File(tmpdir, ".attach_pid" + pid); createAttachFile0(f.getPath()); return f; } + /* + * Returns a platform-specific temporary directory for a given process. + * In VMs running as unprivileged user it returns the default platform-specific + * temporary directory. In VMs running as root it searches over the list of + * temporary directories for one containing HotSpot PerfData directory. + */ + private String getTempDirFromPid(int pid) { + ProcessHandle ph = ProcessHandle.of(pid).orElse(null); + if (ph != null) { + String user = ph.info().user().orElse(null); + if (user != null) { + for (String dir : platformSupport.getTemporaryDirectories(pid)) { + Path fullPath = Path.of(dir, HSPERFDATA_PREFIX + user, String.valueOf(pid)); + if (Files.exists(fullPath)) { + return dir; + } + } + } + } + return PlatformSupport.getTemporaryDirectory(); + } + //-- native methods static native boolean checkCatchesAndSendQuitTo(int pid, boolean throwIfNotReady) throws IOException, AttachNotSupportedException; @@ -235,10 +266,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { static native void createAttachFile0(String path); - static native String getTempDir(); - static { System.loadLibrary("attach"); - tmpdir = getTempDir(); } } diff --git a/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c b/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c index d105d7d3b1b..5b2579eba39 100644 --- a/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c +++ b/src/jdk.attach/macosx/native/libattach/VirtualMachineImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -335,27 +335,3 @@ JNIEXPORT void JNICALL Java_sun_tools_attach_VirtualMachineImpl_createAttachFile JNU_ReleaseStringPlatformChars(env, path, _path); } } - -/* - * Class: sun_tools_attach_BSDVirtualMachine - * Method: getTempDir - * Signature: (V)Ljava.lang.String; - */ -JNIEXPORT jstring JNICALL Java_sun_tools_attach_VirtualMachineImpl_getTempDir(JNIEnv *env, jclass cls) -{ - // This must be hard coded because it's the system's temporary - // directory not the java application's temp directory, ala java.io.tmpdir. - -#ifdef __APPLE__ - // macosx has a secure per-user temporary directory. - // Don't cache the result as this is only called once. - char path[PATH_MAX]; - int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, path, PATH_MAX); - if (pathSize == 0 || pathSize > PATH_MAX) { - strlcpy(path, "/tmp", sizeof(path)); - } - return JNU_NewStringPlatform(env, path); -#else /* __APPLE__ */ - return (*env)->NewStringUTF(env, "/tmp"); -#endif /* __APPLE__ */ -} diff --git a/src/jdk.internal.jvmstat/macosx/classes/sun/jvmstat/PlatformSupportImpl.java b/src/jdk.internal.jvmstat/macosx/classes/sun/jvmstat/PlatformSupportImpl.java new file mode 100644 index 00000000000..f858fde4dce --- /dev/null +++ b/src/jdk.internal.jvmstat/macosx/classes/sun/jvmstat/PlatformSupportImpl.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2025, BELLSOFT. 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * 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 sun.jvmstat; + +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +/* + * macOS specific implementation of the PlatformSupport routines + * providing temporary directory support. + */ +public class PlatformSupportImpl extends PlatformSupport { + + private static final String VAR_FOLDERS_PATH = "/var/folders"; + private static final String USER_NAME_SYSTEM_PROPERTY = "user.name"; + private static final String USER_NAME_ROOT = "root"; + private static final String DIRHELPER_TEMP_STR = "T"; + + private static final boolean isCurrentUserRoot = + System.getProperty(USER_NAME_SYSTEM_PROPERTY).equals(USER_NAME_ROOT); + + public PlatformSupportImpl() { + super(); + } + + /* + * Return a list of the temporary directories that the VM uses + * for the attach and perf data files. + * + * This function returns the traditional temp directory. Additionally, + * when called by root, it returns other temporary directories of non-root + * users. + * + * macOS per-user temp directories are located under /var/folders + * and have the form /var/folders///T + */ + @Override + public List getTemporaryDirectories(int pid) { + if (!isCurrentUserRoot) { + // early exit for non-root + return List.of(PlatformSupport.getTemporaryDirectory()); + } + List result = new ArrayList<>(); + try (DirectoryStream bs = Files.newDirectoryStream(Path.of(VAR_FOLDERS_PATH))) { + for (Path bucket : bs) { + try (DirectoryStream encUuids = Files.newDirectoryStream(bucket)) { + for (Path encUuid : encUuids) { + try { + Path tempDir = encUuid.resolve(DIRHELPER_TEMP_STR); + if (Files.isDirectory(tempDir) && Files.isReadable(tempDir)) { + result.add(tempDir.toString()); + } + } catch (Exception ignore) { // ignored unreadable bucket/encUuid, continue + } + } + } catch (IOException ignore) { // IOException ignored, continue to the next bucket + } + } + } catch (Exception ignore) { // var/folders directory is inaccessible / other errors + } + return result.isEmpty() ? List.of(PlatformSupport.getTemporaryDirectory()) : result; + } +} diff --git a/src/jdk.internal.jvmstat/share/classes/module-info.java b/src/jdk.internal.jvmstat/share/classes/module-info.java index 9e12c98b016..d9e1bc68008 100644 --- a/src/jdk.internal.jvmstat/share/classes/module-info.java +++ b/src/jdk.internal.jvmstat/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -40,6 +40,8 @@ module jdk.internal.jvmstat { jdk.jstatd; exports sun.jvmstat.perfdata.monitor to jdk.jstatd; + exports sun.jvmstat to + jdk.attach; uses sun.jvmstat.monitor.MonitoredHostService; From 6aeabd4bfaca168e9c88716b185979cf1e1b85ed Mon Sep 17 00:00:00 2001 From: Kieran Farrell Date: Mon, 15 Dec 2025 20:51:08 +0000 Subject: [PATCH 008/390] 8370910: Cleanup terminology of UUID vs Global Identifiers in UUID Reviewed-by: alanb, rriggs, jpai --- src/java.base/share/classes/java/util/UUID.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/util/UUID.java b/src/java.base/share/classes/java/util/UUID.java index fa66d199239..f69ca8171cf 100644 --- a/src/java.base/share/classes/java/util/UUID.java +++ b/src/java.base/share/classes/java/util/UUID.java @@ -32,12 +32,11 @@ import jdk.internal.access.SharedSecrets; import jdk.internal.util.ByteArrayLittleEndian; /** - * A class that represents an immutable universally unique identifier (UUID). + * A class that represents an immutable Universally Unique IDentifier (UUID). * A UUID represents a 128-bit value. * - *

There exist different variants of these global identifiers. The methods - * of this class are for manipulating the Leach-Salz variant, although the - * constructors allow the creation of any variant of UUID (described below). + *

This class is primarily designed for manipulating Leach-Salz variant UUIDs, + * but it also supports the creation of UUIDs of other variants. * *

The layout of a variant 2 (Leach-Salz) UUID is as follows: * From 317788ff12ee231bd3c9e8f1a0c9b38c8dad3feb Mon Sep 17 00:00:00 2001 From: Damon Nguyen Date: Mon, 15 Dec 2025 22:39:09 +0000 Subject: [PATCH 009/390] 8360160: ubuntu-22-04 machine is failing client tests Reviewed-by: prr, azvegint --- test/jdk/java/awt/Frame/FrameVisualTest.java | 73 +++++++++++--------- 1 file changed, 41 insertions(+), 32 deletions(-) diff --git a/test/jdk/java/awt/Frame/FrameVisualTest.java b/test/jdk/java/awt/Frame/FrameVisualTest.java index 767eb0a1896..39853822c44 100644 --- a/test/jdk/java/awt/Frame/FrameVisualTest.java +++ b/test/jdk/java/awt/Frame/FrameVisualTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -46,62 +46,71 @@ import javax.imageio.ImageIO; public class FrameVisualTest { private static GraphicsConfiguration[] gcs; private static volatile Frame[] frames; - private static volatile int index; - private static Frame f; private static Robot robot; + private static volatile int frameNum; private static volatile Point p; private static volatile Dimension d; private static final int TOLERANCE = 5; + private static final int MAX_FRAME_COUNT = 30; public static void main(String[] args) throws Exception { - gcs = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getConfigurations(); + gcs = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice().getConfigurations(); robot = new Robot(); robot.setAutoDelay(100); - try { - EventQueue.invokeAndWait(() -> { - createAndShowUI(); - }); - robot.delay(1000); - System.out.println("frames.length: "+frames.length); - for (index = 0; index < frames.length; index++) { + + // Limit the number of frames tested if needed + if (gcs.length > MAX_FRAME_COUNT) { + frames = new Frame[MAX_FRAME_COUNT]; + } else { + frames = new Frame[gcs.length]; + } + System.out.println(gcs.length + " gcs found. Testing " + + frames.length + " frame(s)."); + + for (frameNum = 0; frameNum < frames.length; frameNum++) { + try { EventQueue.invokeAndWait(() -> { - p = frames[index].getLocation(); - d = frames[index].getSize(); + frames[frameNum] = new Frame("Frame w/ gc " + + frameNum, gcs[frameNum]); + frames[frameNum].setSize(100, 100); + frames[frameNum].setUndecorated(true); + frames[frameNum].setBackground(Color.WHITE); + frames[frameNum].setVisible(true); + System.out.println("Frame " + frameNum + " created"); }); + + robot.delay(1000); + + EventQueue.invokeAndWait(() -> { + p = frames[frameNum].getLocation(); + d = frames[frameNum].getSize(); + }); + Rectangle rect = new Rectangle(p, d); BufferedImage img = robot.createScreenCapture(rect); if (chkImgBackgroundColor(img)) { try { - ImageIO.write(img, "png", new File("Frame_" + index + ".png")); + ImageIO.write(img, "png", + new File("Frame_" + + frameNum + ".png")); } catch (IOException ignored) {} - throw new RuntimeException("Frame visual test failed with non-white background color"); + throw new RuntimeException("Frame visual test " + + "failed with non-white background color"); } - } - } finally { - for (index = 0; index < frames.length; index++) { + } finally { EventQueue.invokeAndWait(() -> { - if (frames[index] != null) { - frames[index].dispose(); + if (frames[frameNum] != null) { + frames[frameNum].dispose(); + System.out.println("Frame " + frameNum + " disposed"); } }); } } } - private static void createAndShowUI() { - frames = new Frame[gcs.length]; - for (int i = 0; i < frames.length; i++) { - frames[i] = new Frame("Frame w/ gc " + i, gcs[i]); - frames[i].setSize(100, 100); - frames[i].setUndecorated(true); - frames[i].setBackground(Color.WHITE); - frames[i].setVisible(true); - } - } - private static boolean chkImgBackgroundColor(BufferedImage img) { - // scan for mid-line and if it is non-white color then return true. for (int x = 1; x < img.getWidth() - 1; ++x) { Color c = new Color(img.getRGB(x, img.getHeight() / 2)); From 1748737b99f283f69b4be0910b6623a27d804e68 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Tue, 16 Dec 2025 00:19:01 +0000 Subject: [PATCH 010/390] 8372988: Test runtime/Nestmates/membership/TestNestHostErrorWithMultiThread.java failed: Unexpected interrupt Reviewed-by: coleenp, iklam, jsjolen --- src/hotspot/share/classfile/resolutionErrors.cpp | 6 ++---- src/hotspot/share/classfile/systemDictionary.cpp | 15 ++++++++++----- src/hotspot/share/classfile/systemDictionary.hpp | 2 +- src/hotspot/share/oops/instanceKlass.cpp | 10 ++++------ 4 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/hotspot/share/classfile/resolutionErrors.cpp b/src/hotspot/share/classfile/resolutionErrors.cpp index f5a335f17f3..c41d5d2f052 100644 --- a/src/hotspot/share/classfile/resolutionErrors.cpp +++ b/src/hotspot/share/classfile/resolutionErrors.cpp @@ -127,10 +127,8 @@ ResolutionErrorEntry::~ResolutionErrorEntry() { } void ResolutionErrorEntry::set_nest_host_error(const char* message) { - // If a message is already set, free it. - if (nest_host_error() != nullptr) { - FREE_C_HEAP_ARRAY(char, _nest_host_error); - } + assert(_nest_host_error == nullptr, "caller should have checked"); + assert_lock_strong(SystemDictionary_lock); _nest_host_error = message; } diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index e03d198eb9f..73738412017 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -1859,7 +1859,7 @@ Symbol* SystemDictionary::find_resolution_error(const constantPoolHandle& pool, void SystemDictionary::add_nest_host_error(const constantPoolHandle& pool, int which, - const char* message) { + const stringStream& message) { { MutexLocker ml(Thread::current(), SystemDictionary_lock); ResolutionErrorEntry* entry = ResolutionErrorTable::find_entry(pool, which); @@ -1868,14 +1868,19 @@ void SystemDictionary::add_nest_host_error(const constantPoolHandle& pool, // constant pool index. In this case resolution succeeded but there's an error in this nest host // that we use the table to record. assert(pool->resolved_klass_at(which) != nullptr, "klass should be resolved if there is no entry"); - ResolutionErrorTable::add_entry(pool, which, message); + ResolutionErrorTable::add_entry(pool, which, message.as_string(true /* on C-heap */)); } else { // An existing entry means we had a true resolution failure (LinkageError) with our nest host, but we // still want to add the error message for the higher-level access checks to report. We should // only reach here under the same error condition, so we can ignore the potential race with setting - // the message, and set it again. - assert(entry->nest_host_error() == nullptr || strcmp(entry->nest_host_error(), message) == 0, "should be the same message"); - entry->set_nest_host_error(message); + // the message. + const char* nhe = entry->nest_host_error(); + if (nhe == nullptr) { + entry->set_nest_host_error(message.as_string(true /* on C-heap */)); + } else { + DEBUG_ONLY(const char* msg = message.base();) + assert(strcmp(nhe, msg) == 0, "New message %s, differs from original %s", msg, nhe); + } } } } diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index 99e13fea61e..e32e0082f8f 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -280,7 +280,7 @@ public: // Record a nest host resolution/validation error static void add_nest_host_error(const constantPoolHandle& pool, int which, - const char* message); + const stringStream& message); static const char* find_nest_host_error(const constantPoolHandle& pool, int which); static void add_to_initiating_loader(JavaThread* current, InstanceKlass* k, diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index e74bc80d893..56a80daed60 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -312,12 +312,11 @@ InstanceKlass* InstanceKlass::nest_host(TRAPS) { ss.print("Nest host resolution of %s with host %s failed: ", this->external_name(), target_host_class); java_lang_Throwable::print(PENDING_EXCEPTION, &ss); - const char* msg = ss.as_string(true /* on C-heap */); constantPoolHandle cph(THREAD, constants()); - SystemDictionary::add_nest_host_error(cph, _nest_host_index, msg); + SystemDictionary::add_nest_host_error(cph, _nest_host_index, ss); CLEAR_PENDING_EXCEPTION; - log_trace(class, nestmates)("%s", msg); + log_trace(class, nestmates)("%s", ss.base()); } else { // A valid nest-host is an instance class in the current package that lists this // class as a nest member. If any of these conditions are not met the class is @@ -356,10 +355,9 @@ InstanceKlass* InstanceKlass::nest_host(TRAPS) { k->external_name(), k->class_loader_data()->loader_name_and_id(), error); - const char* msg = ss.as_string(true /* on C-heap */); constantPoolHandle cph(THREAD, constants()); - SystemDictionary::add_nest_host_error(cph, _nest_host_index, msg); - log_trace(class, nestmates)("%s", msg); + SystemDictionary::add_nest_host_error(cph, _nest_host_index, ss); + log_trace(class, nestmates)("%s", ss.base()); } } } else { From 3f33eaa42aff45422c94300573c898868189fdfc Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Tue, 16 Dec 2025 04:03:12 +0000 Subject: [PATCH 011/390] 8373649: Convert simple AtomicAccess usage in ConcurrentHashTable to use Atomic Reviewed-by: tschatzl, iwalulya --- .../share/utilities/concurrentHashTable.hpp | 11 +-- .../utilities/concurrentHashTable.inline.hpp | 73 ++++++++++--------- .../concurrentHashTableTasks.inline.hpp | 29 ++++---- 3 files changed, 58 insertions(+), 55 deletions(-) diff --git a/src/hotspot/share/utilities/concurrentHashTable.hpp b/src/hotspot/share/utilities/concurrentHashTable.hpp index a837a56a19a..1a50ecabc3e 100644 --- a/src/hotspot/share/utilities/concurrentHashTable.hpp +++ b/src/hotspot/share/utilities/concurrentHashTable.hpp @@ -26,6 +26,7 @@ #define SHARE_UTILITIES_CONCURRENTHASHTABLE_HPP #include "memory/allocation.hpp" +#include "runtime/atomic.hpp" #include "runtime/mutex.hpp" #include "utilities/globalCounter.hpp" #include "utilities/globalDefinitions.hpp" @@ -246,7 +247,7 @@ class ConcurrentHashTable : public CHeapObj { const size_t _log2_start_size; // Start size. const size_t _grow_hint; // Number of linked items - volatile bool _size_limit_reached; + Atomic _size_limit_reached; // We serialize resizers and other bulk operations which do not support // concurrent resize with this lock. @@ -255,7 +256,7 @@ class ConcurrentHashTable : public CHeapObj { // taking the mutex after a safepoint this bool is the actual state. After // acquiring the mutex you must check if this is already locked. If so you // must drop the mutex until the real lock holder grabs the mutex. - volatile Thread* _resize_lock_owner; + Atomic _resize_lock_owner; // Return true if lock mutex/state succeeded. bool try_resize_lock(Thread* locker); @@ -273,7 +274,7 @@ class ConcurrentHashTable : public CHeapObj { // this field keep tracks if a version of the hash-table was ever been seen. // We the working thread pointer as tag for debugging. The _invisible_epoch // can only be used by the owner of _resize_lock. - volatile Thread* _invisible_epoch; + Atomic _invisible_epoch; // Scoped critical section, which also handles the invisible epochs. // An invisible epoch/version do not need a write_synchronize(). @@ -435,11 +436,11 @@ class ConcurrentHashTable : public CHeapObj { size_t get_size_log2(Thread* thread); static size_t get_node_size() { return sizeof(Node); } static size_t get_dynamic_node_size(size_t value_size); - bool is_max_size_reached() { return _size_limit_reached; } + bool is_max_size_reached() { return _size_limit_reached.load_relaxed(); } // This means no paused bucket resize operation is going to resume // on this table. - bool is_safepoint_safe() { return _resize_lock_owner == nullptr; } + bool is_safepoint_safe() { return _resize_lock_owner.load_relaxed() == nullptr; } // Re-size operations. bool shrink(Thread* thread, size_t size_limit_log2 = 0); diff --git a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp index eeaff0167b2..b96a487324c 100644 --- a/src/hotspot/share/utilities/concurrentHashTable.inline.hpp +++ b/src/hotspot/share/utilities/concurrentHashTable.inline.hpp @@ -29,6 +29,7 @@ #include "cppstdlib/type_traits.hpp" #include "memory/allocation.inline.hpp" +#include "runtime/atomic.hpp" #include "runtime/atomicAccess.hpp" #include "runtime/orderAccess.hpp" #include "runtime/prefetch.inline.hpp" @@ -221,8 +222,8 @@ inline ConcurrentHashTable:: _cs_context(GlobalCounter::critical_section_begin(_thread)) { // This version is published now. - if (AtomicAccess::load_acquire(&_cht->_invisible_epoch) != nullptr) { - AtomicAccess::release_store_fence(&_cht->_invisible_epoch, (Thread*)nullptr); + if (_cht->_invisible_epoch.load_acquire() != nullptr) { + _cht->_invisible_epoch.release_store_fence(nullptr); } } @@ -282,16 +283,16 @@ template inline void ConcurrentHashTable:: write_synchonize_on_visible_epoch(Thread* thread) { - assert(_resize_lock_owner == thread, "Re-size lock not held"); + assert(_resize_lock_owner.load_relaxed() == thread, "Re-size lock not held"); OrderAccess::fence(); // Prevent below load from floating up. // If no reader saw this version we can skip write_synchronize. - if (AtomicAccess::load_acquire(&_invisible_epoch) == thread) { + if (_invisible_epoch.load_acquire() == thread) { return; } - assert(_invisible_epoch == nullptr, "Two thread doing bulk operations"); + assert(_invisible_epoch.load_relaxed() == nullptr, "Two thread doing bulk operations"); // We set this/next version that we are synchronizing for to not published. // A reader will zero this flag if it reads this/next version. - AtomicAccess::release_store(&_invisible_epoch, thread); + _invisible_epoch.release_store(thread); GlobalCounter::write_synchronize(); } @@ -300,8 +301,8 @@ inline bool ConcurrentHashTable:: try_resize_lock(Thread* locker) { if (_resize_lock->try_lock()) { - if (_resize_lock_owner != nullptr) { - assert(locker != _resize_lock_owner, "Already own lock"); + if (_resize_lock_owner.load_relaxed() != nullptr) { + assert(locker != _resize_lock_owner.load_relaxed(), "Already own lock"); // We got mutex but internal state is locked. _resize_lock->unlock(); return false; @@ -309,8 +310,8 @@ inline bool ConcurrentHashTable:: } else { return false; } - _invisible_epoch = nullptr; - _resize_lock_owner = locker; + _invisible_epoch.store_relaxed(nullptr); + _resize_lock_owner.store_relaxed(locker); return true; } @@ -326,8 +327,8 @@ inline void ConcurrentHashTable:: _resize_lock->lock_without_safepoint_check(); // If holder of lock dropped mutex for safepoint mutex might be unlocked, // and _resize_lock_owner will contain the owner. - if (_resize_lock_owner != nullptr) { - assert(locker != _resize_lock_owner, "Already own lock"); + if (_resize_lock_owner.load_relaxed() != nullptr) { + assert(locker != _resize_lock_owner.load_relaxed(), "Already own lock"); // We got mutex but internal state is locked. _resize_lock->unlock(); yield.wait(); @@ -335,17 +336,17 @@ inline void ConcurrentHashTable:: break; } } while(true); - _resize_lock_owner = locker; - _invisible_epoch = nullptr; + _resize_lock_owner.store_relaxed(locker); + _invisible_epoch.store_relaxed(nullptr); } template inline void ConcurrentHashTable:: unlock_resize_lock(Thread* locker) { - _invisible_epoch = nullptr; - assert(locker == _resize_lock_owner, "Not unlocked by locker."); - _resize_lock_owner = nullptr; + _invisible_epoch.store_relaxed(nullptr); + assert(locker == _resize_lock_owner.load_relaxed(), "Not unlocked by locker."); + _resize_lock_owner.store_relaxed(nullptr); _resize_lock->unlock(); } @@ -477,8 +478,8 @@ inline void ConcurrentHashTable:: { // Here we have resize lock so table is SMR safe, and there is no new // table. Can do this in parallel if we want. - assert((is_mt && _resize_lock_owner != nullptr) || - (!is_mt && _resize_lock_owner == thread), "Re-size lock not held"); + assert((is_mt && _resize_lock_owner.load_relaxed() != nullptr) || + (!is_mt && _resize_lock_owner.load_relaxed() == thread), "Re-size lock not held"); Node* ndel_stack[StackBufferSize]; InternalTable* table = get_table(); assert(start_idx < stop_idx, "Must be"); @@ -696,7 +697,7 @@ inline bool ConcurrentHashTable:: if (!try_resize_lock(thread)) { return false; } - assert(_resize_lock_owner == thread, "Re-size lock not held"); + assert(_resize_lock_owner.load_relaxed() == thread, "Re-size lock not held"); if (_table->_log2_size == _log2_start_size || _table->_log2_size <= log2_size) { unlock_resize_lock(thread); @@ -710,10 +711,10 @@ template inline void ConcurrentHashTable:: internal_shrink_epilog(Thread* thread) { - assert(_resize_lock_owner == thread, "Re-size lock not held"); + assert(_resize_lock_owner.load_relaxed() == thread, "Re-size lock not held"); InternalTable* old_table = set_table_from_new(); - _size_limit_reached = false; + _size_limit_reached.store_relaxed(false); unlock_resize_lock(thread); #ifdef ASSERT for (size_t i = 0; i < old_table->_size; i++) { @@ -767,13 +768,13 @@ inline bool ConcurrentHashTable:: internal_shrink(Thread* thread, size_t log2_size) { if (!internal_shrink_prolog(thread, log2_size)) { - assert(_resize_lock_owner != thread, "Re-size lock held"); + assert(_resize_lock_owner.load_relaxed() != thread, "Re-size lock held"); return false; } - assert(_resize_lock_owner == thread, "Should be locked by me"); + assert(_resize_lock_owner.load_relaxed() == thread, "Should be locked by me"); internal_shrink_range(thread, 0, _new_table->_size); internal_shrink_epilog(thread); - assert(_resize_lock_owner != thread, "Re-size lock held"); + assert(_resize_lock_owner.load_relaxed() != thread, "Re-size lock held"); return true; } @@ -787,7 +788,7 @@ inline void ConcurrentHashTable:: delete _table; // Create and publish a new table InternalTable* table = new InternalTable(log2_size); - _size_limit_reached = (log2_size == _log2_size_limit); + _size_limit_reached.store_relaxed(log2_size == _log2_size_limit); AtomicAccess::release_store(&_table, table); } @@ -812,7 +813,7 @@ inline bool ConcurrentHashTable:: } _new_table = new InternalTable(_table->_log2_size + 1); - _size_limit_reached = _new_table->_log2_size == _log2_size_limit; + _size_limit_reached.store_relaxed(_new_table->_log2_size == _log2_size_limit); return true; } @@ -821,7 +822,7 @@ template inline void ConcurrentHashTable:: internal_grow_epilog(Thread* thread) { - assert(_resize_lock_owner == thread, "Should be locked"); + assert(_resize_lock_owner.load_relaxed() == thread, "Should be locked"); InternalTable* old_table = set_table_from_new(); unlock_resize_lock(thread); @@ -840,13 +841,13 @@ inline bool ConcurrentHashTable:: internal_grow(Thread* thread, size_t log2_size) { if (!internal_grow_prolog(thread, log2_size)) { - assert(_resize_lock_owner != thread, "Re-size lock held"); + assert(_resize_lock_owner.load_relaxed() != thread, "Re-size lock held"); return false; } - assert(_resize_lock_owner == thread, "Should be locked by me"); + assert(_resize_lock_owner.load_relaxed() == thread, "Should be locked by me"); internal_grow_range(thread, 0, _table->_size); internal_grow_epilog(thread); - assert(_resize_lock_owner != thread, "Re-size lock held"); + assert(_resize_lock_owner.load_relaxed() != thread, "Re-size lock held"); return true; } @@ -961,7 +962,7 @@ template inline void ConcurrentHashTable:: do_scan_locked(Thread* thread, FUNC& scan_f) { - assert(_resize_lock_owner == thread, "Re-size lock not held"); + assert(_resize_lock_owner.load_relaxed() == thread, "Re-size lock not held"); // We can do a critical section over the entire loop but that would block // updates for a long time. Instead we choose to block resizes. InternalTable* table = get_table(); @@ -1020,7 +1021,7 @@ ConcurrentHashTable(size_t log2size, size_t log2size_limit, size_t grow_hint, bo _resize_lock = new Mutex(rank, "ConcurrentHashTableResize_lock"); _table = new InternalTable(log2size); assert(log2size_limit >= log2size, "bad ergo"); - _size_limit_reached = _table->_log2_size == _log2_size_limit; + _size_limit_reached.store_relaxed(_table->_log2_size == _log2_size_limit); } template @@ -1139,11 +1140,11 @@ inline void ConcurrentHashTable:: { assert(!SafepointSynchronize::is_at_safepoint(), "must be outside a safepoint"); - assert(_resize_lock_owner != thread, "Re-size lock held"); + assert(_resize_lock_owner.load_relaxed() != thread, "Re-size lock held"); lock_resize_lock(thread); do_scan_locked(thread, scan_f); unlock_resize_lock(thread); - assert(_resize_lock_owner != thread, "Re-size lock held"); + assert(_resize_lock_owner.load_relaxed() != thread, "Re-size lock held"); } template @@ -1205,7 +1206,7 @@ inline bool ConcurrentHashTable:: } do_bulk_delete_locked(thread, eval_f, del_f); unlock_resize_lock(thread); - assert(_resize_lock_owner != thread, "Re-size lock held"); + assert(_resize_lock_owner.load_relaxed() != thread, "Re-size lock held"); return true; } diff --git a/src/hotspot/share/utilities/concurrentHashTableTasks.inline.hpp b/src/hotspot/share/utilities/concurrentHashTableTasks.inline.hpp index 086a548ede5..054008953a8 100644 --- a/src/hotspot/share/utilities/concurrentHashTableTasks.inline.hpp +++ b/src/hotspot/share/utilities/concurrentHashTableTasks.inline.hpp @@ -27,6 +27,7 @@ // No concurrentHashTableTasks.hpp +#include "runtime/atomic.hpp" #include "runtime/atomicAccess.hpp" #include "utilities/concurrentHashTable.inline.hpp" #include "utilities/globalDefinitions.hpp" @@ -41,7 +42,7 @@ class ConcurrentHashTable::BucketsOperation { ConcurrentHashTable* _cht; class InternalTableClaimer { - volatile size_t _next; + Atomic _next; size_t _limit; size_t _size; @@ -56,14 +57,14 @@ public: void set(size_t claim_size, InternalTable* table) { assert(table != nullptr, "precondition"); - _next = 0; + _next.store_relaxed(0); _limit = table->_size; _size = MIN2(claim_size, _limit); } bool claim(size_t* start, size_t* stop) { - if (AtomicAccess::load(&_next) < _limit) { - size_t claimed = AtomicAccess::fetch_then_add(&_next, _size); + if (_next.load_relaxed() < _limit) { + size_t claimed = _next.fetch_then_add(_size); if (claimed < _limit) { *start = claimed; *stop = MIN2(claimed + _size, _limit); @@ -78,7 +79,7 @@ public: } bool have_more_work() { - return AtomicAccess::load_acquire(&_next) >= _limit; + return _next.load_acquire() >= _limit; } }; @@ -108,13 +109,13 @@ public: } void thread_owns_resize_lock(Thread* thread) { - assert(BucketsOperation::_cht->_resize_lock_owner == thread, + assert(BucketsOperation::_cht->_resize_lock_owner.load_relaxed() == thread, "Should be locked by me"); assert(BucketsOperation::_cht->_resize_lock->owned_by_self(), "Operations lock not held"); } void thread_owns_only_state_lock(Thread* thread) { - assert(BucketsOperation::_cht->_resize_lock_owner == thread, + assert(BucketsOperation::_cht->_resize_lock_owner.load_relaxed() == thread, "Should be locked by me"); assert(!BucketsOperation::_cht->_resize_lock->owned_by_self(), "Operations lock held"); @@ -122,7 +123,7 @@ public: void thread_do_not_own_resize_lock(Thread* thread) { assert(!BucketsOperation::_cht->_resize_lock->owned_by_self(), "Operations lock held"); - assert(BucketsOperation::_cht->_resize_lock_owner != thread, + assert(BucketsOperation::_cht->_resize_lock_owner.load_relaxed() != thread, "Should not be locked by me"); } @@ -169,7 +170,7 @@ class ConcurrentHashTable::BulkDeleteTask : template bool do_task(Thread* thread, EVALUATE_FUNC& eval_f, DELETE_FUNC& del_f) { size_t start, stop; - assert(BucketsOperation::_cht->_resize_lock_owner != nullptr, + assert(BucketsOperation::_cht->_resize_lock_owner.load_relaxed() != nullptr, "Should be locked"); if (!this->claim(&start, &stop)) { return false; @@ -177,7 +178,7 @@ class ConcurrentHashTable::BulkDeleteTask : BucketsOperation::_cht->do_bulk_delete_locked_for(thread, start, stop, eval_f, del_f, BucketsOperation::_is_mt); - assert(BucketsOperation::_cht->_resize_lock_owner != nullptr, + assert(BucketsOperation::_cht->_resize_lock_owner.load_relaxed() != nullptr, "Should be locked"); return true; } @@ -210,13 +211,13 @@ class ConcurrentHashTable::GrowTask : // Re-sizes a portion of the table. Returns true if there is more work. bool do_task(Thread* thread) { size_t start, stop; - assert(BucketsOperation::_cht->_resize_lock_owner != nullptr, + assert(BucketsOperation::_cht->_resize_lock_owner.load_relaxed() != nullptr, "Should be locked"); if (!this->claim(&start, &stop)) { return false; } BucketsOperation::_cht->internal_grow_range(thread, start, stop); - assert(BucketsOperation::_cht->_resize_lock_owner != nullptr, + assert(BucketsOperation::_cht->_resize_lock_owner.load_relaxed() != nullptr, "Should be locked"); return true; } @@ -253,13 +254,13 @@ class ConcurrentHashTable::StatisticsTask : template bool do_task(Thread* thread, VALUE_SIZE_FUNC& sz) { size_t start, stop; - assert(BucketsOperation::_cht->_resize_lock_owner != nullptr, + assert(BucketsOperation::_cht->_resize_lock_owner.load_relaxed() != nullptr, "Should be locked"); if (!this->claim(&start, &stop)) { return false; } BucketsOperation::_cht->internal_statistics_range(thread, start, stop, sz, _summary, _literal_bytes); - assert(BucketsOperation::_cht->_resize_lock_owner != nullptr, + assert(BucketsOperation::_cht->_resize_lock_owner.load_relaxed() != nullptr, "Should be locked"); return true; } From b1e8c4e030f42ea3146b2502c9ab030bc79a8147 Mon Sep 17 00:00:00 2001 From: Rui Li Date: Tue, 16 Dec 2025 07:02:15 +0000 Subject: [PATCH 012/390] 8372543: Shenandoah: undercalculated the available size when soft max takes effect Reviewed-by: wkemper, kdnilsen --- .../shenandoahAdaptiveHeuristics.cpp | 13 +- .../shenandoahCompactHeuristics.cpp | 14 +- .../heuristics/shenandoahSpaceInfo.hpp | 2 +- .../heuristics/shenandoahStaticHeuristics.cpp | 16 +-- .../share/gc/shenandoah/shenandoahFreeSet.cpp | 82 +++++------- .../share/gc/shenandoah/shenandoahFreeSet.hpp | 1 + .../gc/shenandoah/shenandoahGeneration.cpp | 4 +- .../gc/shenandoah/shenandoahGeneration.hpp | 2 +- .../shenandoah/shenandoahGlobalGeneration.cpp | 9 -- .../shenandoah/shenandoahGlobalGeneration.hpp | 1 - .../shenandoah/shenandoahYoungGeneration.cpp | 4 +- .../shenandoah/shenandoahYoungGeneration.hpp | 2 +- .../TestSoftMaxHeapSizeAvailableCalc.java | 123 ++++++++++++++++++ 13 files changed, 182 insertions(+), 91 deletions(-) create mode 100644 test/hotspot/jtreg/gc/shenandoah/TestSoftMaxHeapSizeAvailableCalc.java diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp index 6498f0acdb6..41535f302d7 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahAdaptiveHeuristics.cpp @@ -31,7 +31,6 @@ #include "gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" #include "gc/shenandoah/shenandoahCollectorPolicy.hpp" -#include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "logging/log.hpp" @@ -234,11 +233,12 @@ static double saturate(double value, double min, double max) { // allocation rate computation independent. bool ShenandoahAdaptiveHeuristics::should_start_gc() { size_t capacity = ShenandoahHeap::heap()->soft_max_capacity(); - size_t available = _space_info->soft_available(); + size_t available = _space_info->soft_mutator_available(); size_t allocated = _space_info->bytes_allocated_since_gc_start(); - log_debug(gc)("should_start_gc? available: %zu, soft_max_capacity: %zu" - ", allocated: %zu", available, capacity, allocated); + log_debug(gc, ergo)("should_start_gc calculation: available: " PROPERFMT ", soft_max_capacity: " PROPERFMT ", " + "allocated_since_gc_start: " PROPERFMT, + PROPERFMTARGS(available), PROPERFMTARGS(capacity), PROPERFMTARGS(allocated)); // Track allocation rate even if we decide to start a cycle for other reasons. double rate = _allocation_rate.sample(allocated); @@ -252,9 +252,8 @@ bool ShenandoahAdaptiveHeuristics::should_start_gc() { size_t min_threshold = min_free_threshold(); if (available < min_threshold) { - log_trigger("Free (%zu%s) is below minimum threshold (%zu%s)", - byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), - byte_size_in_proper_unit(min_threshold), proper_unit_for_byte_size(min_threshold)); + log_trigger("Free (Soft) (" PROPERFMT ") is below minimum threshold (" PROPERFMT ")", + PROPERFMTARGS(available), PROPERFMTARGS(min_threshold)); accept_trigger_with_type(OTHER); return true; } diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp index f8a77d95d51..28673b28612 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahCompactHeuristics.cpp @@ -26,7 +26,6 @@ #include "gc/shenandoah/heuristics/shenandoahCompactHeuristics.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" -#include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "logging/log.hpp" @@ -47,26 +46,25 @@ ShenandoahCompactHeuristics::ShenandoahCompactHeuristics(ShenandoahSpaceInfo* sp } bool ShenandoahCompactHeuristics::should_start_gc() { - size_t max_capacity = _space_info->max_capacity(); size_t capacity = ShenandoahHeap::heap()->soft_max_capacity(); - size_t available = _space_info->available(); + size_t available = _space_info->soft_mutator_available(); + size_t bytes_allocated = _space_info->bytes_allocated_since_gc_start(); - // Make sure the code below treats available without the soft tail. - size_t soft_tail = max_capacity - capacity; - available = (available > soft_tail) ? (available - soft_tail) : 0; + log_debug(gc, ergo)("should_start_gc calculation: available: " PROPERFMT ", soft_max_capacity: " PROPERFMT ", " + "allocated_since_gc_start: " PROPERFMT, + PROPERFMTARGS(available), PROPERFMTARGS(capacity), PROPERFMTARGS(bytes_allocated)); size_t threshold_bytes_allocated = capacity / 100 * ShenandoahAllocationThreshold; size_t min_threshold = capacity / 100 * ShenandoahMinFreeThreshold; if (available < min_threshold) { - log_trigger("Free (%zu%s) is below minimum threshold (%zu%s)", + log_trigger("Free (Soft) (%zu%s) is below minimum threshold (%zu%s)", byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), byte_size_in_proper_unit(min_threshold), proper_unit_for_byte_size(min_threshold)); accept_trigger(); return true; } - size_t bytes_allocated = _space_info->bytes_allocated_since_gc_start(); if (bytes_allocated > threshold_bytes_allocated) { log_trigger("Allocated since last cycle (%zu%s) is larger than allocation threshold (%zu%s)", byte_size_in_proper_unit(bytes_allocated), proper_unit_for_byte_size(bytes_allocated), diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp index 7fb44c7b71b..6ed05abf0b1 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahSpaceInfo.hpp @@ -38,7 +38,7 @@ class ShenandoahSpaceInfo { public: virtual const char* name() const = 0; virtual size_t max_capacity() const = 0; - virtual size_t soft_available() const = 0; + virtual size_t soft_mutator_available() const = 0; virtual size_t available() const = 0; virtual size_t used() const = 0; diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp index 205135751aa..d4d66fef6a1 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahStaticHeuristics.cpp @@ -26,7 +26,6 @@ #include "gc/shenandoah/heuristics/shenandoahStaticHeuristics.hpp" #include "gc/shenandoah/shenandoahCollectionSet.hpp" -#include "gc/shenandoah/shenandoahFreeSet.hpp" #include "gc/shenandoah/shenandoahHeap.inline.hpp" #include "gc/shenandoah/shenandoahHeapRegion.inline.hpp" #include "logging/log.hpp" @@ -41,20 +40,19 @@ ShenandoahStaticHeuristics::ShenandoahStaticHeuristics(ShenandoahSpaceInfo* spac ShenandoahStaticHeuristics::~ShenandoahStaticHeuristics() {} bool ShenandoahStaticHeuristics::should_start_gc() { - size_t max_capacity = _space_info->max_capacity(); size_t capacity = ShenandoahHeap::heap()->soft_max_capacity(); - size_t available = _space_info->available(); + size_t available = _space_info->soft_mutator_available(); + size_t allocated = _space_info->bytes_allocated_since_gc_start(); - // Make sure the code below treats available without the soft tail. - size_t soft_tail = max_capacity - capacity; - available = (available > soft_tail) ? (available - soft_tail) : 0; + log_debug(gc, ergo)("should_start_gc calculation: available: " PROPERFMT ", soft_max_capacity: " PROPERFMT ", " + "allocated_since_gc_start: " PROPERFMT, + PROPERFMTARGS(available), PROPERFMTARGS(capacity), PROPERFMTARGS(allocated)); size_t threshold_available = capacity / 100 * ShenandoahMinFreeThreshold; if (available < threshold_available) { - log_trigger("Free (%zu%s) is below minimum threshold (%zu%s)", - byte_size_in_proper_unit(available), proper_unit_for_byte_size(available), - byte_size_in_proper_unit(threshold_available), proper_unit_for_byte_size(threshold_available)); + log_trigger("Free (Soft) (" PROPERFMT ") is below minimum threshold (" PROPERFMT ")", + PROPERFMTARGS(available), PROPERFMTARGS(threshold_available)); accept_trigger(); return true; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp index eb05bf24028..c03e66e28da 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.cpp @@ -2921,6 +2921,29 @@ void ShenandoahFreeSet::log_status_under_lock() { } } +void ShenandoahFreeSet::log_freeset_stats(ShenandoahFreeSetPartitionId partition_id, LogStream& ls) { + size_t max = 0; + size_t total_free = 0; + size_t total_used = 0; + + for (idx_t idx = _partitions.leftmost(partition_id); + idx <= _partitions.rightmost(partition_id); idx++) { + if (_partitions.in_free_set(partition_id, idx)) { + ShenandoahHeapRegion *r = _heap->get_region(idx); + size_t free = alloc_capacity(r); + max = MAX2(max, free); + total_free += free; + total_used += r->used(); + } + } + + ls.print(" %s freeset stats: Partition count: %zu, Reserved: " PROPERFMT ", Max free available in a single region: " PROPERFMT ";", + partition_name(partition_id), + _partitions.count(partition_id), + PROPERFMTARGS(total_free), PROPERFMTARGS(max) + ); +} + void ShenandoahFreeSet::log_status() { shenandoah_assert_heaplocked(); @@ -3040,20 +3063,18 @@ void ShenandoahFreeSet::log_status() { // retired, the sum of used and capacities within regions that are still in the Mutator free partition may not match // my internally tracked values of used() and free(). assert(free == total_free, "Free memory (%zu) should match calculated memory (%zu)", free, total_free); - ls.print("Free: %zu%s, Max: %zu%s regular, %zu%s humongous, ", - byte_size_in_proper_unit(total_free), proper_unit_for_byte_size(total_free), - byte_size_in_proper_unit(max), proper_unit_for_byte_size(max), - byte_size_in_proper_unit(max_humongous), proper_unit_for_byte_size(max_humongous) - ); + ls.print("Whole heap stats: Total free: " PROPERFMT ", Total used: " PROPERFMT ", Max free in a single region: " PROPERFMT + ", Max humongous: " PROPERFMT "; ", + PROPERFMTARGS(total_free), PROPERFMTARGS(total_used), PROPERFMTARGS(max), PROPERFMTARGS(max_humongous)); - ls.print("Frag: "); + ls.print("Frag stats: "); size_t frag_ext; if (total_free_ext > 0) { frag_ext = 100 - (100 * max_humongous / total_free_ext); } else { frag_ext = 0; } - ls.print("%zu%% external, ", frag_ext); + ls.print("External: %zu%%, ", frag_ext); size_t frag_int; if (_partitions.count(ShenandoahFreeSetPartitionId::Mutator) > 0) { @@ -3062,52 +3083,13 @@ void ShenandoahFreeSet::log_status() { } else { frag_int = 0; } - ls.print("%zu%% internal; ", frag_int); - ls.print("Used: %zu%s, Mutator Free: %zu", - byte_size_in_proper_unit(total_used), proper_unit_for_byte_size(total_used), - _partitions.count(ShenandoahFreeSetPartitionId::Mutator)); - } - - { - size_t max = 0; - size_t total_free = 0; - size_t total_used = 0; - - for (idx_t idx = _partitions.leftmost(ShenandoahFreeSetPartitionId::Collector); - idx <= _partitions.rightmost(ShenandoahFreeSetPartitionId::Collector); idx++) { - if (_partitions.in_free_set(ShenandoahFreeSetPartitionId::Collector, idx)) { - ShenandoahHeapRegion *r = _heap->get_region(idx); - size_t free = alloc_capacity(r); - max = MAX2(max, free); - total_free += free; - total_used += r->used(); - } - } - ls.print(" Collector Reserve: %zu%s, Max: %zu%s; Used: %zu%s", - byte_size_in_proper_unit(total_free), proper_unit_for_byte_size(total_free), - byte_size_in_proper_unit(max), proper_unit_for_byte_size(max), - byte_size_in_proper_unit(total_used), proper_unit_for_byte_size(total_used)); + ls.print("Internal: %zu%%; ", frag_int); } + log_freeset_stats(ShenandoahFreeSetPartitionId::Mutator, ls); + log_freeset_stats(ShenandoahFreeSetPartitionId::Collector, ls); if (_heap->mode()->is_generational()) { - size_t max = 0; - size_t total_free = 0; - size_t total_used = 0; - - for (idx_t idx = _partitions.leftmost(ShenandoahFreeSetPartitionId::OldCollector); - idx <= _partitions.rightmost(ShenandoahFreeSetPartitionId::OldCollector); idx++) { - if (_partitions.in_free_set(ShenandoahFreeSetPartitionId::OldCollector, idx)) { - ShenandoahHeapRegion *r = _heap->get_region(idx); - size_t free = alloc_capacity(r); - max = MAX2(max, free); - total_free += free; - total_used += r->used(); - } - } - ls.print_cr(" Old Collector Reserve: %zu%s, Max: %zu%s; Used: %zu%s", - byte_size_in_proper_unit(total_free), proper_unit_for_byte_size(total_free), - byte_size_in_proper_unit(max), proper_unit_for_byte_size(max), - byte_size_in_proper_unit(total_used), proper_unit_for_byte_size(total_used)); + log_freeset_stats(ShenandoahFreeSetPartitionId::OldCollector, ls); } } } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp index a9c5ebe49de..400eb8d25ee 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp @@ -629,6 +629,7 @@ private: void establish_old_collector_alloc_bias(); size_t get_usable_free_words(size_t free_bytes) const; + void log_freeset_stats(ShenandoahFreeSetPartitionId partition_id, LogStream& ls); // log status, assuming lock has already been acquired by the caller. void log_status(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp index b9295654b6f..d74ee872cd1 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.cpp @@ -938,8 +938,8 @@ size_t ShenandoahGeneration::available_with_reserve() const { return result; } -size_t ShenandoahGeneration::soft_available() const { - size_t result = available(ShenandoahHeap::heap()->soft_max_capacity()); +size_t ShenandoahGeneration::soft_mutator_available() const { + size_t result = available(ShenandoahHeap::heap()->soft_max_capacity() * (100.0 - ShenandoahEvacReserve) / 100); return result; } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.hpp b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.hpp index 6f393110666..06cf132f946 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGeneration.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGeneration.hpp @@ -126,7 +126,7 @@ private: // The soft max heap size may be adjusted lower than the max heap size to cause the trigger // to believe it has less memory available than is _really_ available. Lowering the soft // max heap size will cause the adaptive heuristic to run more frequent cycles. - size_t soft_available() const override; + size_t soft_mutator_available() const override; void log_status(const char* msg) const; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.cpp index c9972e2db81..a072fe2db06 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.cpp @@ -78,15 +78,6 @@ size_t ShenandoahGlobalGeneration::available() const { return MIN2(available, ShenandoahHeap::heap()->free_set()->available()); } -size_t ShenandoahGlobalGeneration::soft_available() const { - size_t available = this->available(); - - // Make sure the code below treats available without the soft tail. - assert(max_capacity() >= ShenandoahHeap::heap()->soft_max_capacity(), "Max capacity must be greater than soft max capacity."); - size_t soft_tail = max_capacity() - ShenandoahHeap::heap()->soft_max_capacity(); - return (available > soft_tail) ? (available - soft_tail) : 0; -} - void ShenandoahGlobalGeneration::set_concurrent_mark_in_progress(bool in_progress) { ShenandoahHeap* heap = ShenandoahHeap::heap(); if (in_progress && heap->mode()->is_generational()) { diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.hpp b/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.hpp index 5ceba8ed50e..9f9e4818a95 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGlobalGeneration.hpp @@ -56,7 +56,6 @@ public: size_t max_capacity() const override; size_t available() const override; - size_t soft_available() const override; void set_concurrent_mark_in_progress(bool in_progress) override; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.cpp b/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.cpp index 86be2fc60be..f00ce16136f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.cpp @@ -138,8 +138,8 @@ size_t ShenandoahYoungGeneration::available() const { return MIN2(available, ShenandoahHeap::heap()->free_set()->available()); } -size_t ShenandoahYoungGeneration::soft_available() const { - size_t available = this->ShenandoahGeneration::soft_available(); +size_t ShenandoahYoungGeneration::soft_mutator_available() const { + size_t available = this->ShenandoahGeneration::soft_mutator_available(); return MIN2(available, ShenandoahHeap::heap()->free_set()->available()); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.hpp b/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.hpp index 6b2794b12c3..930c5ff1747 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahYoungGeneration.hpp @@ -83,7 +83,7 @@ public: size_t max_capacity() const override; size_t available() const override; - size_t soft_available() const override; + size_t soft_mutator_available() const override; void prepare_gc() override; }; diff --git a/test/hotspot/jtreg/gc/shenandoah/TestSoftMaxHeapSizeAvailableCalc.java b/test/hotspot/jtreg/gc/shenandoah/TestSoftMaxHeapSizeAvailableCalc.java new file mode 100644 index 00000000000..e70f2f0849f --- /dev/null +++ b/test/hotspot/jtreg/gc/shenandoah/TestSoftMaxHeapSizeAvailableCalc.java @@ -0,0 +1,123 @@ +/* + * 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=satb-adaptive + * @requires vm.gc.Shenandoah + * @library /test/lib + * @bug 8372543 + * @summary When soft max heap size < Xmx, we had a bug reported in JBS-8372543 where available size was undercalculated. + * This caused excessive GC runs. + * + * @run main/othervm -XX:SoftMaxHeapSize=512m -Xmx2g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -Xlog:gc=info + * -XX:ShenandoahGCMode=satb + * -XX:+ShenandoahDegeneratedGC + * -XX:ShenandoahGCHeuristics=adaptive + * TestSoftMaxHeapSizeAvailableCalc + */ + +/** + * @test id=satb-static + * @requires vm.gc.Shenandoah + * @library /test/lib + * + * @run main/othervm -XX:SoftMaxHeapSize=512m -Xmx2g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -Xlog:gc=info + * -XX:ShenandoahGCMode=satb + * -XX:+ShenandoahDegeneratedGC + * -XX:ShenandoahGCHeuristics=static + * TestSoftMaxHeapSizeAvailableCalc + */ + +/** + * @test id=generational + * @requires vm.gc.Shenandoah + * @library /test/lib + * + * @run main/othervm -XX:SoftMaxHeapSize=512m -Xmx2g -XX:+UnlockDiagnosticVMOptions -XX:+UnlockExperimentalVMOptions + * -XX:+UseShenandoahGC -Xlog:gc=info + * -XX:ShenandoahGCMode=generational + * -XX:ShenandoahGCHeuristics=adaptive + * TestSoftMaxHeapSizeAvailableCalc + * + */ +import java.lang.management.ManagementFactory; + +import jdk.test.lib.Asserts; +import jdk.test.lib.Utils; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.dcmd.PidJcmdExecutor; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; + +import com.sun.management.GarbageCollectorMXBean; + +public class TestSoftMaxHeapSizeAvailableCalc { + public static void main(String[] args) throws Exception { + Allocate.test(); + } + + // This test runs an app that has a stable heap of ~300M and allocates temporary garbage at ~100M/s + // Soft max: 512M, ShenandoahMinFreeThreshold: 10 (default), ShenandoahEvacReserve: 5 (default) + // Soft max for mutator: 512M * (100.0 - 5) / 100 = 486.4M + // Threshold to trigger gc: 486.4M - 512 * 10 / 100.0 = 435.2M, just above (300 + 100)M. + // Expect gc count to be less than 1 / sec. + public static class Allocate { + static final List longLived = new ArrayList<>(); + + public static void test() throws Exception { + final int expectedMaxGcCount = Integer.getInteger("expectedMaxGcCount", 30); + List collectors = ManagementFactory.getGarbageCollectorMXBeans(); + java.lang.management.GarbageCollectorMXBean cycleCollector = null; + for (java.lang.management.GarbageCollectorMXBean bean : collectors) { + if (bean.getName().contains("Cycles")) { + cycleCollector = bean; + } + } + + // Allocate ~300MB of long-lived objects + for (int i = 0; i < 300; i++) { + longLived.add(new byte[1_000_000]); + } + + // allocate short-lived garbage to the heap + long end = System.currentTimeMillis() + 30_000; // 30 seconds + + while (System.currentTimeMillis() < end) { + byte[] garbage = new byte[1_000_000]; + garbage[0] = 1; // prevent optimization + + Thread.sleep(10); // Pace to generate garbage at speed of ~100M/s + } + + long gcCount = cycleCollector.getCollectionCount(); + Asserts.assertLessThan(gcCount, (long) expectedMaxGcCount, "GC was triggered too many times. Expected to be less than: " + expectedMaxGcCount + ", triggered: " + gcCount); + } + } +} From 78c2d57259ad829a2cfc1370efbb2a5913df4661 Mon Sep 17 00:00:00 2001 From: Axel Boldt-Christmas Date: Tue, 16 Dec 2025 07:38:26 +0000 Subject: [PATCH 013/390] 8373668: Add override keyword to *Klass classes Reviewed-by: jwaters, dholmes, kbarrett, tschatzl --- src/hotspot/share/oops/arrayKlass.hpp | 36 ++++----- src/hotspot/share/oops/instanceKlass.hpp | 78 +++++++++---------- .../share/oops/instanceMirrorKlass.hpp | 2 +- src/hotspot/share/oops/instanceRefKlass.hpp | 2 +- src/hotspot/share/oops/klass.hpp | 13 +--- src/hotspot/share/oops/objArrayKlass.hpp | 40 +++++----- src/hotspot/share/oops/typeArrayKlass.hpp | 28 +++---- 7 files changed, 97 insertions(+), 102 deletions(-) diff --git a/src/hotspot/share/oops/arrayKlass.hpp b/src/hotspot/share/oops/arrayKlass.hpp index 6ee783fb510..b9b100f18a8 100644 --- a/src/hotspot/share/oops/arrayKlass.hpp +++ b/src/hotspot/share/oops/arrayKlass.hpp @@ -51,15 +51,15 @@ class ArrayKlass: public Klass { public: // Testing operation - DEBUG_ONLY(bool is_array_klass_slow() const { return true; }) + DEBUG_ONLY(bool is_array_klass_slow() const override { return true; }) // Returns the ObjArrayKlass for n'th dimension. - ArrayKlass* array_klass(int n, TRAPS); - ArrayKlass* array_klass_or_null(int n); + ArrayKlass* array_klass(int n, TRAPS) override; + ArrayKlass* array_klass_or_null(int n) override; // Returns the array class with this class as element type. - ArrayKlass* array_klass(TRAPS); - ArrayKlass* array_klass_or_null(); + ArrayKlass* array_klass(TRAPS) override; + ArrayKlass* array_klass_or_null() override; // Instance variables int dimension() const { return _dimension; } @@ -79,7 +79,7 @@ class ArrayKlass: public Klass { // type of elements (T_OBJECT for both oop arrays and array-arrays) BasicType element_type() const { return layout_helper_element_type(layout_helper()); } - virtual InstanceKlass* java_super() const; + InstanceKlass* java_super() const override; // Allocation // Sizes points to the first dimension of the array, subsequent dimensions @@ -87,13 +87,13 @@ class ArrayKlass: public Klass { virtual oop multi_allocate(int rank, jint* sizes, TRAPS); // find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined - Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; + Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const override; // Lookup operations Method* uncached_lookup_method(const Symbol* name, const Symbol* signature, OverpassLookupMode overpass_mode, - PrivateLookupMode private_mode = PrivateLookupMode::find) const; + PrivateLookupMode private_mode = PrivateLookupMode::find) const override; static ArrayKlass* cast(Klass* k) { return const_cast(cast(const_cast(k))); @@ -105,38 +105,38 @@ class ArrayKlass: public Klass { } GrowableArray* compute_secondary_supers(int num_extra_slots, - Array* transitive_interfaces); + Array* transitive_interfaces) override; // Sizing static int static_size(int header_size); - virtual void metaspace_pointers_do(MetaspaceClosure* iter); + void metaspace_pointers_do(MetaspaceClosure* iter) override; // Return a handle. static void complete_create_array_klass(ArrayKlass* k, Klass* super_klass, ModuleEntry* module, TRAPS); // JVMTI support - jint jvmti_class_status() const; + jint jvmti_class_status() const override; #if INCLUDE_CDS // CDS support - remove and restore oops from metadata. Oops are not shared. - virtual void remove_unshareable_info(); - virtual void remove_java_mirror(); + void remove_unshareable_info() override; + void remove_java_mirror() override; void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS); void cds_print_value_on(outputStream* st) const; #endif void log_array_class_load(Klass* k); // Printing - void print_on(outputStream* st) const; - void print_value_on(outputStream* st) const; + void print_on(outputStream* st) const override; + void print_value_on(outputStream* st) const override; - void oop_print_on(oop obj, outputStream* st); + void oop_print_on(oop obj, outputStream* st) override; // Verification - void verify_on(outputStream* st); + void verify_on(outputStream* st) override; - void oop_verify_on(oop obj, outputStream* st); + void oop_verify_on(oop obj, outputStream* st) override; }; #endif // SHARE_OOPS_ARRAYKLASS_HPP diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index a03e6c05b54..23a59d26093 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -313,8 +313,8 @@ class InstanceKlass: public Klass { bool is_public() const { return _access_flags.is_public(); } bool is_final() const { return _access_flags.is_final(); } - bool is_interface() const { return _access_flags.is_interface(); } - bool is_abstract() const { return _access_flags.is_abstract(); } + bool is_interface() const override { return _access_flags.is_interface(); } + bool is_abstract() const override { return _access_flags.is_abstract(); } bool is_super() const { return _access_flags.is_super(); } bool is_synthetic() const { return _access_flags.is_synthetic(); } void set_is_synthetic() { _access_flags.set_is_synthetic(); } @@ -494,8 +494,8 @@ public: }; // package - PackageEntry* package() const { return _package_entry; } - ModuleEntry* module() const; + PackageEntry* package() const override { return _package_entry; } + ModuleEntry* module() const override; bool in_javabase_module() const; bool in_unnamed_package() const { return (_package_entry == nullptr); } void set_package(ClassLoaderData* loader_data, PackageEntry* pkg_entry, TRAPS); @@ -552,11 +552,11 @@ public: void set_is_marked_dependent(bool value) { _misc_flags.set_is_marked_dependent(value); } // initialization (virtuals from Klass) - bool should_be_initialized() const; // means that initialize should be called + bool should_be_initialized() const override; // means that initialize should be called void initialize_with_aot_initialized_mirror(TRAPS); void assert_no_clinit_will_run_for_aot_initialized_class() const NOT_DEBUG_RETURN; - void initialize(TRAPS); - void initialize_preemptable(TRAPS); + void initialize(TRAPS) override; + void initialize_preemptable(TRAPS) override; void link_class(TRAPS); bool link_class_or_fail(TRAPS); // returns false on failure void rewrite_class(TRAPS); @@ -578,7 +578,7 @@ public: // find field in direct superinterfaces, returns the interface in which the field is defined Klass* find_interface_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; // find field according to JVM spec 5.4.3.2, returns the klass in which the field is defined - Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const; + Klass* find_field(Symbol* name, Symbol* sig, fieldDescriptor* fd) const override; // find instance or static fields according to JVM spec 5.4.3.2, returns the klass in which the field is defined Klass* find_field(Symbol* name, Symbol* sig, bool is_static, fieldDescriptor* fd) const; @@ -637,7 +637,7 @@ public: Method* uncached_lookup_method(const Symbol* name, const Symbol* signature, OverpassLookupMode overpass_mode, - PrivateLookupMode private_mode = PrivateLookupMode::find) const; + PrivateLookupMode private_mode = PrivateLookupMode::find) const override; // lookup a method in all the interfaces that this class implements // (returns null if not found) @@ -660,7 +660,7 @@ public: void set_constants(ConstantPool* c) { _constants = c; } // protection domain - oop protection_domain() const; + oop protection_domain() const override; // signers objArrayOop signers() const; @@ -834,7 +834,7 @@ public: // Check whether reflection/jni/jvm code is allowed to instantiate this class; // if not, throw either an Error or an Exception. - virtual void check_valid_for_instantiation(bool throwError, TRAPS); + void check_valid_for_instantiation(bool throwError, TRAPS) override; // initialization void call_class_initializer(TRAPS); @@ -901,12 +901,12 @@ public: public: // virtual operations from Klass GrowableArray* compute_secondary_supers(int num_extra_slots, - Array* transitive_interfaces); - bool can_be_primary_super_slow() const; - size_t oop_size(oop obj) const { return size_helper(); } + Array* transitive_interfaces) override; + bool can_be_primary_super_slow() const override; + size_t oop_size(oop obj) const override { return size_helper(); } // slow because it's a virtual call and used for verifying the layout_helper. // Using the layout_helper bits, we can call is_instance_klass without a virtual call. - DEBUG_ONLY(bool is_instance_klass_slow() const { return true; }) + DEBUG_ONLY(bool is_instance_klass_slow() const override { return true; }) // Iterators void do_local_static_fields(FieldClosure* cl); @@ -932,7 +932,7 @@ public: return (Klass::super() == nullptr) ? nullptr : InstanceKlass::cast(Klass::super()); } - virtual InstanceKlass* java_super() const { + InstanceKlass* java_super() const override { return InstanceKlass::super(); } @@ -949,10 +949,10 @@ public: (is_interface ? (int)sizeof(Klass*)/wordSize : 0)); } - int size() const { return size(vtable_length(), - itable_length(), - nonstatic_oop_map_size(), - is_interface()); + int size() const override { return size(vtable_length(), + itable_length(), + nonstatic_oop_map_size(), + is_interface()); } @@ -1008,15 +1008,15 @@ public: void static deallocate_record_components(ClassLoaderData* loader_data, Array* record_component); - virtual bool on_stack() const; + bool on_stack() const override; // callbacks for actions during class unloading static void unload_class(InstanceKlass* ik); - virtual void release_C_heap_structures(bool release_sub_metadata = true); + void release_C_heap_structures(bool release_sub_metadata = true) override; // Naming - const char* signature_name() const; + const char* signature_name() const override; // Oop fields (and metadata) iterators // @@ -1095,12 +1095,12 @@ public: oop init_lock() const; // Returns the array class for the n'th dimension - virtual ArrayKlass* array_klass(int n, TRAPS); - virtual ArrayKlass* array_klass_or_null(int n); + ArrayKlass* array_klass(int n, TRAPS) override; + ArrayKlass* array_klass_or_null(int n) override; // Returns the array class with this class as element type - virtual ArrayKlass* array_klass(TRAPS); - virtual ArrayKlass* array_klass_or_null(); + ArrayKlass* array_klass(TRAPS) override; + ArrayKlass* array_klass_or_null() override; static void clean_initialization_error_table(); private: @@ -1139,9 +1139,9 @@ public: #if INCLUDE_CDS // CDS support - remove and restore oops from metadata. Oops are not shared. - virtual void remove_unshareable_info(); + void remove_unshareable_info() override; void remove_unshareable_flags(); - virtual void remove_java_mirror(); + void remove_java_mirror() override; void restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, PackageEntry* pkg_entry, TRAPS); void init_shared_package_entry(); bool can_be_verified_at_dumptime() const; @@ -1154,22 +1154,22 @@ public: _misc_flags.set_has_init_deps_processed(true); } - u2 compute_modifier_flags() const; + u2 compute_modifier_flags() const override; public: // JVMTI support - jint jvmti_class_status() const; + jint jvmti_class_status() const override; - virtual void metaspace_pointers_do(MetaspaceClosure* iter); + void metaspace_pointers_do(MetaspaceClosure* iter) override; public: // Printing - void print_on(outputStream* st) const; - void print_value_on(outputStream* st) const; + void print_on(outputStream* st) const override; + void print_value_on(outputStream* st) const override; - void oop_print_value_on(oop obj, outputStream* st); + void oop_print_value_on(oop obj, outputStream* st) override; - void oop_print_on (oop obj, outputStream* st); + void oop_print_on (oop obj, outputStream* st) override; #ifndef PRODUCT void print_dependent_nmethods(bool verbose = false); @@ -1177,12 +1177,12 @@ public: bool verify_itable_index(int index); #endif - const char* internal_name() const; + const char* internal_name() const override; // Verification - void verify_on(outputStream* st); + void verify_on(outputStream* st) override; - void oop_verify_on(oop obj, outputStream* st); + void oop_verify_on(oop obj, outputStream* st) override; // Logging void print_class_load_logging(ClassLoaderData* loader_data, diff --git a/src/hotspot/share/oops/instanceMirrorKlass.hpp b/src/hotspot/share/oops/instanceMirrorKlass.hpp index 4546f904eca..a89e573503d 100644 --- a/src/hotspot/share/oops/instanceMirrorKlass.hpp +++ b/src/hotspot/share/oops/instanceMirrorKlass.hpp @@ -67,7 +67,7 @@ class InstanceMirrorKlass: public InstanceKlass { } // Returns the size of the instance including the extra static fields. - virtual size_t oop_size(oop obj) const; + size_t oop_size(oop obj) const override; // Static field offset is an offset into the Heap, should be converted by // based on UseCompressedOop for traversal diff --git a/src/hotspot/share/oops/instanceRefKlass.hpp b/src/hotspot/share/oops/instanceRefKlass.hpp index c372b83a267..57126156dd8 100644 --- a/src/hotspot/share/oops/instanceRefKlass.hpp +++ b/src/hotspot/share/oops/instanceRefKlass.hpp @@ -126,7 +126,7 @@ class InstanceRefKlass: public InstanceKlass { public: // Verification - void oop_verify_on(oop obj, outputStream* st); + void oop_verify_on(oop obj, outputStream* st) override; }; #endif // SHARE_OOPS_INSTANCEREFKLASS_HPP diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index 25fb900e7d6..b6974762209 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -215,7 +215,7 @@ protected: enum class StaticLookupMode { find, skip }; enum class PrivateLookupMode { find, skip }; - virtual bool is_klass() const { return true; } + bool is_klass() const override { return true; } // super() cannot be InstanceKlass* -- Java arrays are covariant, and _super is used // to implement that. NB: the _super of "[Ljava/lang/Integer;" is "[Ljava/lang/Number;" @@ -649,9 +649,6 @@ public: // actual oop size of obj in memory in word size. virtual size_t oop_size(oop obj) const = 0; - // Size of klass in word size. - virtual int size() const = 0; - // Returns the Java name for a class (Resource allocated) // For arrays, this returns the name of the element with a leading '['. // For classes, this returns the name with the package separators @@ -728,8 +725,8 @@ public: JFR_ONLY(DEFINE_TRACE_ID_METHODS;) - virtual void metaspace_pointers_do(MetaspaceClosure* iter); - virtual MetaspaceObj::Type type() const { return ClassType; } + void metaspace_pointers_do(MetaspaceClosure* iter) override; + MetaspaceObj::Type type() const override { return ClassType; } inline bool is_loader_alive() const; inline bool is_loader_present_and_alive() const; @@ -764,15 +761,13 @@ public: virtual jint jvmti_class_status() const; // Printing - virtual void print_on(outputStream* st) const; + void print_on(outputStream* st) const override; virtual void oop_print_value_on(oop obj, outputStream* st); virtual void oop_print_on (oop obj, outputStream* st); void print_secondary_supers_on(outputStream* st) const; - virtual const char* internal_name() const = 0; - // Verification virtual void verify_on(outputStream* st); void verify() { verify_on(tty); } diff --git a/src/hotspot/share/oops/objArrayKlass.hpp b/src/hotspot/share/oops/objArrayKlass.hpp index 1a4f7f657d2..12db56351ed 100644 --- a/src/hotspot/share/oops/objArrayKlass.hpp +++ b/src/hotspot/share/oops/objArrayKlass.hpp @@ -72,29 +72,29 @@ class ObjArrayKlass : public ArrayKlass { void set_bottom_klass(Klass* k) { _bottom_klass = k; } Klass** bottom_klass_addr() { return &_bottom_klass; } - ModuleEntry* module() const; - PackageEntry* package() const; + ModuleEntry* module() const override; + PackageEntry* package() const override; // Dispatched operation - bool can_be_primary_super_slow() const; + bool can_be_primary_super_slow() const override; GrowableArray* compute_secondary_supers(int num_extra_slots, - Array* transitive_interfaces); - DEBUG_ONLY(bool is_objArray_klass_slow() const { return true; }) - size_t oop_size(oop obj) const; + Array* transitive_interfaces) override; + DEBUG_ONLY(bool is_objArray_klass_slow() const override { return true; }) + size_t oop_size(oop obj) const override; // Allocation static ObjArrayKlass* allocate_objArray_klass(ClassLoaderData* loader_data, int n, Klass* element_klass, TRAPS); - oop multi_allocate(int rank, jint* sizes, TRAPS); + oop multi_allocate(int rank, jint* sizes, TRAPS) override; // Copying - void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS); + void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS) override; // Compute protection domain - oop protection_domain() const { return bottom_klass()->protection_domain(); } + oop protection_domain() const override { return bottom_klass()->protection_domain(); } - virtual void metaspace_pointers_do(MetaspaceClosure* iter); + virtual void metaspace_pointers_do(MetaspaceClosure* iter) override; private: // Either oop or narrowOop depending on UseCompressedOops. @@ -114,10 +114,10 @@ class ObjArrayKlass : public ArrayKlass { // Sizing static int header_size() { return sizeof(ObjArrayKlass)/wordSize; } - int size() const { return ArrayKlass::static_size(header_size()); } + int size() const override { return ArrayKlass::static_size(header_size()); } // Initialization (virtual from Klass) - void initialize(TRAPS); + void initialize(TRAPS) override; // Oop fields (and metadata) iterators // @@ -150,24 +150,24 @@ class ObjArrayKlass : public ArrayKlass { inline void oop_oop_iterate_elements_bounded(objArrayOop a, OopClosureType* closure, void* low, void* high); public: - u2 compute_modifier_flags() const; + u2 compute_modifier_flags() const override; public: // Printing - void print_on(outputStream* st) const; - void print_value_on(outputStream* st) const; + void print_on(outputStream* st) const override; + void print_value_on(outputStream* st) const override; - void oop_print_value_on(oop obj, outputStream* st); + void oop_print_value_on(oop obj, outputStream* st) override; #ifndef PRODUCT - void oop_print_on (oop obj, outputStream* st); + void oop_print_on (oop obj, outputStream* st) override; #endif //PRODUCT - const char* internal_name() const; + const char* internal_name() const override; // Verification - void verify_on(outputStream* st); + void verify_on(outputStream* st) override; - void oop_verify_on(oop obj, outputStream* st); + void oop_verify_on(oop obj, outputStream* st) override; }; #endif // SHARE_OOPS_OBJARRAYKLASS_HPP diff --git a/src/hotspot/share/oops/typeArrayKlass.hpp b/src/hotspot/share/oops/typeArrayKlass.hpp index 22600702fe2..87a41a6d4b3 100644 --- a/src/hotspot/share/oops/typeArrayKlass.hpp +++ b/src/hotspot/share/oops/typeArrayKlass.hpp @@ -56,10 +56,10 @@ class TypeArrayKlass : public ArrayKlass { jint max_length() { return _max_length; } void set_max_length(jint m) { _max_length = m; } - u2 compute_modifier_flags() const; + u2 compute_modifier_flags() const override; // testers - DEBUG_ONLY(bool is_typeArray_klass_slow() const { return true; }) + DEBUG_ONLY(bool is_typeArray_klass_slow() const override { return true; }) // klass allocation static TypeArrayKlass* create_klass(BasicType type, const char* name_str, @@ -68,15 +68,15 @@ class TypeArrayKlass : public ArrayKlass { return create_klass(type, external_name(type), THREAD); } - size_t oop_size(oop obj) const; + size_t oop_size(oop obj) const override; // Allocation - oop multi_allocate(int rank, jint* sizes, TRAPS); + oop multi_allocate(int rank, jint* sizes, TRAPS) override; - oop protection_domain() const { return nullptr; } + oop protection_domain() const override { return nullptr; } // Copying - void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS); + void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS) override; // Oop iterators. Since there are no oops in TypeArrayKlasses, // these functions only return the size of the object. @@ -113,23 +113,23 @@ class TypeArrayKlass : public ArrayKlass { // Sizing static int header_size() { return sizeof(TypeArrayKlass)/wordSize; } - int size() const { return ArrayKlass::static_size(header_size()); } + int size() const override { return ArrayKlass::static_size(header_size()); } // Initialization (virtual from Klass) - void initialize(TRAPS); + void initialize(TRAPS) override; public: // Printing - void oop_print_on(oop obj, outputStream* st); + void oop_print_on(oop obj, outputStream* st) override; void oop_print_elements_on(typeArrayOop ta, outputStream* st); - void print_on(outputStream* st) const; - void print_value_on(outputStream* st) const; + void print_on(outputStream* st) const override; + void print_value_on(outputStream* st) const override; public: - const char* internal_name() const; + const char* internal_name() const override; - ModuleEntry* module() const; - PackageEntry* package() const; + ModuleEntry* module() const override; + PackageEntry* package() const override; }; #endif // SHARE_OOPS_TYPEARRAYKLASS_HPP From 8402891889c29894555eca6449ba63f7b7458124 Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Tue, 16 Dec 2025 09:34:42 +0000 Subject: [PATCH 014/390] 8373355: C2: CompileCommand PrintIdealPhase should also print nodes that are not "reachable from below" Reviewed-by: rcastanedalo, mchevalier, bmaillard --- src/hotspot/share/opto/compile.cpp | 4 +- .../compiler/c2/irTests/ModDNodeTests.java | 94 ++++++++++++++----- .../compiler/c2/irTests/ModFNodeTests.java | 94 ++++++++++++++----- .../compiler/lib/ir_framework/IRNode.java | 10 -- .../tests/TestIRFindFromAbove.java | 63 +++++++++++++ 5 files changed, 210 insertions(+), 55 deletions(-) create mode 100644 test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRFindFromAbove.java diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 16f5be50805..cea2b09e142 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -595,7 +595,9 @@ void Compile::print_ideal_ir(const char* phase_name) { if (_output == nullptr) { ss.print_cr("AFTER: %s", phase_name); // Print out all nodes in ascending order of index. - root()->dump_bfs(MaxNodeLimit, nullptr, "+S$", &ss); + // It is important that we traverse both inputs and outputs of nodes, + // so that we reach all nodes that are connected to Root. + root()->dump_bfs(MaxNodeLimit, nullptr, "-+S$", &ss); } else { // Dump the node blockwise if we have a scheduling _output->print_scheduling(&ss); diff --git a/test/hotspot/jtreg/compiler/c2/irTests/ModDNodeTests.java b/test/hotspot/jtreg/compiler/c2/irTests/ModDNodeTests.java index 7eed798871e..6b20b782923 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/ModDNodeTests.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/ModDNodeTests.java @@ -63,17 +63,29 @@ public class ModDNodeTests { Asserts.assertEQ(unusedResultAfterLoopOpt3(1.1d, 2.2d), 0.d); } + // Note: we used to check for ConD nodes in the IR. But that is a bit brittle: + // Constant nodes can appear during IR transformations, and then lose their outputs. + // During IGNV, the constants stay in the graph even if they lose the inputs. But + // CCP cleans them out because they are not in the useful set. So for now, we do not + // rely on any constant counting, just on counting the operation nodes. + @Test - @IR(failOn = {"drem"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_D, "1"}) + @IR(counts = {IRNode.MOD_D, "2"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {".*CallLeaf.*drem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public double constant() { // All constants available during parsing return q % 72.0d % 30.0d; } @Test - @IR(failOn = {"drem"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_D, "1"}) + @IR(counts = {IRNode.MOD_D, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_D, "1"}, + phase = CompilePhase.PHASEIDEALLOOP1) // Only constant fold after some loop opts + @IR(counts = {".*CallLeaf.*drem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public double alsoConstant() { // Make sure value is only available after second loop opts round double val = 0; @@ -86,8 +98,12 @@ public class ModDNodeTests { } @Test - @IR(failOn = {"drem"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_D, "1"}) + @IR(counts = {IRNode.MOD_D, "2"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_D, "2"}, + phase = CompilePhase.PHASEIDEALLOOP1) // Only constant fold after some loop opts + @IR(counts = {".*CallLeaf.*drem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public double nanLeftConstant() { // Make sure value is only available after second loop opts round double val = 134.18d; @@ -100,8 +116,12 @@ public class ModDNodeTests { } @Test - @IR(failOn = {"drem"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_D, "1"}) + @IR(counts = {IRNode.MOD_D, "2"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_D, "2"}, + phase = CompilePhase.PHASEIDEALLOOP1) // Only constant fold after some loop opts + @IR(counts = {".*CallLeaf.*drem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public double nanRightConstant() { // Make sure value is only available after second loop opts round double val = 134.18d; @@ -114,29 +134,41 @@ public class ModDNodeTests { } @Test - @IR(counts = {"drem", "1"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_D, "1"}) + @IR(counts = {IRNode.MOD_D, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {".*CallLeaf.*drem.*", "1"}, + phase = CompilePhase.BEFORE_MATCHING) // no constant folding public double notConstant(double x) { return x % 32.0d; } @Test - @IR(counts = {"drem", "2"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_D, "1"}) + @IR(counts = {IRNode.MOD_D, "2"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {".*CallLeaf.*drem.*", "2"}, + phase = CompilePhase.BEFORE_MATCHING) // no constant folding public double veryNotConstant(double x, double y) { return x % 32.0d % y; } @Test - @IR(failOn = IRNode.MOD_D, phase = CompilePhase.ITER_GVN1) - @IR(counts = {IRNode.MOD_D, "1"}, phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_D, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_D, "0"}, + phase = CompilePhase.ITER_GVN1) // IGVN removes unused nodes + @IR(counts = {".*CallLeaf.*drem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public void unusedResult(double x, double y) { double unused = x % y; } @Test - @IR(failOn = IRNode.MOD_D, phase = CompilePhase.ITER_GVN1) - @IR(counts = {IRNode.MOD_D, "1"}, phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_D, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_D, "0"}, + phase = CompilePhase.ITER_GVN1) // IGVN removes unused nodes + @IR(counts = {".*CallLeaf.*drem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public void repeatedlyUnused(double x, double y) { double unused = 1.d; for (int i = 0; i < 100_000; i++) { @@ -149,8 +181,14 @@ public class ModDNodeTests { // and thus a different execution path. In unusedResultAfterLoopOpt1 the modulo is // used in the traps of the parse predicates. In unusedResultAfterLoopOpt2, it is not. @Test - @IR(counts = {IRNode.MOD_D, "1"}, phase = CompilePhase.ITER_GVN2) - @IR(failOn = IRNode.MOD_D, phase = CompilePhase.BEFORE_MACRO_EXPANSION) + @IR(counts = {IRNode.MOD_D, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_D, "1"}, + phase = CompilePhase.ITER_GVN2) + @IR(counts = {IRNode.MOD_D, "0"}, + phase = CompilePhase.BEFORE_MACRO_EXPANSION) + @IR(counts = {".*CallLeaf.*drem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public double unusedResultAfterLoopOpt1(double x, double y) { double unused = x % y; @@ -168,8 +206,14 @@ public class ModDNodeTests { } @Test - @IR(counts = {IRNode.MOD_D, "1"}, phase = CompilePhase.AFTER_CLOOPS) - @IR(failOn = IRNode.MOD_D, phase = CompilePhase.PHASEIDEALLOOP1) + @IR(counts = {IRNode.MOD_D, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_D, "1"}, + phase = CompilePhase.AFTER_CLOOPS) + @IR(counts = {IRNode.MOD_D, "0"}, + phase = CompilePhase.PHASEIDEALLOOP1) + @IR(counts = {".*CallLeaf.*drem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public double unusedResultAfterLoopOpt2(double x, double y) { int a = 77; int b = 0; @@ -187,8 +231,14 @@ public class ModDNodeTests { } @Test - @IR(counts = {IRNode.MOD_D, "2"}, phase = CompilePhase.AFTER_CLOOPS) - @IR(failOn = IRNode.MOD_D, phase = CompilePhase.PHASEIDEALLOOP1) + @IR(counts = {IRNode.MOD_D, "3"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_D, "2"}, + phase = CompilePhase.AFTER_CLOOPS) // drop the useless one + @IR(counts = {IRNode.MOD_D, "0"}, + phase = CompilePhase.PHASEIDEALLOOP1) // drop the rest + @IR(counts = {".*CallLeaf.*drem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public double unusedResultAfterLoopOpt3(double x, double y) { double unused = x % y; diff --git a/test/hotspot/jtreg/compiler/c2/irTests/ModFNodeTests.java b/test/hotspot/jtreg/compiler/c2/irTests/ModFNodeTests.java index 886efe57124..2f69578c2f0 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/ModFNodeTests.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/ModFNodeTests.java @@ -63,17 +63,29 @@ public class ModFNodeTests { Asserts.assertEQ(unusedResultAfterLoopOpt3(1.1f, 2.2f), 0.f); } + // Note: we used to check for ConF nodes in the IR. But that is a bit brittle: + // Constant nodes can appear during IR transformations, and then lose their outputs. + // During IGNV, the constants stay in the graph even if they lose the inputs. But + // CCP cleans them out because they are not in the useful set. So for now, we do not + // rely on any constant counting, just on counting the operation nodes. + @Test - @IR(failOn = {"frem"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_F, "1"}) + @IR(counts = {IRNode.MOD_F, "2"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {".*CallLeaf.*frem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public float constant() { // All constants available during parsing return q % 72.0f % 30.0f; } @Test - @IR(failOn = {"frem"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_F, "1"}) + @IR(counts = {IRNode.MOD_F, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_F, "1"}, + phase = CompilePhase.PHASEIDEALLOOP1) // Only constant fold after some loop opts + @IR(counts = {".*CallLeaf.*frem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public float alsoConstant() { // Make sure value is only available after second loop opts round float val = 0; @@ -86,8 +98,12 @@ public class ModFNodeTests { } @Test - @IR(failOn = {"frem"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_F, "1"}) + @IR(counts = {IRNode.MOD_F, "2"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_F, "2"}, + phase = CompilePhase.PHASEIDEALLOOP1) // Only constant fold after some loop opts + @IR(counts = {".*CallLeaf.*frem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public float nanLeftConstant() { // Make sure value is only available after second loop opts round float val = 134.18f; @@ -100,8 +116,12 @@ public class ModFNodeTests { } @Test - @IR(failOn = {"frem"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_F, "1"}) + @IR(counts = {IRNode.MOD_F, "2"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_F, "2"}, + phase = CompilePhase.PHASEIDEALLOOP1) // Only constant fold after some loop opts + @IR(counts = {".*CallLeaf.*frem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public float nanRightConstant() { // Make sure value is only available after second loop opts round float val = 134.18f; @@ -114,29 +134,41 @@ public class ModFNodeTests { } @Test - @IR(counts = {"frem", "1"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_F, "1"}) + @IR(counts = {IRNode.MOD_F, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {".*CallLeaf.*frem.*", "1"}, + phase = CompilePhase.BEFORE_MATCHING) // no constant folding public float notConstant(float x) { return x % 32.0f; } @Test - @IR(counts = {"frem", "2"}, phase = CompilePhase.BEFORE_MATCHING) - @IR(counts = {IRNode.CON_F, "1"}) + @IR(counts = {IRNode.MOD_F, "2"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {".*CallLeaf.*frem.*", "2"}, + phase = CompilePhase.BEFORE_MATCHING) // no constant folding public float veryNotConstant(float x, float y) { return x % 32.0f % y; } @Test - @IR(failOn = IRNode.MOD_F, phase = CompilePhase.ITER_GVN1) - @IR(counts = {IRNode.MOD_F, "1"}, phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_F, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_F, "0"}, + phase = CompilePhase.ITER_GVN1) // IGVN removes unused nodes + @IR(counts = {".*CallLeaf.*frem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public void unusedResult(float x, float y) { float unused = x % y; } @Test - @IR(failOn = IRNode.MOD_F, phase = CompilePhase.ITER_GVN1) - @IR(counts = {IRNode.MOD_F, "1"}, phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_F, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_F, "0"}, + phase = CompilePhase.ITER_GVN1) // IGVN removes unused nodes + @IR(counts = {".*CallLeaf.*frem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public void repeatedlyUnused(float x, float y) { float unused = 1.f; for (int i = 0; i < 100_000; i++) { @@ -149,8 +181,14 @@ public class ModFNodeTests { // and thus a different execution path. In unusedResultAfterLoopOpt1 the modulo is // used in the traps of the parse predicates. In unusedResultAfterLoopOpt2, it is not. @Test - @IR(counts = {IRNode.MOD_F, "1"}, phase = CompilePhase.ITER_GVN2) - @IR(failOn = IRNode.MOD_F, phase = CompilePhase.BEFORE_MACRO_EXPANSION) + @IR(counts = {IRNode.MOD_F, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_F, "1"}, + phase = CompilePhase.ITER_GVN2) + @IR(counts = {IRNode.MOD_F, "0"}, + phase = CompilePhase.BEFORE_MACRO_EXPANSION) + @IR(counts = {".*CallLeaf.*frem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public float unusedResultAfterLoopOpt1(float x, float y) { float unused = x % y; @@ -168,8 +206,14 @@ public class ModFNodeTests { } @Test - @IR(counts = {IRNode.MOD_F, "1"}, phase = CompilePhase.AFTER_CLOOPS) - @IR(failOn = IRNode.MOD_F, phase = CompilePhase.PHASEIDEALLOOP1) + @IR(counts = {IRNode.MOD_F, "1"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_F, "1"}, + phase = CompilePhase.AFTER_CLOOPS) + @IR(counts = {IRNode.MOD_F, "0"}, + phase = CompilePhase.PHASEIDEALLOOP1) + @IR(counts = {".*CallLeaf.*frem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public float unusedResultAfterLoopOpt2(float x, float y) { int a = 77; int b = 0; @@ -187,8 +231,14 @@ public class ModFNodeTests { } @Test - @IR(counts = {IRNode.MOD_F, "2"}, phase = CompilePhase.AFTER_CLOOPS) - @IR(failOn = IRNode.MOD_F, phase = CompilePhase.PHASEIDEALLOOP1) + @IR(counts = {IRNode.MOD_F, "3"}, + phase = CompilePhase.AFTER_PARSING) + @IR(counts = {IRNode.MOD_F, "2"}, + phase = CompilePhase.AFTER_CLOOPS) // drop the useless one + @IR(counts = {IRNode.MOD_F, "0"}, + phase = CompilePhase.PHASEIDEALLOOP1) // drop the rest + @IR(counts = {".*CallLeaf.*frem.*", "0"}, + phase = CompilePhase.BEFORE_MATCHING) public float unusedResultAfterLoopOpt3(float x, float y) { float unused = x % y; diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java index d5799e5aa05..3fd8e2eceb4 100644 --- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java +++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java @@ -690,16 +690,6 @@ public class IRNode { beforeMatchingNameRegex(CON_L, "ConL"); } - public static final String CON_D = PREFIX + "CON_D" + POSTFIX; - static { - beforeMatchingNameRegex(CON_D, "ConD"); - } - - public static final String CON_F = PREFIX + "CON_F" + POSTFIX; - static { - beforeMatchingNameRegex(CON_F, "ConF"); - } - public static final String COUNTED_LOOP = PREFIX + "COUNTED_LOOP" + POSTFIX; static { String regex = START + "CountedLoop\\b" + MID + END; diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRFindFromAbove.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRFindFromAbove.java new file mode 100644 index 00000000000..23e46428460 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/tests/TestIRFindFromAbove.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 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 ir_framework.tests; + +import compiler.lib.ir_framework.*; + +/* + * @test + * @bug 8373355 + * @summary Test that IR matching happens on the whole graph, not just nodes + * that can be found by traversing up from the Root. + * @library /test/lib / + * @run main ${test.main.class} + */ + +public class TestIRFindFromAbove { + public static boolean flag = false; + public static int fld = 0; + + public static void main(String[] args) { + TestFramework.run(); + } + + @Test + @Warmup(0) + // Simulate Xcomp with no warmup: ensure the flag branch is not an unstable if + // but that we compile the infinite loop. + @IR(counts = {IRNode.LOAD_I, "1", IRNode.STORE_I, "1", ".*NeverBranch.*", "0"}, + phase = CompilePhase.ITER_GVN1) + @IR(counts = {IRNode.LOAD_I, "1", IRNode.STORE_I, "1", ".*NeverBranch.*", "1"}, + phase = CompilePhase.PHASEIDEALLOOP1) + public static void test() { + if (flag) { + // This loop has no exit. So it is at first not connected down to Root. + while (true) { + // During PHASEIDEALLOOP1, we insert a NeverBranch here, with a fake + // exit, that connects the loop down to Root. + fld++; // LoadI and StoreI + } + } + } +} From 43d4456181fcd759e3f1de7ca4f6d74827a3c644 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Tue, 16 Dec 2025 10:01:13 +0000 Subject: [PATCH 015/390] 8373570: Javac stack overflow on method-local class with nested record referring to enclosing type Reviewed-by: vromero --- .../com/sun/tools/javac/comp/Resolve.java | 5 +- .../javac/SuperInit/NewLocalNotInInner.java | 72 +++++++++++++++++++ .../javac/SuperInit/NewLocalNotInInner.out | 6 ++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 test/langtools/tools/javac/SuperInit/NewLocalNotInInner.java create mode 100644 test/langtools/tools/javac/SuperInit/NewLocalNotInInner.out diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index 07f2a742bcb..d88180bb15c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -3843,12 +3843,15 @@ public class Resolve { Env env1 = env; boolean staticOnly = false; while (env1.outer != null) { + // If the local class is defined inside a static method, and the instance creation expression + // occurs in that same method, the creation occurs (technically) inside a static context, but that's ok. if (env1.info.scope.owner == owner) { return (staticOnly) ? new BadLocalClassCreation(c) : owner; + } else if (isStatic(env1) || env1.enclClass.sym.isStatic()) { + staticOnly = true; } - if (isStatic(env1)) staticOnly = true; env1 = env1.outer; } return owner.kind == MTH ? diff --git a/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.java b/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.java new file mode 100644 index 00000000000..8a69bc37667 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.java @@ -0,0 +1,72 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8373570 + * @summary Javac stack overflow on method-local class with nested record referring to enclosing type + * @compile/fail/ref=NewLocalNotInInner.out -XDrawDiagnostics NewLocalNotInInner.java + */ +class NewLocalNotInInner { + void m() { + class Local { + static class Foo { + void m() { + new Local(); // error + } + } + } + } + + void m_anon() { + class Local { + static class Foo { + void m() { + new Local() { }; // error + } + } + } + } + + void m_record() { + class Local { + record Foo() { + void m() { + new Local(); // error + } + } + } + } + + void m_intf() { + class Local { + interface Foo { + default void m() { + new Local(); // error + } + } + } + } + + void sup() { + class Local { + static class Foo { + void m() { + class Sub extends Local { }; // error + new Sub(); + } + } + } + } + + static void staticLocal() { + class Local { } + new Local(); // ok + } + + static void staticLocalFromAnon() { + class Local { } + new Object() { + Local local() { + return new Local(); // ok + } + }; + } +} diff --git a/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.out b/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.out new file mode 100644 index 00000000000..dd816f2ab0e --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/NewLocalNotInInner.out @@ -0,0 +1,6 @@ +NewLocalNotInInner.java:12:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +NewLocalNotInInner.java:22:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +NewLocalNotInInner.java:32:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +NewLocalNotInInner.java:42:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +NewLocalNotInInner.java:52:21: compiler.err.local.cant.be.inst.static: kindname.class, Local +5 errors From 41d28c1838bcd7a69f78c9799b449af2a33c11c3 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Tue, 16 Dec 2025 10:08:08 +0000 Subject: [PATCH 016/390] 8373561: Replace usages of -verify java launcher option with -Xverify:all JVM option Reviewed-by: serb, prr, dholmes, jlahoda --- test/hotspot/jtreg/runtime/verifier/TestANewArray.java | 6 +++--- test/hotspot/jtreg/runtime/verifier/TraceClassRes.java | 2 +- .../verifier/stackMapTableTests/StackMapTableTest.java | 4 ++-- test/jdk/javax/swing/JFileChooser/6520101/bug6520101.java | 4 ++-- .../langtools/tools/javac/VarDeclarationWithAssignment.java | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/test/hotspot/jtreg/runtime/verifier/TestANewArray.java b/test/hotspot/jtreg/runtime/verifier/TestANewArray.java index e1b0dcf764c..f7b133868d4 100644 --- a/test/hotspot/jtreg/runtime/verifier/TestANewArray.java +++ b/test/hotspot/jtreg/runtime/verifier/TestANewArray.java @@ -69,7 +69,7 @@ public class TestANewArray { byte[] classFile_254 = dumpClassFile(cfv, test_Dimension_254, array_Dimension_254); writeClassFileFromByteArray(classFile_254); System.err.println("Running with cfv: " + cfv + ", test_Dimension_254"); - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder("-verify", "-cp", ".", classCName); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder("-Xverify:all", "-cp", ".", classCName); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldNotContain("java.lang.VerifyError"); output.shouldHaveExitValue(0); @@ -78,7 +78,7 @@ public class TestANewArray { byte[] classFile_255 = dumpClassFile(cfv, test_Dimension_255, array_Dimension_255); writeClassFileFromByteArray(classFile_255); System.err.println("Running with cfv: " + cfv + ", test_Dimension_255"); - pb = ProcessTools.createTestJavaProcessBuilder("-verify", "-cp", ".", classCName); + pb = ProcessTools.createTestJavaProcessBuilder("-Xverify:all", "-cp", ".", classCName); output = new OutputAnalyzer(pb.start()); // If anewarray has an operand with 255 array dimensions then VerifyError should // be thrown because the resulting array would have 256 dimensions. @@ -95,7 +95,7 @@ public class TestANewArray { byte[] classFile_264 = dumpClassFile(cfv, test_Dimension_264, array_Dimension_264); writeClassFileFromByteArray(classFile_264); System.err.println("Running with cfv: " + cfv + ", test_Dimension_264"); - pb = ProcessTools.createTestJavaProcessBuilder("-verify", "-cp", ".", classCName); + pb = ProcessTools.createTestJavaProcessBuilder("-Xverify:all", "-cp", ".", classCName); output = new OutputAnalyzer(pb.start()); output.shouldContain("java.lang.ClassFormatError"); output.shouldHaveExitValue(1); diff --git a/test/hotspot/jtreg/runtime/verifier/TraceClassRes.java b/test/hotspot/jtreg/runtime/verifier/TraceClassRes.java index ddb5e68e1d3..e9be98fea17 100644 --- a/test/hotspot/jtreg/runtime/verifier/TraceClassRes.java +++ b/test/hotspot/jtreg/runtime/verifier/TraceClassRes.java @@ -39,7 +39,7 @@ public class TraceClassRes { public static void main(String[] args) throws Exception { ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( - "-Xlog:class+resolve=debug", "-verify", "-Xshare:off", "-version"); + "-Xlog:class+resolve=debug", "-Xverify:all", "-Xshare:off", "-version"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldContain("[class,resolve] java.lang.ClassLoader java.lang.Throwable ClassLoader.java (verification)"); diff --git a/test/hotspot/jtreg/runtime/verifier/stackMapTableTests/StackMapTableTest.java b/test/hotspot/jtreg/runtime/verifier/stackMapTableTests/StackMapTableTest.java index f7f2ca1e881..08ddad6464f 100644 --- a/test/hotspot/jtreg/runtime/verifier/stackMapTableTests/StackMapTableTest.java +++ b/test/hotspot/jtreg/runtime/verifier/stackMapTableTests/StackMapTableTest.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 @@ -28,7 +28,7 @@ * @summary Test that the JVM does not assert when printing a stack map table * containing a stack map with a bad verification type. * @compile badStackMapTable.jcod - * @run main/othervm -verify StackMapTableTest + * @run main/othervm -Xverify:all StackMapTableTest */ public class StackMapTableTest { diff --git a/test/jdk/javax/swing/JFileChooser/6520101/bug6520101.java b/test/jdk/javax/swing/JFileChooser/6520101/bug6520101.java index f6671872ba8..131ccc0e348 100644 --- a/test/jdk/javax/swing/JFileChooser/6520101/bug6520101.java +++ b/test/jdk/javax/swing/JFileChooser/6520101/bug6520101.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -27,7 +27,7 @@ * @bug 6520101 * @summary JFileChooser throws OOM in 1.4.2, 5.0u4 and 1.6.0 * @author Praveen Gupta - * @run main/othervm/timeout=600 -Xmx8m -verify bug6520101 + * @run main/othervm/timeout=600 -Xmx8m -Xverify:all bug6520101 */ import javax.swing.*; diff --git a/test/langtools/tools/javac/VarDeclarationWithAssignment.java b/test/langtools/tools/javac/VarDeclarationWithAssignment.java index 7ee81cbc0e2..171c49274e0 100644 --- a/test/langtools/tools/javac/VarDeclarationWithAssignment.java +++ b/test/langtools/tools/javac/VarDeclarationWithAssignment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -29,7 +29,7 @@ * @author turnidge * * @compile VarDeclarationWithAssignment.java - * @run main/othervm -verify VarDeclarationWithAssignment + * @run main/othervm -Xverify:all VarDeclarationWithAssignment */ public From 53ebcdbd029a1c78f8429574b78cecce70c11af2 Mon Sep 17 00:00:00 2001 From: Serguei Spitsyn Date: Tue, 16 Dec 2025 10:28:27 +0000 Subject: [PATCH 017/390] 8373627: assert(!is_vthread_transition_disabler()) failed: no suspend allowed for vthread transition disablers Reviewed-by: pchilanomate, dholmes --- src/hotspot/share/runtime/mountUnmountDisabler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/runtime/mountUnmountDisabler.cpp b/src/hotspot/share/runtime/mountUnmountDisabler.cpp index 5bf00323f10..261bbfb9c18 100644 --- a/src/hotspot/share/runtime/mountUnmountDisabler.cpp +++ b/src/hotspot/share/runtime/mountUnmountDisabler.cpp @@ -367,7 +367,7 @@ MountUnmountDisabler::enable_transition_for_all() { OrderAccess::release(); MonitorLocker ml(VThreadTransition_lock); - if (exclusive_operation_ongoing()) { + if (_is_exclusive) { set_exclusive_operation_ongoing(false); } dec_active_disablers(); From a61394b1da40cfbb617fec35553da2d3c3e27d37 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev Date: Tue, 16 Dec 2025 13:18:59 +0000 Subject: [PATCH 018/390] 8373789: No PCH release build failure after JDK-8372543 Reviewed-by: tschatzl --- src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp index 400eb8d25ee..95f9fbe6856 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahFreeSet.hpp @@ -29,6 +29,7 @@ #include "gc/shenandoah/shenandoahHeap.hpp" #include "gc/shenandoah/shenandoahHeapRegionSet.hpp" #include "gc/shenandoah/shenandoahSimpleBitMap.hpp" +#include "logging/logStream.hpp" // Each ShenandoahHeapRegion is associated with a ShenandoahFreeSetPartitionId. enum class ShenandoahFreeSetPartitionId : uint8_t { From 89e77512fd44b6a0299ab36db15142e7544899f3 Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Tue, 16 Dec 2025 13:33:02 +0000 Subject: [PATCH 019/390] 8370922: Template Framework Library: Float16 type and operations Reviewed-by: galder, thartmann, bmaillard --- .../jtreg/compiler/igvn/ExpressionFuzzer.java | 39 ++++-- .../library/CodeGenerationDataNameType.java | 22 +++ .../library/Float16Type.java | 62 +++++++++ .../library/Operations.java | 94 +++++++++++-- .../library/PrimitiveType.java | 1 + .../jtreg/compiler/lib/verify/Verify.java | 36 +++++ .../examples/TestExpressions.java | 17 ++- .../verify/tests/TestVerify.java | 4 +- .../verify/tests/TestVerifyFloat16.java | 129 ++++++++++++++++++ 9 files changed, 376 insertions(+), 28 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/lib/template_framework/library/Float16Type.java create mode 100644 test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerifyFloat16.java diff --git a/test/hotspot/jtreg/compiler/igvn/ExpressionFuzzer.java b/test/hotspot/jtreg/compiler/igvn/ExpressionFuzzer.java index 570c59f0da2..875ef57c865 100644 --- a/test/hotspot/jtreg/compiler/igvn/ExpressionFuzzer.java +++ b/test/hotspot/jtreg/compiler/igvn/ExpressionFuzzer.java @@ -23,10 +23,11 @@ /* * @test - * @bug 8359412 + * @bug 8359412 8370922 * @key randomness * @summary Use the template framework library to generate random expressions. * @modules java.base/jdk.internal.misc + * @modules jdk.incubator.vector * @library /test/lib / * @compile ../lib/verify/Verify.java * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:CompileTaskTimeout=10000 compiler.igvn.ExpressionFuzzer @@ -55,6 +56,7 @@ import compiler.lib.template_framework.library.Operations; import compiler.lib.template_framework.library.PrimitiveType; import compiler.lib.template_framework.library.TestFrameworkClass; import static compiler.lib.template_framework.library.CodeGenerationDataNameType.PRIMITIVE_TYPES; +import static compiler.lib.template_framework.library.CodeGenerationDataNameType.SCALAR_NUMERIC_TYPES; // We generate random Expressions from primitive type operators. // @@ -84,10 +86,14 @@ public class ExpressionFuzzer { comp.addJavaSourceCode("compiler.igvn.templated.ExpressionFuzzerInnerTest", generate(comp)); // Compile the source file. - comp.compile(); + comp.compile("--add-modules=jdk.incubator.vector"); // compiler.igvn.templated.InnterTest.main(new String[] {}); - comp.invoke("compiler.igvn.templated.ExpressionFuzzerInnerTest", "main", new Object[] {new String[] {}}); + comp.invoke("compiler.igvn.templated.ExpressionFuzzerInnerTest", "main", new Object[] {new String[] { + "--add-modules=jdk.incubator.vector", + "--add-opens", "jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED", + "--add-opens", "java.base/java.lang=ALL-UNNAMED" + }}); } // Generate a Java source file as String @@ -189,10 +195,10 @@ public class ExpressionFuzzer { case "byte", "short", "char", "int", "long" -> List.of("val", Collections.nCopies(20, integralCmpTemplate.asToken(expression.returnType))); // Float/Double have no range, just return the value: - case "float", "double" -> "val"; + case "float", "double", "Float16" -> "val"; // Check if the boolean constant folded: case "boolean" -> "val, val == true, val == false"; - default -> throw new RuntimeException("should only be primitive types"); + default -> throw new RuntimeException("type not supported yet: " + expression.returnType.name()); } , "};\n", """ @@ -224,7 +230,7 @@ public class ExpressionFuzzer { // Booleans do have an int-range, but restricting it would just make it constant, which // is not very useful: we would like to keep it variable here. We already mix in variable // arguments and constants in the testTemplate. - case "boolean", "float", "double" -> "return v;\n"; + case "boolean", "float", "double", "Float16" -> "return v;\n"; case "byte", "short", "char", "int", "long" -> List.of( // Sometimes constrain the signed range // v = min(max(v, CON1), CON2) @@ -241,7 +247,7 @@ public class ExpressionFuzzer { : List.of(), // FUTURE: we could also constrain the unsigned bounds. "return v;\n"); - default -> throw new RuntimeException("should only be primitive types"); + default -> throw new RuntimeException("type not supported yet: " + type.name()); }, """ } @@ -325,6 +331,7 @@ public class ExpressionFuzzer { // Generate expressions with the primitive types. for (PrimitiveType type : PRIMITIVE_TYPES) { + // Prmitive expressions are most important, so let's create many expressions per output type. for (int i = 0; i < 10; i++) { // The depth determines roughly how many operations are going to be used in the expression. int depth = RANDOM.nextInt(1, 20); @@ -333,6 +340,21 @@ public class ExpressionFuzzer { } } + // Generate expressions with any scalar numeric types. + for (CodeGenerationDataNameType type : SCALAR_NUMERIC_TYPES) { + // The extended set of scalar numeric expressions (incl. special types such as Float16) are relevant + // but don't currently warrant the same number amount of testing time, so we only create 2 cases + // per type. Note: this still produces a lot of expressions, given that we have a lot of output + // types, and even if the output type is "float", we can still use other types in the expression, + // such as "float -> Float16 -> float". We can consider adjusting this arbitrary count in the future. + for (int i = 0; i < 2; i++) { + // The depth determines roughly how many operations are going to be used in the expression. + int depth = RANDOM.nextInt(1, 20); + Expression expression = Expression.nestRandomly(type, Operations.SCALAR_NUMERIC_OPERATIONS, depth); + tests.add(testTemplate.asToken(expression)); + } + } + // Create the test class, which runs all tests. return TestFrameworkClass.render( // package and class name. @@ -341,7 +363,8 @@ public class ExpressionFuzzer { Set.of("compiler.lib.verify.*", "java.util.Random", "jdk.test.lib.Utils", - "compiler.lib.generators.*"), + "compiler.lib.generators.*", + "jdk.incubator.vector.Float16"), // classpath, so the Test VM has access to the compiled class files. comp.getEscapedClassPathOfCompiledClasses(), // The list of tests. diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/library/CodeGenerationDataNameType.java b/test/hotspot/jtreg/compiler/lib/template_framework/library/CodeGenerationDataNameType.java index 56f7afcbaeb..b461e3e857f 100644 --- a/test/hotspot/jtreg/compiler/lib/template_framework/library/CodeGenerationDataNameType.java +++ b/test/hotspot/jtreg/compiler/lib/template_framework/library/CodeGenerationDataNameType.java @@ -100,6 +100,13 @@ public interface CodeGenerationDataNameType extends DataName.Type { */ static PrimitiveType booleans() { return PrimitiveType.BOOLEANS; } + /** + * The Float16 type. + * + * @return The Float16 type. + */ + static CodeGenerationDataNameType float16() { return Float16Type.FLOAT16; } + /** * List of all {@link PrimitiveType}s. */ @@ -154,4 +161,19 @@ public interface CodeGenerationDataNameType extends DataName.Type { floats(), doubles() ); + + /** + * List of all scalar numeric types. + */ + List SCALAR_NUMERIC_TYPES = List.of( + bytes(), + chars(), + shorts(), + ints(), + longs(), + floats(), + doubles(), + booleans(), + float16() + ); } diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/library/Float16Type.java b/test/hotspot/jtreg/compiler/lib/template_framework/library/Float16Type.java new file mode 100644 index 00000000000..e591fe4e045 --- /dev/null +++ b/test/hotspot/jtreg/compiler/lib/template_framework/library/Float16Type.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 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 compiler.lib.template_framework.library; + +import compiler.lib.generators.Generators; +import compiler.lib.generators.Generator; + +import compiler.lib.template_framework.DataName; + +/** + * The {@link Float16Type} models Java's {@link Float16} type. + */ +final class Float16Type implements CodeGenerationDataNameType { + private static final Generator GEN_FLOAT16 = Generators.G.float16s(); + + // We only need one static instance of the class. + static final Float16Type FLOAT16 = new Float16Type(); + + // Private constructor so nobody can create duplicate instances. + private Float16Type() {} + + @Override + public boolean isSubtypeOf(DataName.Type other) { + return other instanceof Float16Type; + } + + @Override + public String name() { + return "Float16"; + } + + @Override + public String toString() { + return name(); + } + + @Override + public Object con() { + return "Float16.shortBitsToFloat16((short)" + GEN_FLOAT16.next() + ")"; + } +} diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/library/Operations.java b/test/hotspot/jtreg/compiler/lib/template_framework/library/Operations.java index 53acf943b20..7d353a8c610 100644 --- a/test/hotspot/jtreg/compiler/lib/template_framework/library/Operations.java +++ b/test/hotspot/jtreg/compiler/lib/template_framework/library/Operations.java @@ -23,9 +23,12 @@ package compiler.lib.template_framework.library; -import java.util.List; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static compiler.lib.template_framework.library.PrimitiveType.BYTES; import static compiler.lib.template_framework.library.PrimitiveType.SHORTS; @@ -35,6 +38,7 @@ import static compiler.lib.template_framework.library.PrimitiveType.LONGS; import static compiler.lib.template_framework.library.PrimitiveType.FLOATS; import static compiler.lib.template_framework.library.PrimitiveType.DOUBLES; import static compiler.lib.template_framework.library.PrimitiveType.BOOLEANS; +import static compiler.lib.template_framework.library.Float16Type.FLOAT16; /** * This class provides various lists of {@link Expression}s, that represent Java operators or library @@ -45,18 +49,39 @@ public final class Operations { // private constructor to avoid instantiation. private Operations() {} + private static Expression.Info WITH_ARITHMETIC_EXCEPTION = new Expression.Info().withExceptions(Set.of("ArithmeticException")); + private static Expression.Info WITH_NONDETERMINISTIC_RESULT = new Expression.Info().withNondeterministicResult(); + + /** * Provides a lits of operations on {@link PrimitiveType}s, such as arithmetic, logical, * and cast operations. */ public static final List PRIMITIVE_OPERATIONS = generatePrimitiveOperations(); + public static final List FLOAT16_OPERATIONS = generateFloat16Operations(); + + public static final List SCALAR_NUMERIC_OPERATIONS = concat( + PRIMITIVE_OPERATIONS, + FLOAT16_OPERATIONS + ); + + @SafeVarargs + private static List concat(List... lists) { + return Arrays.stream(lists) + .flatMap(List::stream) + .collect(Collectors.toList()); + } + + private static void addComparisonOperations(List ops, String operatorName, CodeGenerationDataNameType type) { + for (String mask : List.of("==", "!=", "<", ">", "<=", ">=")) { + ops.add(Expression.make(BOOLEANS, "(" + operatorName + "(", type, ", ", type, ")" + mask + "0)")); + } + } + private static List generatePrimitiveOperations() { List ops = new ArrayList<>(); - Expression.Info withArithmeticException = new Expression.Info().withExceptions(Set.of("ArithmeticException")); - Expression.Info withNondeterministicResult = new Expression.Info().withNondeterministicResult(); - // Cast between all primitive types. Except for Boolean, we cannot cast from and to. CodeGenerationDataNameType.INTEGRAL_AND_FLOATING_TYPES.stream().forEach(src -> { CodeGenerationDataNameType.INTEGRAL_AND_FLOATING_TYPES.stream().forEach(dst -> { @@ -75,8 +100,8 @@ public final class Operations { ops.add(Expression.make(type, "(", type, " + ", type, ")")); ops.add(Expression.make(type, "(", type, " - ", type, ")")); ops.add(Expression.make(type, "(", type, " * ", type, ")")); - ops.add(Expression.make(type, "(", type, " / ", type, ")", withArithmeticException)); - ops.add(Expression.make(type, "(", type, " % ", type, ")", withArithmeticException)); + ops.add(Expression.make(type, "(", type, " / ", type, ")", WITH_ARITHMETIC_EXCEPTION)); + ops.add(Expression.make(type, "(", type, " % ", type, ")", WITH_ARITHMETIC_EXCEPTION)); // Bitwise Operators (non short-circuit) ops.add(Expression.make(type, "(~(", type, "))")); @@ -94,6 +119,8 @@ public final class Operations { ops.add(Expression.make(BOOLEANS, "(", type, " < ", type, ")")); ops.add(Expression.make(BOOLEANS, "(", type, " >= ", type, ")")); ops.add(Expression.make(BOOLEANS, "(", type, " <= ", type, ")")); + addComparisonOperations(ops, type.boxedTypeName() + ".compare", type); + addComparisonOperations(ops, type.boxedTypeName() + ".compareUnsigned", type); // ugt, uge, ule, ult }); CodeGenerationDataNameType.FLOATING_TYPES.stream().forEach(type -> { @@ -112,6 +139,7 @@ public final class Operations { ops.add(Expression.make(BOOLEANS, "(", type, " < ", type, ")")); ops.add(Expression.make(BOOLEANS, "(", type, " >= ", type, ")")); ops.add(Expression.make(BOOLEANS, "(", type, " <= ", type, ")")); + addComparisonOperations(ops, type.boxedTypeName() + ".compare", type); }); // ------------ byte ------------- @@ -152,7 +180,7 @@ public final class Operations { ops.add(Expression.make(INTS, "Integer.compare(", INTS, ", ", INTS, ")")); ops.add(Expression.make(INTS, "Integer.compareUnsigned(", INTS, ", ", INTS, ")")); ops.add(Expression.make(INTS, "Integer.compress(", INTS, ", ", INTS, ")")); - ops.add(Expression.make(INTS, "Integer.divideUnsigned(", INTS, ", ", INTS, ")", withArithmeticException)); + ops.add(Expression.make(INTS, "Integer.divideUnsigned(", INTS, ", ", INTS, ")", WITH_ARITHMETIC_EXCEPTION)); ops.add(Expression.make(INTS, "Integer.expand(", INTS, ", ", INTS, ")")); ops.add(Expression.make(INTS, "Integer.highestOneBit(", INTS, ")")); ops.add(Expression.make(INTS, "Integer.lowestOneBit(", INTS, ")")); @@ -160,7 +188,7 @@ public final class Operations { ops.add(Expression.make(INTS, "Integer.min(", INTS, ", ", INTS, ")")); ops.add(Expression.make(INTS, "Integer.numberOfLeadingZeros(", INTS, ")")); ops.add(Expression.make(INTS, "Integer.numberOfTrailingZeros(", INTS, ")")); - ops.add(Expression.make(INTS, "Integer.remainderUnsigned(", INTS, ", ", INTS, ")", withArithmeticException)); + ops.add(Expression.make(INTS, "Integer.remainderUnsigned(", INTS, ", ", INTS, ")", WITH_ARITHMETIC_EXCEPTION)); ops.add(Expression.make(INTS, "Integer.reverse(", INTS, ")")); ops.add(Expression.make(INTS, "Integer.reverseBytes(", INTS, ")")); ops.add(Expression.make(INTS, "Integer.rotateLeft(", INTS, ", ", INTS, ")")); @@ -178,7 +206,7 @@ public final class Operations { ops.add(Expression.make(INTS, "Long.compare(", LONGS, ", ", LONGS, ")")); ops.add(Expression.make(INTS, "Long.compareUnsigned(", LONGS, ", ", LONGS, ")")); ops.add(Expression.make(LONGS, "Long.compress(", LONGS, ", ", LONGS, ")")); - ops.add(Expression.make(LONGS, "Long.divideUnsigned(", LONGS, ", ", LONGS, ")", withArithmeticException)); + ops.add(Expression.make(LONGS, "Long.divideUnsigned(", LONGS, ", ", LONGS, ")", WITH_ARITHMETIC_EXCEPTION)); ops.add(Expression.make(LONGS, "Long.expand(", LONGS, ", ", LONGS, ")")); ops.add(Expression.make(LONGS, "Long.highestOneBit(", LONGS, ")")); ops.add(Expression.make(LONGS, "Long.lowestOneBit(", LONGS, ")")); @@ -186,7 +214,7 @@ public final class Operations { ops.add(Expression.make(LONGS, "Long.min(", LONGS, ", ", LONGS, ")")); ops.add(Expression.make(INTS, "Long.numberOfLeadingZeros(", LONGS, ")")); ops.add(Expression.make(INTS, "Long.numberOfTrailingZeros(", LONGS, ")")); - ops.add(Expression.make(LONGS, "Long.remainderUnsigned(", LONGS, ", ", LONGS, ")", withArithmeticException)); + ops.add(Expression.make(LONGS, "Long.remainderUnsigned(", LONGS, ", ", LONGS, ")", WITH_ARITHMETIC_EXCEPTION)); ops.add(Expression.make(LONGS, "Long.reverse(", LONGS, ")")); ops.add(Expression.make(LONGS, "Long.reverseBytes(", LONGS, ")")); ops.add(Expression.make(LONGS, "Long.rotateLeft(", LONGS, ", ", INTS, ")")); @@ -201,7 +229,7 @@ public final class Operations { // ------------ Float ------------- ops.add(Expression.make(INTS, "Float.compare(", FLOATS, ", ", FLOATS, ")")); ops.add(Expression.make(INTS, "Float.floatToIntBits(", FLOATS, ")")); - ops.add(Expression.make(INTS, "Float.floatToRawIntBits(", FLOATS, ")", withNondeterministicResult)); + ops.add(Expression.make(INTS, "Float.floatToRawIntBits(", FLOATS, ")", WITH_NONDETERMINISTIC_RESULT)); // Note: there are multiple NaN values with different bit representations. ops.add(Expression.make(FLOATS, "Float.float16ToFloat(", SHORTS, ")")); ops.add(Expression.make(FLOATS, "Float.intBitsToFloat(", INTS, ")")); @@ -220,7 +248,7 @@ public final class Operations { ops.add(Expression.make(INTS, "Double.compare(", DOUBLES, ", ", DOUBLES, ")")); ops.add(Expression.make(LONGS, "Double.doubleToLongBits(", DOUBLES, ")")); // Note: there are multiple NaN values with different bit representations. - ops.add(Expression.make(LONGS, "Double.doubleToRawLongBits(", DOUBLES, ")", withNondeterministicResult)); + ops.add(Expression.make(LONGS, "Double.doubleToRawLongBits(", DOUBLES, ")", WITH_NONDETERMINISTIC_RESULT)); ops.add(Expression.make(DOUBLES, "Double.longBitsToDouble(", LONGS, ")")); ops.add(Expression.make(BOOLEANS, "Double.isFinite(", DOUBLES, ")")); ops.add(Expression.make(BOOLEANS, "Double.isInfinite(", DOUBLES, ")")); @@ -250,4 +278,46 @@ public final class Operations { // Make sure the list is not modifiable. return List.copyOf(ops); } + + private static List generateFloat16Operations() { + List ops = new ArrayList<>(); + + // Casts. + CodeGenerationDataNameType.INTEGRAL_AND_FLOATING_TYPES.stream().forEach(type -> { + if (type == CHARS) { return; } + ops.add(Expression.make(FLOAT16, "Float16.valueOf(", type, ")")); + ops.add(Expression.make(type, "", FLOAT16, "." + type.name() + "Value()")); + }); + + ops.add(Expression.make(FLOAT16, "Float16.abs(", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.add(", FLOAT16, ",", FLOAT16, ")")); + ops.add(Expression.make(INTS, "Float16.compare(", FLOAT16, ",", FLOAT16, ")")); + addComparisonOperations(ops, "Float16.compare", FLOAT16); + ops.add(Expression.make(INTS, "(", FLOAT16, ").compareTo(", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.copySign(", FLOAT16, ",", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.divide(", FLOAT16, ",", FLOAT16, ")")); + ops.add(Expression.make(BOOLEANS, "", FLOAT16, ".equals(", FLOAT16, ")")); + ops.add(Expression.make(SHORTS, "Float16.float16ToRawShortBits(", FLOAT16, ")")); + ops.add(Expression.make(SHORTS, "Float16.float16ToShortBits(", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.fma(", FLOAT16, ",", FLOAT16, ", ", FLOAT16, ")")); + ops.add(Expression.make(INTS, "Float16.getExponent(", FLOAT16, ")")); + ops.add(Expression.make(BOOLEANS, "Float16.isFinite(", FLOAT16, ")")); + ops.add(Expression.make(BOOLEANS, "Float16.isInfinite(", FLOAT16, ")")); + ops.add(Expression.make(BOOLEANS, "Float16.isNaN(", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.max(", FLOAT16, ",", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.min(", FLOAT16, ",", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.multiply(", FLOAT16, ",", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.negate(", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.nextDown(", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.nextUp(", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.scalb(", FLOAT16, ", ", INTS, ")")); + ops.add(Expression.make(FLOAT16, "Float16.shortBitsToFloat16(", SHORTS, ")")); + ops.add(Expression.make(FLOAT16, "Float16.signum(", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.sqrt(", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.subtract(", FLOAT16, ",", FLOAT16, ")")); + ops.add(Expression.make(FLOAT16, "Float16.ulp(", FLOAT16, ")")); + + // Make sure the list is not modifiable. + return List.copyOf(ops); + } } diff --git a/test/hotspot/jtreg/compiler/lib/template_framework/library/PrimitiveType.java b/test/hotspot/jtreg/compiler/lib/template_framework/library/PrimitiveType.java index c0db3d51545..b789da45d44 100644 --- a/test/hotspot/jtreg/compiler/lib/template_framework/library/PrimitiveType.java +++ b/test/hotspot/jtreg/compiler/lib/template_framework/library/PrimitiveType.java @@ -93,6 +93,7 @@ public final class PrimitiveType implements CodeGenerationDataNameType { return name(); } + @Override public Object con() { return switch (kind) { case BYTE -> "(byte)" + GEN_BYTE.next(); diff --git a/test/hotspot/jtreg/compiler/lib/verify/Verify.java b/test/hotspot/jtreg/compiler/lib/verify/Verify.java index 7b5e554b0e3..c79ad2c55a0 100644 --- a/test/hotspot/jtreg/compiler/lib/verify/Verify.java +++ b/test/hotspot/jtreg/compiler/lib/verify/Verify.java @@ -150,6 +150,8 @@ public final class Verify { default -> { if (isVectorAPIClass(ca)) { checkEQForVectorAPIClass(a, b, field, aParent, bParent); + } else if (isFloat16Class(ca)) { + checkEQForFloat16Class(a, b, field, aParent, bParent); } else { checkEQArbitraryClasses(a, b); } @@ -456,6 +458,40 @@ public final class Verify { checkEQdispatch(va, vb, field + ".toArray", aParent, bParent); } + private static boolean isFloat16Class(Class c) { + return c.getName().equals("jdk.incubator.vector.Float16"); + } + + /** + * We do not want to import jdk.incubator.vector.Float16 explicitly, because it would mean we would + * also have to add "--add-modules=jdk.incubator.vector" to the command-line of every test that uses + * the Verify class. So we hack this via reflection. + * + * An additional challenge is the boxing and NaNs, see also isFloatEQ. + */ + private void checkEQForFloat16Class(Object a, Object b, String field, Object aParent, Object bParent) { + Class ca = a.getClass(); + short bitsA; + short bitsB; + try { + Method m = isFloatCheckWithRawBits ? ca.getMethod("float16ToRawShortBits", ca) + : ca.getMethod("float16ToShortBits", ca); + m.setAccessible(true); + bitsA = (short)m.invoke(null, a); + bitsB = (short)m.invoke(null, b); + } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { + throw new RuntimeException("Could not invoke float16ToRawShortBits on " + ca.getName(), e); + } + + if (bitsA != bitsB) { + System.err.println("ERROR: Equality matching failed: value mismatch. check raw: " + isFloatCheckWithRawBits); + System.err.println(" Values: " + a + " vs " + b); + System.err.println(" Bits: " + bitsA + " vs " + bitsB); + print(a, b, field, aParent, bParent); + throw new VerifyException("Value mismatch: " + a + " vs " + b); + } + } + private void checkEQArbitraryClasses(Object a, Object b) { Class c = a.getClass(); while (c != Object.class) { diff --git a/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestExpressions.java b/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestExpressions.java index 6a0a2d3786a..4bec633553b 100644 --- a/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestExpressions.java +++ b/test/hotspot/jtreg/testlibrary_tests/template_framework/examples/TestExpressions.java @@ -23,12 +23,13 @@ /* * @test - * @bug 8359412 + * @bug 8359412 8370922 * @summary Demonstrate the use of Expressions from the Template Library. * @modules java.base/jdk.internal.misc + * @modules jdk.incubator.vector * @library /test/lib / * @compile ../../../compiler/lib/verify/Verify.java - * @run main template_framework.examples.TestExpressions + * @run main ${test.main.class} */ package template_framework.examples; @@ -55,10 +56,14 @@ public class TestExpressions { comp.addJavaSourceCode("p.xyz.InnerTest", generate(comp)); // Compile the source file. - comp.compile(); + comp.compile("--add-modules=jdk.incubator.vector"); // p.xyz.InnterTest.main(new String[] {}); - comp.invoke("p.xyz.InnerTest", "main", new Object[] {new String[] {}}); + comp.invoke("p.xyz.InnerTest", "main", new Object[] {new String[] { + "--add-modules=jdk.incubator.vector", + "--add-opens", "jdk.incubator.vector/jdk.incubator.vector=ALL-UNNAMED", + "--add-opens", "java.base/java.lang=ALL-UNNAMED" + }}); } // Generate a Java source file as String @@ -121,7 +126,7 @@ public class TestExpressions { ); }); - for (Expression operation : Operations.PRIMITIVE_OPERATIONS) { + for (Expression operation : Operations.SCALAR_NUMERIC_OPERATIONS) { tests.add(withConstantsTemplate.asToken(operation)); } @@ -130,7 +135,7 @@ public class TestExpressions { // package and class name. "p.xyz", "InnerTest", // Set of imports. - Set.of("compiler.lib.verify.*"), + Set.of("compiler.lib.verify.*", "jdk.incubator.vector.Float16"), // classpath, so the Test VM has access to the compiled class files. comp.getEscapedClassPathOfCompiledClasses(), // The list of tests. diff --git a/test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerify.java b/test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerify.java index 34cff79dd6e..519331b17fd 100644 --- a/test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerify.java +++ b/test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerify.java @@ -23,10 +23,10 @@ /* * @test - * @summary Test functionality of IntGenerator implementations. + * @summary Test basic functionality of Verify implementations. * @modules java.base/jdk.internal.misc * @library /test/lib / - * @run driver verify.tests.TestVerify + * @run driver ${test.main.class} */ package verify.tests; diff --git a/test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerifyFloat16.java b/test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerifyFloat16.java new file mode 100644 index 00000000000..8d1d763a250 --- /dev/null +++ b/test/hotspot/jtreg/testlibrary_tests/verify/tests/TestVerifyFloat16.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 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. + */ + +/* + * @test + * @key randomness + * @summary Test functionality of Verify implementations for Float16. + * @modules jdk.incubator.vector + * @library /test/lib / + * @run driver ${test.main.class} + */ + +package verify.tests; + +import java.lang.foreign.*; +import java.util.Random; +import jdk.test.lib.Utils; + +import jdk.incubator.vector.Float16; + +import compiler.lib.verify.*; + +public class TestVerifyFloat16 { + private static final Random RANDOM = Utils.getRandomInstance(); + + public static void main(String[] args) { + testArrayFloat16(); + testRawFloat16(); + testFloat16Random(); + } + + public static void testArrayFloat16() { + Float16[] a = new Float16[1000]; + Float16[] b = new Float16[1001]; + Float16[] c = new Float16[1000]; + + Verify.checkEQ(a, a); + Verify.checkEQ(b, b); + Verify.checkEQ(a, c); + Verify.checkEQ(c, a); + + // Size mismatch + checkNE(a, b); + + c[RANDOM.nextInt(c.length)] = Float16.valueOf(1f); + + // Value mismatch + checkNE(a, c); + } + + public static void testRawFloat16() { + Float16 nan1 = Float16.shortBitsToFloat16((short)0xFFFF); + Float16 nan2 = Float16.shortBitsToFloat16((short)0x7FFF); + if (!Float16.isNaN(nan1)) { throw new RuntimeException("must be NaN"); } + if (!Float16.isNaN(nan2)) { throw new RuntimeException("must be NaN"); } + if (Float16.float16ToRawShortBits(nan1) != (short)0xFFFF) { throw new RuntimeException("wrong bits"); } + if (Float16.float16ToRawShortBits(nan2) != (short)0x7FFF) { throw new RuntimeException("wrong bits"); } + + Float16[] arr1 = new Float16[]{nan1}; + Float16[] arr2 = new Float16[]{nan2}; + + Verify.checkEQ(nan1, Float16.NaN); + Verify.checkEQ(nan1, nan1); + Verify.checkEQWithRawBits(nan1, nan1); + Verify.checkEQ(nan1, nan2); + + Verify.checkEQ(arr1, arr1); + Verify.checkEQWithRawBits(arr1, arr1); + Verify.checkEQ(arr1, arr2); + + checkNEWithRawBits(nan1, nan2); + + checkNEWithRawBits(arr1, arr2); + } + + public static void testFloat16Random() { + // Testing all 2^16 * 2^16 = 2^32 would take a bit long, so we randomly sample instead. + for (int i = 0; i < 10_000; i++) { + short bitsA = (short)RANDOM.nextInt(); + short bitsB = (short)RANDOM.nextInt(); + Float16 a = Float16.shortBitsToFloat16(bitsA); + Float16 b = Float16.shortBitsToFloat16(bitsB); + if (bitsA == bitsB) { + Verify.checkEQWithRawBits(a, b); + } else { + checkNEWithRawBits(a, b); + } + if (a.equals(b)) { + Verify.checkEQ(a, b); + } else { + checkNE(a, b); + } + } + } + + public static void checkNE(Object a, Object b) { + try { + Verify.checkEQ(a, b); + throw new RuntimeException("Should have thrown: " + a + " vs " + b); + } catch (VerifyException e) {} + } + + public static void checkNEWithRawBits(Object a, Object b) { + try { + Verify.checkEQWithRawBits(a, b); + throw new RuntimeException("Should have thrown: " + a + " vs " + b); + } catch (VerifyException e) {} + } +} From 76e79dbb3eca5589aae6852c8f55adf0759c714e Mon Sep 17 00:00:00 2001 From: Marc Chevalier Date: Tue, 16 Dec 2025 14:32:23 +0000 Subject: [PATCH 020/390] 8371716: C2: Phi node fails Value()'s verification when speculative types clash Co-authored-by: Roland Westrelin Reviewed-by: roland, epeter --- src/hotspot/share/opto/cfgnode.cpp | 64 ++++++++ src/hotspot/share/opto/cfgnode.hpp | 1 + .../igvn/ClashingSpeculativeTypePhiNode.java | 153 ++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/igvn/ClashingSpeculativeTypePhiNode.java diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp index 07657dd0883..776a2d4c90b 100644 --- a/src/hotspot/share/opto/cfgnode.cpp +++ b/src/hotspot/share/opto/cfgnode.cpp @@ -1351,11 +1351,75 @@ const Type* PhiNode::Value(PhaseGVN* phase) const { } #endif //ASSERT + // In rare cases, during an IGVN call to `PhiNode::Value`, `_type` and `t` have incompatible opinion on speculative type, + // resulting into a too small intersection (such as AnyNull), which is removed in cleanup_speculative. + // From that `ft` has no speculative type (ft->speculative() == nullptr). + // After the end of the current `PhiNode::Value` call, `ft` (that is returned) is being store into `_type` + // (see PhaseIterGVN::transform_old -> raise_bottom_type -> set_type). + // + // It is possible that verification happens immediately after, without any change to the current node, or any of its inputs. + // In the verification invocation of `PhiNode::Value`, `t` would be the same as the IGVN `t` (union of input types, that are unchanged), + // but the new `_type` is the value returned by the IGVN invocation of `PhiNode::Value`, the former `ft`, that has no speculative type. + // Thus, the result of `t->filter_speculative(_type)`, the new `ft`, gets the speculative type of `t`, which is not empty. Since the + // result of the verification invocation of `PhiNode::Value` has some speculative type, it is not the same as the previously returned type + // (that had no speculative type), making verification fail. + // + // In such a case, doing the filtering one time more allows to reach a fixpoint. + if (ft->speculative() == nullptr && t->speculative() != nullptr) { + ft = t->filter_speculative(ft); + } + verify_type_stability(phase, t, ft); + // Deal with conversion problems found in data loops. ft = phase->saturate_and_maybe_push_to_igvn_worklist(this, ft); return ft; } +#ifdef ASSERT +// Makes sure that a newly computed type is stable when filtered against the incoming types. +// Otherwise, we may have IGVN verification failures. See PhiNode::Value, and the second +// filtering (enforcing stability), for details. +void PhiNode::verify_type_stability(const PhaseGVN* const phase, const Type* const union_of_input_types, const Type* const new_type) const { + const Type* doubly_filtered_type = union_of_input_types->filter_speculative(new_type); + if (Type::equals(new_type, doubly_filtered_type)) { + return; + } + + stringStream ss; + + ss.print_cr("At node:"); + this->dump("\n", false, &ss); + + const Node* region = in(Region); + for (uint i = 1; i < req(); ++i) { + ss.print("in(%d): ", i); + if (region->in(i) != nullptr && phase->type(region->in(i)) == Type::CONTROL) { + const Type* ti = phase->type(in(i)); + ti->dump_on(&ss); + } + ss.print_cr(""); + } + + ss.print("t: "); + union_of_input_types->dump_on(&ss); + ss.print_cr(""); + + ss.print("_type: "); + _type->dump_on(&ss); + ss.print_cr(""); + + ss.print("Filter once: "); + new_type->dump_on(&ss); + ss.print_cr(""); + ss.print("Filter twice: "); + doubly_filtered_type->dump_on(&ss); + ss.print_cr(""); + tty->print("%s", ss.base()); + tty->flush(); + assert(false, "computed type would not pass verification"); +} +#endif + // Does this Phi represent a simple well-shaped diamond merge? Return the // index of the true path or 0 otherwise. int PhiNode::is_diamond_phi() const { diff --git a/src/hotspot/share/opto/cfgnode.hpp b/src/hotspot/share/opto/cfgnode.hpp index f3ccf23703f..ef799f4c39a 100644 --- a/src/hotspot/share/opto/cfgnode.hpp +++ b/src/hotspot/share/opto/cfgnode.hpp @@ -182,6 +182,7 @@ class PhiNode : public TypeNode { bool is_split_through_mergemem_terminating() const; + void verify_type_stability(const PhaseGVN* phase, const Type* union_of_input_types, const Type* new_type) const NOT_DEBUG_RETURN; bool wait_for_cast_input_igvn(const PhaseIterGVN* igvn) const; public: diff --git a/test/hotspot/jtreg/compiler/igvn/ClashingSpeculativeTypePhiNode.java b/test/hotspot/jtreg/compiler/igvn/ClashingSpeculativeTypePhiNode.java new file mode 100644 index 00000000000..7d8f9e8d409 --- /dev/null +++ b/test/hotspot/jtreg/compiler/igvn/ClashingSpeculativeTypePhiNode.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2025, Red Hat, Inc. + * Copyright (c) 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. + */ + +/** + * @test + * @bug 8371716 + * @summary Ranges can be proven to be disjoint but not orderable (thanks to unsigned range) + * Comparing such values in such range with != should always be true. + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions + * -XX:-TieredCompilation + * -XX:-UseOnStackReplacement + * -XX:-BackgroundCompilation + * -XX:CompileOnly=${test.main.class}::test1 + * -XX:CompileCommand=quiet + * -XX:TypeProfileLevel=222 + * -XX:+AlwaysIncrementalInline + * -XX:VerifyIterativeGVN=10 + * -XX:CompileCommand=dontinline,${test.main.class}::notInlined1 + * ${test.main.class} + * + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions + * -XX:+UnlockDiagnosticVMOptions + * -XX:-TieredCompilation + * -XX:-UseOnStackReplacement + * -XX:-BackgroundCompilation + * -XX:CompileOnly=${test.main.class}::test2 + * -XX:CompileOnly=${test.main.class}::inlined3 + * -XX:CompileCommand=quiet + * -XX:TypeProfileLevel=200 + * -XX:+AlwaysIncrementalInline + * -XX:VerifyIterativeGVN=10 + * -XX:CompileCommand=dontinline,${test.main.class}::notInlined1 + * -XX:+StressIncrementalInlining + * ${test.main.class} + * + * @run main ${test.main.class} + */ + +package compiler.igvn; + +public class ClashingSpeculativeTypePhiNode { + public static void main(String[] args) { + main1(); + main2(); + } + + // 1st case + + static void main1() { + for (int i = 0; i < 20_000; i++) { + test1(false); // returns null + inlined1(true, true); // returns C1 + inlined2(false); // returns C2 + } + } + + private static Object test1(boolean flag1) { + return inlined1(flag1, false); + // When inlined1 is inlined + // return Phi(flag1, inlined2(flag2), null) + // inlined2 is speculatively returning C1, known from the calls `inlined1(true, true)` in main1 + // Phi node gets speculative type C1 + // When inline2 is inlined + // return Phi[C1](flag1, Phi(false, new C1(), notInlined1()), null) + // => Phi[C1](flag1, notInlined1(), null) + // notInlined1 is speculatively returning C2, known from `inline2(false)` in main1 + // return Phi[C1](flag1, notInlined1()[C2], null) + // Clashing speculative type between Phi's _type (C1) and union of inputs (C2). + } + + private static Object inlined1(boolean flag1, boolean flag2) { + if (flag1) { + return inlined2(flag2); // C1 + } + return null; + } + + private static Object inlined2(boolean flag2) { + if (flag2) { + return new C1(); + } + return notInlined1(); // C2 + } + + private static Object notInlined1() { + return new C2(); + } + + // 2nd case + + static void main2() { + for (int i = 0; i < 20_000; i++) { + inlined3(new C1()); + } + for (int i = 0; i < 20_000; i++) { + test2(true, new C2()); + test2(false, new C2()); + } + } + + + private static Object test2(boolean flag1, Object o) { + o = inlined4(o); + if (flag1) { + return inlined3(o); + } + return null; + // We profile only parameters. Param o is speculated to be C2. + // return Phi(flag1, inline3(inline4(o[C2])), null) + // We inline inline3 + // return Phi(flag1, inline4(o[C2])[C1], null) + // As input of inline3, inline4(o) is speculated to be C1. The Phi has C1 as speculative type in _type + // return Phi[C1](flag1, o[C2], null) + // Since o is speculated to be C2 as parameter of test2, we get a clash. + } + + private static Object inlined3(Object o) { + return o; // C1 + } + + private static Object inlined4(Object o) { + return o; + } + + static class C1 { + + } + + static class C2 { + + } +} From 81e375768837e1ae6c34c1d0a8eff06b4e1d2889 Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Tue, 16 Dec 2025 18:11:37 +0000 Subject: [PATCH 021/390] 8373566: Performance regression with java.text.MessageFormat subformat patterns Reviewed-by: liach, rriggs, naoto --- .../classes/java/text/MessageFormat.java | 69 +++++++++---------- .../java/text/MessageFormatterBench.java | 15 ++++ 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/src/java.base/share/classes/java/text/MessageFormat.java b/src/java.base/share/classes/java/text/MessageFormat.java index 5477d0f881a..1a850ebaa42 100644 --- a/src/java.base/share/classes/java/text/MessageFormat.java +++ b/src/java.base/share/classes/java/text/MessageFormat.java @@ -1713,12 +1713,7 @@ public class MessageFormat extends Format { throw new IllegalArgumentException("unknown format type: " + type); } // Get the style if recognized, otherwise treat style as a SubformatPattern - FormatStyle fStyle; - try { - fStyle = FormatStyle.fromString(style); - } catch (IllegalArgumentException iae) { - fStyle = FormatStyle.SUBFORMATPATTERN; - } + FormatStyle fStyle = FormatStyle.fromString(style); return switch (fType) { case NUMBER -> switch (fStyle) { case DEFAULT -> NumberFormat.getInstance(locale); @@ -1976,41 +1971,43 @@ public class MessageFormat extends Format { } // Corresponding to the FormatStyle pattern + // WARNING: fromString is dependent on ordinal positioning and Enum names. private enum FormatStyle { - DEFAULT(""), - SHORT("short"), - MEDIUM("medium"), - LONG("long"), - FULL("full"), - INTEGER("integer"), - CURRENCY("currency"), - PERCENT("percent"), - COMPACT_SHORT("compact_short"), - COMPACT_LONG("compact_long"), - OR("or"), - UNIT("unit"), - SUBFORMATPATTERN(null); + // Special styles + DEFAULT, + SUBFORMATPATTERN, + // Pre-defined styles + SHORT, + MEDIUM, + LONG, + FULL, + INTEGER, + CURRENCY, + PERCENT, + COMPACT_SHORT, + COMPACT_LONG, + OR, + UNIT; - private final String text; - - // Differs from FormatType in that the text String is - // not guaranteed to match the Enum name, thus a text field is used - FormatStyle(String text) { - this.text = text; - } - - // This method returns a FormatStyle (excluding SUBFORMATPATTERN) - // that matches the passed String. If no FormatStyle is found, - // an IllegalArgumentException is thrown + // Returns a FormatStyle corresponding to the input text. + // DEFAULT is the empty String. + // Pre-defined styles are lower case versions of their enum name + // (but compared case-insensitive for historical compatibility). + // SUBFORMATPATTERN is anything else. private static FormatStyle fromString(String text) { - for (FormatStyle style : values()) { - // Also check trimmed case-insensitive for historical reasons - if (style != FormatStyle.SUBFORMATPATTERN && - text.trim().compareToIgnoreCase(style.text) == 0) { - return style; + var style = text.trim(); + if (style.isEmpty()) { + return FormatStyle.DEFAULT; + } + var styles = values(); + // Match starting at the pre-defined styles -> [SHORT:] + for (int i = SHORT.ordinal(); i < styles.length; i++) { + var fStyle = styles[i]; + if (style.compareToIgnoreCase(fStyle.name()) == 0) { + return fStyle; } } - throw new IllegalArgumentException(); + return FormatStyle.SUBFORMATPATTERN; } } diff --git a/test/micro/org/openjdk/bench/java/text/MessageFormatterBench.java b/test/micro/org/openjdk/bench/java/text/MessageFormatterBench.java index 5d3399cb46d..191634ad299 100644 --- a/test/micro/org/openjdk/bench/java/text/MessageFormatterBench.java +++ b/test/micro/org/openjdk/bench/java/text/MessageFormatterBench.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -51,6 +52,8 @@ import java.util.concurrent.TimeUnit; public class MessageFormatterBench { private Object[][] values; + private String choicePattern; + private String numberPattern; @Setup public void setup() { @@ -60,6 +63,8 @@ public class MessageFormatterBench { new Object[]{Double.valueOf(123.89), "MyDisk3"}, new Object[]{Long.valueOf(1234567), "MyDisk4"}, }; + choicePattern = "{0,choice,0#|1#{1}|2#{1} ({2})}"; + numberPattern = "{0,number,000}"; } private MessageFormat messageFormat = new MessageFormat("There is {0} GB of free space on the {1}.", Locale.ENGLISH); @@ -72,6 +77,16 @@ public class MessageFormatterBench { } } + @Benchmark + public MessageFormat testSubformatChoice() { + return new MessageFormat(choicePattern); + } + + @Benchmark + public MessageFormat testSubformatNumber() { + return new MessageFormat(numberPattern); + } + public static void main(String... args) throws Exception { Options opts = new OptionsBuilder().include(MessageFormatterBench.class.getSimpleName()).shouldDoGC(true).build(); new Runner(opts).run(); From b0b42e7eb14dbe04c9c00e8d1fda139a502f2120 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Tue, 16 Dec 2025 18:19:40 +0000 Subject: [PATCH 022/390] 8373615: Improve HotSpot debug functions findclass() and findmethod Reviewed-by: matsaave, asmehra --- src/hotspot/share/classfile/classPrinter.cpp | 159 ++++++++++++++---- src/hotspot/share/classfile/classPrinter.hpp | 4 +- .../gtest/runtime/test_classPrinter.cpp | 61 ++++++- 3 files changed, 178 insertions(+), 46 deletions(-) diff --git a/src/hotspot/share/classfile/classPrinter.cpp b/src/hotspot/share/classfile/classPrinter.cpp index c4b6a024242..3ed0a5e9840 100644 --- a/src/hotspot/share/classfile/classPrinter.cpp +++ b/src/hotspot/share/classfile/classPrinter.cpp @@ -28,9 +28,10 @@ #include "memory/iterator.hpp" #include "memory/resourceArea.hpp" #include "oops/instanceKlass.hpp" -#include "oops/klass.hpp" +#include "oops/klass.inline.hpp" #include "oops/method.hpp" #include "oops/symbol.hpp" +#include "utilities/growableArray.hpp" #include "utilities/ostream.hpp" class ClassPrinter::KlassPrintClosure : public LockedClassesDo { @@ -42,16 +43,15 @@ class ClassPrinter::KlassPrintClosure : public LockedClassesDo { outputStream* _st; int _num; bool _has_printed_methods; + GrowableArray _klasses; + public: KlassPrintClosure(const char* class_name_pattern, const char* method_name_pattern, const char* method_signature_pattern, bool always_print_class_name, int flags, outputStream* st) - : _class_name_pattern(class_name_pattern), - _method_name_pattern(method_name_pattern), - _method_signature_pattern(method_signature_pattern), - _always_print_class_name(always_print_class_name), + : _always_print_class_name(always_print_class_name), _flags(flags), _st(st), _num(0), _has_printed_methods(false) { if (has_mode(_flags, PRINT_METHOD_HANDLE)) { @@ -66,70 +66,150 @@ public: if (has_mode(_flags, PRINT_BYTECODE)) { _flags |= (PRINT_METHOD_NAME); } + + if (has_mode(_flags, PRINT_CLASS_DETAILS)) { + _always_print_class_name = true; + } + + _class_name_pattern = copy_pattern(class_name_pattern); + _method_name_pattern = copy_pattern(method_name_pattern); + _method_signature_pattern = copy_pattern(method_signature_pattern); + } + + static const char* copy_pattern(const char* pattern) { + if (pattern == nullptr) { + return nullptr; + } + char* copy = ResourceArea::strdup(pattern); + for (char* p = copy; *p; p++) { + if (*p == '.') { + *p = '/'; + } + } + return copy; } virtual void do_klass(Klass* k) { if (!k->is_instance_klass()) { return; } - print_instance_klass(InstanceKlass::cast(k)); + InstanceKlass* ik = InstanceKlass::cast(k); + if (ik->is_loaded() && ik->name()->is_star_match(_class_name_pattern)) { + _klasses.append(ik); + } } + void print() { + _klasses.sort(compare_klasses_alphabetically); + for (int i = 0; i < _klasses.length(); i++) { + print_instance_klass(_klasses.at(i)); + } + } + + static bool match(const char* pattern, Symbol* sym) { return (pattern == nullptr || sym->is_star_match(pattern)); } + static int compare_klasses_alphabetically(InstanceKlass** a, InstanceKlass** b) { + return compare_symbols_alphabetically((*a)->name(), (*b)->name()); + } + + static int compare_methods_alphabetically(const void* a, const void* b) { + Method* ma = *(Method**)a; + Method* mb = *(Method**)b; + int n = compare_symbols_alphabetically(ma->name(), mb->name()); + if (n == 0) { + n = compare_symbols_alphabetically(ma->signature(), mb->signature()); + } + return n; + } + + static int compare_symbols_alphabetically(Symbol* a, Symbol *b) { + if (a == b) { + return 0; + } + if (a != nullptr && b == nullptr) { + return 1; + } + if (a == nullptr && b != nullptr) { + return -1; + } + + return strcmp(a->as_C_string(), b->as_C_string()); + } + void print_klass_name(InstanceKlass* ik) { - _st->print("[%3d] " INTPTR_FORMAT " class %s ", _num++, p2i(ik), ik->name()->as_C_string()); + _st->print("[%3d] " INTPTR_FORMAT " class: %s mirror: " INTPTR_FORMAT " ", _num++, + p2i(ik), ik->name()->as_C_string(), p2i(ik->java_mirror())); ik->class_loader_data()->print_value_on(_st); _st->cr(); } void print_instance_klass(InstanceKlass* ik) { - if (ik->is_loaded() && ik->name()->is_star_match(_class_name_pattern)) { - ResourceMark rm; - if (_has_printed_methods) { - // We have printed some methods in the previous class. - // Print a new line to separate the two classes - _st->cr(); + ResourceMark rm; + if (_has_printed_methods) { + // We have printed some methods in the previous class. + // Print a new line to separate the two classes + _st->cr(); + } + _has_printed_methods = false; + if (_always_print_class_name) { + print_klass_name(ik); + } + + if (has_mode(_flags, ClassPrinter::PRINT_CLASS_DETAILS)) { + _st->print("InstanceKlass: "); + ik->print_on(_st); + oop mirror = ik->java_mirror(); + if (mirror != nullptr) { + _st->print("\nJava mirror oop for %s: ", ik->name()->as_C_string()); + mirror->print_on(_st); } - _has_printed_methods = false; - if (_always_print_class_name) { - print_klass_name(ik); + } + + if (has_mode(_flags, ClassPrinter::PRINT_METHOD_NAME)) { + bool print_codes = has_mode(_flags, ClassPrinter::PRINT_BYTECODE); + int len = ik->methods()->length(); + int num_methods_printed = 0; + + Method** sorted_methods = NEW_RESOURCE_ARRAY(Method*, len); + for (int index = 0; index < len; index++) { + sorted_methods[index] = ik->methods()->at(index); } - if (has_mode(_flags, ClassPrinter::PRINT_METHOD_NAME)) { - bool print_codes = has_mode(_flags, ClassPrinter::PRINT_BYTECODE); - int len = ik->methods()->length(); - int num_methods_printed = 0; + qsort(sorted_methods, len, sizeof(Method*), compare_methods_alphabetically); - for (int index = 0; index < len; index++) { - Method* m = ik->methods()->at(index); - if (match(_method_name_pattern, m->name()) && - match(_method_signature_pattern, m->signature())) { - if (print_codes && num_methods_printed++ > 0) { - _st->cr(); - } - - if (_has_printed_methods == false) { - if (!_always_print_class_name) { - print_klass_name(ik); - } - _has_printed_methods = true; - } - print_method(m); + for (int index = 0; index < len; index++) { + Method* m = sorted_methods[index]; + if (match(_method_name_pattern, m->name()) && + match(_method_signature_pattern, m->signature())) { + if (print_codes && num_methods_printed++ > 0) { + _st->cr(); } + + if (_has_printed_methods == false) { + if (!_always_print_class_name) { + print_klass_name(ik); + } + _has_printed_methods = true; + } + print_method(m); } } } } void print_method(Method* m) { - bool print_codes = has_mode(_flags, ClassPrinter::PRINT_BYTECODE); _st->print_cr(INTPTR_FORMAT " %smethod %s : %s", p2i(m), m->is_static() ? "static " : "", m->name()->as_C_string(), m->signature()->as_C_string()); - if (print_codes) { + + if (has_mode(_flags, ClassPrinter::PRINT_METHOD_DETAILS)) { + m->print_on(_st); + } + + if (has_mode(_flags, ClassPrinter::PRINT_BYTECODE)) { m->print_codes_on(_st, _flags); } } @@ -142,12 +222,16 @@ void ClassPrinter::print_flags_help(outputStream* os) { os->print_cr(" 0x%02x - print the address of bytecodes", PRINT_BYTECODE_ADDR); os->print_cr(" 0x%02x - print info for invokedynamic", PRINT_DYNAMIC); os->print_cr(" 0x%02x - print info for invokehandle", PRINT_METHOD_HANDLE); + os->print_cr(" 0x%02x - print details of the C++ and Java objects that represent classes", PRINT_CLASS_DETAILS); + os->print_cr(" 0x%02x - print details of the C++ objects that represent methods", PRINT_METHOD_DETAILS); os->cr(); } void ClassPrinter::print_classes(const char* class_name_pattern, int flags, outputStream* os) { + ResourceMark rm; KlassPrintClosure closure(class_name_pattern, nullptr, nullptr, true, flags, os); ClassLoaderDataGraph::classes_do(&closure); + closure.print(); } void ClassPrinter::print_methods(const char* class_name_pattern, @@ -174,4 +258,5 @@ void ClassPrinter::print_methods(const char* class_name_pattern, KlassPrintClosure closure(class_name_pattern, method_name_pattern, method_signature_pattern, false, flags | PRINT_METHOD_NAME, os); ClassLoaderDataGraph::classes_do(&closure); + closure.print(); } diff --git a/src/hotspot/share/classfile/classPrinter.hpp b/src/hotspot/share/classfile/classPrinter.hpp index 0fff372c302..470e82ddc0e 100644 --- a/src/hotspot/share/classfile/classPrinter.hpp +++ b/src/hotspot/share/classfile/classPrinter.hpp @@ -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 @@ -52,6 +52,8 @@ public: PRINT_BYTECODE_ADDR = 1 << 2, PRINT_DYNAMIC = 1 << 3, // extra information for invokedynamic (and dynamic constant ...) PRINT_METHOD_HANDLE = 1 << 4, // extra information for invokehandle + PRINT_CLASS_DETAILS = 1 << 5, // print details of the C++ and Java objects that represent classes + PRINT_METHOD_DETAILS = 1 << 6, // print details of the C++ objects that represent methods }; static bool has_mode(int flags, Mode mode) { return (flags & static_cast(mode)) != 0; diff --git a/test/hotspot/gtest/runtime/test_classPrinter.cpp b/test/hotspot/gtest/runtime/test_classPrinter.cpp index b13713d7232..9b6d47f09bc 100644 --- a/test/hotspot/gtest/runtime/test_classPrinter.cpp +++ b/test/hotspot/gtest/runtime/test_classPrinter.cpp @@ -28,6 +28,7 @@ #include "utilities/ostream.hpp" #include "unittest.hpp" +using testing::ContainsRegex; using testing::HasSubstr; TEST_VM(ClassPrinter, print_classes) { @@ -35,13 +36,31 @@ TEST_VM(ClassPrinter, print_classes) { ThreadInVMfromNative invm(THREAD); ResourceMark rm; - stringStream ss; - ClassPrinter::print_classes("java/lang/Object", 0x03, &ss); - const char* output = ss.freeze(); + stringStream s1; + ClassPrinter::print_classes("java/lang/Object", 0x03, &s1); + const char* o1 = s1.freeze(); - ASSERT_THAT(output, HasSubstr("class java/lang/Object loader data:")) << "must find java/lang/Object"; - ASSERT_THAT(output, HasSubstr("method wait : (J)V")) << "must find java/lang/Object::wait"; - ASSERT_THAT(output, HasSubstr("method finalize : ()V\n 0 return")) << "must find java/lang/Object::finalize and disasm"; + ASSERT_THAT(o1, HasSubstr("class: java/lang/Object mirror:")) << "must find java/lang/Object"; + ASSERT_THAT(o1, HasSubstr("method wait : (J)V")) << "must find java/lang/Object::wait"; + ASSERT_THAT(o1, HasSubstr("method finalize : ()V\n 0 return")) << "must find java/lang/Object::finalize and disasm"; + + // "." should also work as separator in class name + stringStream s2; + ClassPrinter::print_classes("java.lang.Object", 0x03, &s2); + const char* o2 = s2.freeze(); + ASSERT_THAT(o2, HasSubstr("class: java/lang/Object mirror:")) << "must find java/lang/Object"; + + // 0x20 is PRINT_CLASS_DETAILS + stringStream s3; + ClassPrinter::print_classes("java.lang.Integer", 0x20, &s3); + const char* o3 = s3.freeze(); + ASSERT_THAT(o3, HasSubstr("class: java/lang/Integer mirror:")) << "must find java/lang/Integer"; + ASSERT_THAT(o3, HasSubstr("InstanceKlass: java.lang.Integer {0x")) << "must print InstanceKlass"; + ASSERT_THAT(o3, HasSubstr("Java mirror oop for java/lang/Integer:")) << "must print mirror oop"; +#if GTEST_USES_POSIX_RE + // Complex regex not available on Windows + ASSERT_THAT(o3, ContainsRegex("public static final 'MIN_VALUE' 'I'.* -2147483648 [(]0x80000000[)]")) << "must print static fields"; +#endif } TEST_VM(ClassPrinter, print_methods) { @@ -52,7 +71,7 @@ TEST_VM(ClassPrinter, print_methods) { stringStream s1; ClassPrinter::print_methods("*ang/Object*", "wait", 0x1, &s1); const char* o1 = s1.freeze(); - ASSERT_THAT(o1, HasSubstr("class java/lang/Object loader data:")) << "must find java/lang/Object"; + ASSERT_THAT(o1, HasSubstr("class: java/lang/Object mirror:")) << "must find java/lang/Object"; ASSERT_THAT(o1, HasSubstr("method wait : (J)V")) << "must find java/lang/Object::wait(long)"; ASSERT_THAT(o1, HasSubstr("method wait : ()V")) << "must find java/lang/Object::wait()"; ASSERT_THAT(o1, Not(HasSubstr("method finalize : ()V"))) << "must not find java/lang/Object::finalize"; @@ -60,8 +79,34 @@ TEST_VM(ClassPrinter, print_methods) { stringStream s2; ClassPrinter::print_methods("j*ang/Object*", "wait:(*J*)V", 0x1, &s2); const char* o2 = s2.freeze(); - ASSERT_THAT(o2, HasSubstr("class java/lang/Object loader data:")) << "must find java/lang/Object"; + ASSERT_THAT(o2, HasSubstr("class: java/lang/Object mirror:")) << "must find java/lang/Object"; ASSERT_THAT(o2, HasSubstr("method wait : (J)V")) << "must find java/lang/Object::wait(long)"; ASSERT_THAT(o2, HasSubstr("method wait : (JI)V")) << "must find java/lang/Object::wait(long,int)"; ASSERT_THAT(o2, Not(HasSubstr("method wait : ()V"))) << "must not find java/lang/Object::wait()"; + + // 0x02 is PRINT_BYTECODE + // 0x04 is PRINT_BYTECODE_ADDRESS + // 0x40 is PRINT_METHOD_DETAILS + stringStream s3; + ClassPrinter::print_methods("java.lang.Object", "wait:()V", 0x46, &s3); + const char* o3 = s3.freeze(); + ASSERT_THAT(o3, HasSubstr("method wait : ()V")) << "must find java/lang/Object::wait()"; + +#ifndef PRODUCT + // PRINT_METHOD_DETAILS -- available only in debug builds + ASSERT_THAT(o3, HasSubstr("{method}")) << "must print Method metadata"; +#if GTEST_USES_POSIX_RE + // Complex regex not available on Windows + ASSERT_THAT(o3, ContainsRegex("method holder:.*'java/lang/Object'")) << "must print Method metadata details"; + ASSERT_THAT(o3, ContainsRegex("name: *'wait'")) << "must print Method metadata details"; +#endif +#endif + +#if GTEST_USES_POSIX_RE + // Bytecodes: we should have at least one 'return' bytecide for Object.wait() + // The print out should look like this: + // 0x000000004adf73ad 5 return + ASSERT_THAT(o3, ContainsRegex("0x[0-9a-f]+ +[0-9]+ +return")) << "must print return bytecode"; +#endif + } From a0dd66f92d7f8400b9800847e36d036315628afb Mon Sep 17 00:00:00 2001 From: Saint Wesonga Date: Tue, 16 Dec 2025 18:36:28 +0000 Subject: [PATCH 023/390] 8373630: r18_tls should not be modified on Windows AArch64 Reviewed-by: pchilanomate, aph --- .../cpu/aarch64/c1_Runtime1_aarch64.cpp | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp index 350b6f68196..449ad4f8a4c 100644 --- a/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c1_Runtime1_aarch64.cpp @@ -310,7 +310,18 @@ static void restore_live_registers(StubAssembler* sasm, bool restore_fpu_registe __ add(sp, sp, 32 * wordSize); } +#ifdef R18_RESERVED + /* + Do not modify r18_tls when restoring registers if it is a reserved register. On Windows, + for example, r18_tls is used to store the pointer to the current thread's TEB (where TLS + variables are stored). Therefore, modifying r18_tls would corrupt the TEB pointer. + */ + __ pop(RegSet::range(r0, r17), sp); + __ ldp(zr, r19, Address(__ post(sp, 2 * wordSize))); + __ pop(RegSet::range(r20, r29), sp); +#else __ pop(RegSet::range(r0, r29), sp); +#endif } static void restore_live_registers_except_r0(StubAssembler* sasm, bool restore_fpu_registers = true) { @@ -323,8 +334,20 @@ static void restore_live_registers_except_r0(StubAssembler* sasm, bool restore_f __ add(sp, sp, 32 * wordSize); } +#ifdef R18_RESERVED + /* + Do not modify r18_tls when restoring registers if it is a reserved register. On Windows, + for example, r18_tls is used to store the pointer to the current thread's TEB (where TLS + variables are stored). Therefore, modifying r18_tls would corrupt the TEB pointer. + */ + __ ldp(zr, r1, Address(__ post(sp, 2 * wordSize))); + __ pop(RegSet::range(r2, r17), sp); + __ ldp(zr, r19, Address(__ post(sp, 2 * wordSize))); + __ pop(RegSet::range(r20, r29), sp); +#else __ ldp(zr, r1, Address(__ post(sp, 16))); __ pop(RegSet::range(r2, r29), sp); +#endif } From 817e3dfde9eaa467ea0dca9b70282e914cdde093 Mon Sep 17 00:00:00 2001 From: Mark Powers Date: Tue, 16 Dec 2025 18:38:11 +0000 Subject: [PATCH 024/390] 8350711: [JMH] test Signatures.RSASSAPSS failed for 2 threads config Reviewed-by: hchao, valeriep --- .../bench/java/security/Signatures.java | 197 ++++++++++++------ 1 file changed, 129 insertions(+), 68 deletions(-) diff --git a/test/micro/org/openjdk/bench/java/security/Signatures.java b/test/micro/org/openjdk/bench/java/security/Signatures.java index 1216e253663..b72a4077045 100644 --- a/test/micro/org/openjdk/bench/java/security/Signatures.java +++ b/test/micro/org/openjdk/bench/java/security/Signatures.java @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (C) 2022, Tencent. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,84 +32,142 @@ import java.util.concurrent.TimeUnit; @BenchmarkMode(Mode.Throughput) @OutputTimeUnit(TimeUnit.SECONDS) -@State(Scope.Thread) @Warmup(iterations = 5, time = 1) @Measurement(iterations = 5, time = 1) @Fork(jvmArgs = {"-Xms1024m", "-Xmx1024m", "-Xmn768m", "-XX:+UseParallelGC"}, value = 3) public class Signatures { - private static Signature signer; - @Param({"64", "512", "2048", "16384"}) - private static int messageLength; - - @Param({"secp256r1", "secp384r1", "secp521r1"}) - private String algorithm; - - private static byte[] message; - - @Setup - public void setup() throws Exception { - message = new byte[messageLength]; - (new Random(System.nanoTime())).nextBytes(message); - - String signName = switch (algorithm) { - case "secp256r1" -> "SHA256withECDSA"; - case "secp384r1" -> "SHA384withECDSA"; - case "secp521r1" -> "SHA512withECDSA"; - default -> throw new RuntimeException(); - }; - - AlgorithmParameters params = - AlgorithmParameters.getInstance("EC", "SunEC"); - params.init(new ECGenParameterSpec(algorithm)); - ECGenParameterSpec ecParams = - params.getParameterSpec(ECGenParameterSpec.class); - - KeyPairGenerator kpg = - KeyPairGenerator.getInstance("EC", "SunEC"); - kpg.initialize(ecParams); - KeyPair kp = kpg.generateKeyPair(); - - signer = Signature.getInstance(signName, "SunEC"); - signer.initSign(kp.getPrivate()); + @State(Scope.Benchmark) + public static class test01 { + @Param({"64", "512", "2048", "16384"}) + private int messageLength; + @Param({"secp256r1", "secp384r1", "secp521r1"}) + private String algorithm; + } + @State(Scope.Benchmark) + public static class test02 { + @Param({"64", "512", "2048", "16384"}) + private int messageLength; + @Param({"Ed25519", "Ed448"}) + private String algorithm; + } + @State(Scope.Benchmark) + public static class test03 { + @Param({"64", "512", "2048", "16384"}) + private int messageLength; + @Param({"SHA256withDSA", "SHA384withDSA", "SHA512withDSA"}) + private String algorithm; + } + @State(Scope.Benchmark) + public static class test04 { + @Param({"64", "512", "2048", "16384"}) + private int messageLength; + @Param({"SHA256withRSA", "SHA384withRSA", "SHA512withRSA"}) + private String algorithm; + } + @State(Scope.Benchmark) + public static class test05 { + @Param({"64", "512", "2048", "16384"}) + private int messageLength; + @Param({"SHA256", "SHA384", "SHA512"}) + private String algorithm; } @Benchmark - public byte[] sign() throws SignatureException { - signer.update(message); - return signer.sign(); + public byte[] ECDSA(s1 state) throws Exception { + state.signer.update(state.message); + return state.signer.sign(); } - public static class EdDSA extends Signatures { - @Param({"Ed25519", "Ed448"}) - private String algorithm; + @Benchmark + public byte[] EdDSA(s2 state) throws Exception { + state.signer.update(state.message); + return state.signer.sign(); + } + + @Benchmark + public byte[] DSA(s3 state) throws Exception { + state.signer.update(state.message); + return state.signer.sign(); + } + + @Benchmark + public byte[] RSA(s4 state) throws Exception { + state.signer.update(state.message); + return state.signer.sign(); + } + + @Benchmark + public byte[] RSASSAPSS(s5 state) throws Exception { + state.signer.update(state.message); + return state.signer.sign(); + } + + @State(Scope.Thread) + public static class s1 { + private Signature signer; + private byte[] message; @Setup - public void setup() throws Exception { - message = new byte[messageLength]; + public void setup(test01 test) throws Exception { + message = new byte[test.messageLength]; (new Random(System.nanoTime())).nextBytes(message); + String signName = switch (test.algorithm) { + case "secp256r1" -> "SHA256withECDSA"; + case "secp384r1" -> "SHA384withECDSA"; + case "secp521r1" -> "SHA512withECDSA"; + default -> throw new RuntimeException(); + }; + + AlgorithmParameters params = + AlgorithmParameters.getInstance("EC", "SunEC"); + params.init(new ECGenParameterSpec(test.algorithm)); + ECGenParameterSpec ecParams = + params.getParameterSpec(ECGenParameterSpec.class); + KeyPairGenerator kpg = - KeyPairGenerator.getInstance(algorithm, "SunEC"); - NamedParameterSpec spec = new NamedParameterSpec(algorithm); - kpg.initialize(spec); + KeyPairGenerator.getInstance("EC", "SunEC"); + kpg.initialize(ecParams); KeyPair kp = kpg.generateKeyPair(); - signer = Signature.getInstance(algorithm, "SunEC"); + signer = Signature.getInstance(signName, "SunEC"); signer.initSign(kp.getPrivate()); } } - public static class DSA extends Signatures { - @Param({"SHA256withDSA", "SHA384withDSA", "SHA512withDSA"}) - private String algorithm; + @State(Scope.Thread) + public static class s2 { + private Signature signer; + private byte[] message; @Setup - public void setup() throws Exception { - message = new byte[messageLength]; + public void setup(test02 test) throws Exception { + message = new byte[test.messageLength]; (new Random(System.nanoTime())).nextBytes(message); - int keyLength = switch (algorithm) { + KeyPairGenerator kpg = + KeyPairGenerator.getInstance(test.algorithm, "SunEC"); + NamedParameterSpec spec = new NamedParameterSpec(test.algorithm); + kpg.initialize(spec); + KeyPair kp = kpg.generateKeyPair(); + + signer = Signature.getInstance(test.algorithm, "SunEC"); + signer.initSign(kp.getPrivate()); + } + } + + @State(Scope.Thread) + public static class s3 { + private Signature signer; + private byte[] message; + + @Setup + public void setup(test03 test) throws Exception { + message = new byte[test.messageLength]; + (new Random(System.nanoTime())).nextBytes(message); + + int keyLength = switch (test.algorithm) { case "SHA256withDSA" -> 2048; case "SHA384withDSA" -> 3072; case "SHA512withDSA" -> 3072; @@ -119,21 +178,22 @@ public class Signatures { kpg.initialize(keyLength); KeyPair kp = kpg.generateKeyPair(); - signer = Signature.getInstance(algorithm); + signer = Signature.getInstance(test.algorithm); signer.initSign(kp.getPrivate()); } } - public static class RSA extends Signatures { - @Param({"SHA256withRSA", "SHA384withRSA", "SHA512withRSA"}) - private String algorithm; + @State(Scope.Thread) + public static class s4 { + private Signature signer; + private byte[] message; @Setup - public void setup() throws Exception { - message = new byte[messageLength]; + public void setup(test04 test) throws Exception { + message = new byte[test.messageLength]; (new Random(System.nanoTime())).nextBytes(message); - int keyLength = switch (algorithm) { + int keyLength = switch (test.algorithm) { case "SHA256withRSA" -> 2048; case "SHA384withRSA" -> 3072; case "SHA512withRSA" -> 4096; @@ -144,28 +204,29 @@ public class Signatures { kpg.initialize(keyLength); KeyPair kp = kpg.generateKeyPair(); - signer = Signature.getInstance(algorithm); + signer = Signature.getInstance(test.algorithm); signer.initSign(kp.getPrivate()); } } - public static class RSASSAPSS extends Signatures { - @Param({"SHA256", "SHA384", "SHA512"}) - private String algorithm; + @State(Scope.Thread) + public static class s5 { + private Signature signer; + private byte[] message; @Setup - public void setup() throws Exception { - message = new byte[messageLength]; + public void setup(test05 test) throws Exception { + message = new byte[test.messageLength]; (new Random(System.nanoTime())).nextBytes(message); - int keyLength = switch (algorithm) { + int keyLength = switch (test.algorithm) { case "SHA256" -> 2048; case "SHA384" -> 3072; case "SHA512" -> 4096; default -> throw new RuntimeException(); }; - PSSParameterSpec spec = switch (algorithm) { + PSSParameterSpec spec = switch (test.algorithm) { case "SHA256" -> new PSSParameterSpec( "SHA-256", "MGF1", From 1e357e9e976bfb0abc9d4e14bfb1572693622af8 Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Tue, 16 Dec 2025 20:23:58 +0000 Subject: [PATCH 025/390] 8373623: Refactor Serialization tests for Records to JUnit Reviewed-by: jlu --- .../records/AbsentStreamValuesTest.java | 48 +++++----- .../records/BadCanonicalCtrTest.java | 30 +++--- .../io/Serializable/records/BadValues.java | 17 ++-- .../Serializable/records/BasicRecordSer.java | 56 ++++++----- .../records/ConstructorAccessTest.java | 19 ++-- .../io/Serializable/records/CycleTest.java | 33 +++---- .../records/DifferentStreamFieldsTest.java | 95 ++++++++++--------- .../records/ProhibitedMethods.java | 46 +++++---- .../Serializable/records/ReadResolveTest.java | 22 +++-- .../Serializable/records/RecordClassTest.java | 36 +++---- .../records/SerialPersistentFieldsTest.java | 28 +++--- .../records/SerialVersionUIDTest.java | 37 ++++---- .../Serializable/records/StreamRefTest.java | 23 ++--- .../records/ThrowingConstructorTest.java | 33 ++++--- .../io/Serializable/records/UnsharedTest.java | 29 +++--- .../records/WriteReplaceTest.java | 24 +++-- .../records/migration/AbstractTest.java | 9 +- .../records/migration/AssignableFromTest.java | 25 ++--- .../records/migration/DefaultValuesTest.java | 23 +++-- .../migration/SuperStreamFieldsTest.java | 34 ++++--- 20 files changed, 367 insertions(+), 300 deletions(-) diff --git a/test/jdk/java/io/Serializable/records/AbsentStreamValuesTest.java b/test/jdk/java/io/Serializable/records/AbsentStreamValuesTest.java index 0f72b9f8f67..02cb35601a9 100644 --- a/test/jdk/java/io/Serializable/records/AbsentStreamValuesTest.java +++ b/test/jdk/java/io/Serializable/records/AbsentStreamValuesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -25,7 +25,7 @@ * @test * @bug 8246774 * @summary Checks that the appropriate default value is given to the canonical ctr - * @run testng AbsentStreamValuesTest + * @run junit AbsentStreamValuesTest */ import java.io.ByteArrayInputStream; @@ -34,16 +34,20 @@ import java.io.DataOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.io.ObjectStreamConstants.*; import static java.lang.System.out; -import static org.testng.Assert.*; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * Basic test to check that default primitive / reference values are presented * to the record's canonical constructor, for fields not in the stream. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class AbsentStreamValuesTest { record R01(boolean x) implements Serializable { } @@ -61,7 +65,6 @@ public class AbsentStreamValuesTest { record R13(R12 x) implements Serializable { } record R14(R13[] x) implements Serializable { } - @DataProvider(name = "recordTypeAndExpectedValue") public Object[][] recordTypeAndExpectedValue() { return new Object[][] { new Object[] { R01.class, false }, @@ -81,7 +84,8 @@ public class AbsentStreamValuesTest { }; } - @Test(dataProvider = "recordTypeAndExpectedValue") + @ParameterizedTest + @MethodSource("recordTypeAndExpectedValue") public void testWithDifferentTypes(Class clazz, Object expectedXValue) throws Exception { @@ -92,7 +96,7 @@ public class AbsentStreamValuesTest { Object obj = deserialize(bytes); out.println("deserialized: " + obj); Object actualXValue = clazz.getDeclaredMethod("x").invoke(obj); - assertEquals(actualXValue, expectedXValue); + assertEquals(expectedXValue, actualXValue); } // --- all together @@ -107,18 +111,18 @@ public class AbsentStreamValuesTest { R15 obj = (R15)deserialize(bytes); out.println("deserialized: " + obj); - assertEquals(obj.a, false); - assertEquals(obj.b, 0); - assertEquals(obj.c, 0); - assertEquals(obj.d, '\u0000'); - assertEquals(obj.e, 0); - assertEquals(obj.f, 0l); - assertEquals(obj.g, 0f); - assertEquals(obj.h, 0d); - assertEquals(obj.i, null); - assertEquals(obj.j, null); - assertEquals(obj.k, null); - assertEquals(obj.l, null); + assertEquals(false, obj.a); + assertEquals(0, obj.b); + assertEquals(0, obj.c); + assertEquals('\u0000', obj.d); + assertEquals(0, obj.e); + assertEquals(0l, obj.f); + assertEquals(0f, obj.g); + assertEquals(0d, obj.h); + assertEquals(null, obj.i); + assertEquals(null, obj.j); + assertEquals(null, obj.k); + assertEquals(null, obj.l); } // --- generic type @@ -132,8 +136,8 @@ public class AbsentStreamValuesTest { R16 obj = (R16)deserialize(bytes); out.println("deserialized: " + obj); - assertEquals(obj.t, null); - assertEquals(obj.u, null); + assertEquals(null, obj.t); + assertEquals(null, obj.u); } // --- infra diff --git a/test/jdk/java/io/Serializable/records/BadCanonicalCtrTest.java b/test/jdk/java/io/Serializable/records/BadCanonicalCtrTest.java index 44959eaea87..528a006fc87 100644 --- a/test/jdk/java/io/Serializable/records/BadCanonicalCtrTest.java +++ b/test/jdk/java/io/Serializable/records/BadCanonicalCtrTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -27,7 +27,7 @@ * @summary InvalidClassException is thrown when the canonical constructor * cannot be found during deserialization. * @library /test/lib - * @run testng BadCanonicalCtrTest + * @run junit BadCanonicalCtrTest */ import java.io.ByteArrayInputStream; @@ -44,22 +44,25 @@ import java.lang.constant.MethodTypeDesc; import jdk.test.lib.compiler.InMemoryJavaCompiler; import jdk.test.lib.ByteCodeLoader; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; import static java.lang.classfile.ClassFile.ACC_PUBLIC; import static java.lang.constant.ConstantDescs.CD_Object; import static java.lang.constant.ConstantDescs.CD_void; import static java.lang.constant.ConstantDescs.INIT_NAME; import static java.lang.constant.ConstantDescs.MTD_void; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.expectThrows; + +import org.junit.jupiter.api.Assertions; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * Checks that an InvalidClassException is thrown when the canonical * constructor cannot be found during deserialization. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class BadCanonicalCtrTest { // ClassLoader for creating instances of the records to test with. @@ -76,7 +79,7 @@ public class BadCanonicalCtrTest { * the initial bytecode for the record classes using javac, then removes or * modifies the generated canonical constructor. */ - @BeforeTest + @BeforeAll public void setup() { { byte[] byteCode = InMemoryJavaCompiler.compile("R1", @@ -133,7 +136,6 @@ public class BadCanonicalCtrTest { return c.getConstructor(long.class).newInstance(l); } - @DataProvider(name = "recordInstances") public Object[][] recordInstances() throws Exception { return new Object[][] { new Object[] { newR1() }, @@ -148,13 +150,14 @@ public class BadCanonicalCtrTest { * Tests that InvalidClassException is thrown when no constructor is * present. */ - @Test(dataProvider = "recordInstances") + @ParameterizedTest + @MethodSource("recordInstances") public void missingConstructorTest(Object objToSerialize) throws Exception { out.println("\n---"); out.println("serializing : " + objToSerialize); byte[] bytes = serialize(objToSerialize); out.println("deserializing"); - InvalidClassException ice = expectThrows(ICE, () -> deserialize(bytes, missingCtrClassLoader)); + InvalidClassException ice = Assertions.assertThrows(ICE, () -> deserialize(bytes, missingCtrClassLoader)); out.println("caught expected ICE: " + ice); assertTrue(ice.getMessage().contains("record canonical constructor not found")); } @@ -164,13 +167,14 @@ public class BadCanonicalCtrTest { * constructor is not present. ( a non-canonical constructor is * present ). */ - @Test(dataProvider = "recordInstances") + @ParameterizedTest + @MethodSource("recordInstances") public void nonCanonicalConstructorTest(Object objToSerialize) throws Exception { out.println("\n---"); out.println("serializing : " + objToSerialize); byte[] bytes = serialize(objToSerialize); out.println("deserializing"); - InvalidClassException ice = expectThrows(ICE, () -> deserialize(bytes, nonCanonicalCtrClassLoader)); + InvalidClassException ice = Assertions.assertThrows(ICE, () -> deserialize(bytes, nonCanonicalCtrClassLoader)); out.println("caught expected ICE: " + ice); assertTrue(ice.getMessage().contains("record canonical constructor not found")); } diff --git a/test/jdk/java/io/Serializable/records/BadValues.java b/test/jdk/java/io/Serializable/records/BadValues.java index 4e3dbaa200f..9d5e0c7be82 100644 --- a/test/jdk/java/io/Serializable/records/BadValues.java +++ b/test/jdk/java/io/Serializable/records/BadValues.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 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 @@ -24,7 +24,7 @@ /* * @test * @summary Basic test for ClassNotFoundException - * @run testng BadValues + * @run junit BadValues */ import java.io.ByteArrayInputStream; @@ -32,10 +32,11 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.ObjectInputStream; -import org.testng.annotations.Test; import static java.io.ObjectStreamConstants.*; import static java.lang.System.out; -import static org.testng.Assert.*; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; /** * Not directly related to records but provokes surrounding code, and ensures @@ -73,7 +74,7 @@ public class BadValues { public void testNotFoundSer() throws Exception { out.println("\n---"); byte[] bytes = byteStreamFor("XxYyZz", 0L, (byte)SC_SERIALIZABLE); - Throwable t = expectThrows(CNFE, () -> deserialize(bytes)); + Throwable t = assertThrows(CNFE, () -> deserialize(bytes)); out.println("caught expected CNFE: " + t); } @@ -81,7 +82,7 @@ public class BadValues { public void testNotFoundSerWr() throws Exception { out.println("\n---"); byte[] bytes = byteStreamFor("XxYyZz", 0L, (byte)(SC_SERIALIZABLE | SC_WRITE_METHOD)); - Throwable t = expectThrows(CNFE, () -> deserialize(bytes)); + Throwable t = assertThrows(CNFE, () -> deserialize(bytes)); out.println("caught expected CNFE: " + t); } @@ -89,7 +90,7 @@ public class BadValues { public void testNotFoundExt() throws Exception { out.println("\n---"); byte[] bytes = byteStreamFor("AaBbCc", 0L, (byte)SC_EXTERNALIZABLE); - Throwable t = expectThrows(CNFE, () -> deserialize(bytes)); + Throwable t = assertThrows(CNFE, () -> deserialize(bytes)); out.println("caught expected CNFE: " + t); } @@ -97,7 +98,7 @@ public class BadValues { public void testNotFoundExtWr() throws Exception { out.println("\n---"); byte[] bytes = byteStreamFor("AaBbCc", 0L, (byte)(SC_SERIALIZABLE | SC_WRITE_METHOD)); - Throwable t = expectThrows(CNFE, () -> deserialize(bytes)); + Throwable t = assertThrows(CNFE, () -> deserialize(bytes)); out.println("caught expected CNFE: " + t); } diff --git a/test/jdk/java/io/Serializable/records/BasicRecordSer.java b/test/jdk/java/io/Serializable/records/BasicRecordSer.java index 94a79e85b38..b05d6bd9550 100644 --- a/test/jdk/java/io/Serializable/records/BasicRecordSer.java +++ b/test/jdk/java/io/Serializable/records/BasicRecordSer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -25,7 +25,7 @@ * @test * @bug 8246774 * @summary Basic test that serializes and deserializes a number of records - * @run testng BasicRecordSer + * @run junit BasicRecordSer */ import java.io.ByteArrayInputStream; @@ -39,19 +39,24 @@ import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.Serializable; import java.math.BigInteger; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.String.format; import static java.lang.System.out; import static java.net.InetAddress.getLoopbackAddress; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.expectThrows; -import static org.testng.Assert.fail; + +import org.junit.jupiter.api.Assertions; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * Basic test that serializes and deserializes a number of simple records. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class BasicRecordSer { // a mix of a few record and non-record classes @@ -101,7 +106,6 @@ public class BasicRecordSer { record Wubble (Wobble wobble, Wibble wibble, String s) implements ThrowingExternalizable { } - @DataProvider(name = "serializable") public Object[][] serializable() { Foo foo = new Foo(23); return new Object[][] { @@ -121,14 +125,20 @@ public class BasicRecordSer { } /** Tests serializing and deserializing a number of records. */ - @Test(dataProvider = "serializable") + @ParameterizedTest + @MethodSource("serializable") public void testSerializable(Object objToSerialize) throws Exception { out.println("\n---"); out.println("serializing : " + objToSerialize); var objDeserialized = serializeDeserialize(objToSerialize); out.println("deserialized: " + objDeserialized); - assertEquals(objToSerialize, objDeserialized); - assertEquals(objDeserialized, objToSerialize); + if (objToSerialize.getClass().isArray()) { + assertArrayEquals((Object[]) objDeserialized, (Object[]) objToSerialize); + assertArrayEquals((Object[]) objToSerialize, (Object[]) objDeserialized); + } else { + assertEquals(objDeserialized, objToSerialize); + assertEquals(objToSerialize, objDeserialized); + } } /** Tests serializing and deserializing of local records. */ @@ -154,8 +164,8 @@ public class BasicRecordSer { out.println("serializing : " + objToSerialize); Foo[] objDeserialized = (Foo[])serializeDeserialize(objToSerialize); out.println("deserialized: " + objDeserialized); - assertEquals(objToSerialize, objDeserialized); - assertEquals(objDeserialized, objToSerialize); + Assertions.assertArrayEquals(objDeserialized, objToSerialize); + Assertions.assertArrayEquals(objToSerialize, objDeserialized); for (Foo f : objDeserialized) assertTrue(objDeserialized[0] == f); @@ -171,8 +181,8 @@ public class BasicRecordSer { out.println("serializing : " + objToSerialize); Wobble[] objDeserialized = (Wobble[])serializeDeserialize(objToSerialize); out.println("deserialized: " + objDeserialized); - assertEquals(objToSerialize, objDeserialized); - assertEquals(objDeserialized, objToSerialize); + Assertions.assertArrayEquals(objDeserialized, objToSerialize); + Assertions.assertArrayEquals(objToSerialize, objDeserialized); for (Wobble w : objDeserialized) { assertTrue(objDeserialized[0] == w); @@ -192,7 +202,6 @@ public class BasicRecordSer { final NotSer notSer = new NotSer(7); } - @DataProvider(name = "notSerializable") public Object[][] notSerializable() { return new Object[][] { new Object[] { new NotSerEmpty() }, @@ -209,11 +218,12 @@ public class BasicRecordSer { static final Class NSE = NotSerializableException.class; /** Tests that non-Serializable record objects throw NotSerializableException. */ - @Test(dataProvider = "notSerializable") + @ParameterizedTest + @MethodSource("notSerializable") public void testNotSerializable(Object objToSerialize) throws Exception { out.println("\n---"); out.println("serializing : " + objToSerialize); - NotSerializableException expected = expectThrows(NSE, () -> serialize(objToSerialize)); + NotSerializableException expected = Assertions.assertThrows(NSE, () -> serialize(objToSerialize)); out.println("caught expected NSE:" + expected); } @@ -235,9 +245,9 @@ public class BasicRecordSer { out.println("serializing : " + objToSerialize); var objDeserialized = serializeDeserialize(objToSerialize); out.println("deserialized: " + objDeserialized); - assertEquals(objToSerialize, objDeserialized); assertEquals(objDeserialized, objToSerialize); - assertEquals(e_ctrInvocationCount, 1); + assertEquals(objToSerialize, objDeserialized); + assertEquals(1, e_ctrInvocationCount); } // --- @@ -258,9 +268,9 @@ public class BasicRecordSer { var objToSerialize = new G(); g_ctrInvocationCount = 0; // reset out.println("serializing : " + objToSerialize); - NotSerializableException expected = expectThrows(NSE, () -> serialize(objToSerialize)); + NotSerializableException expected = Assertions.assertThrows(NSE, () -> serialize(objToSerialize)); out.println("caught expected NSE:" + expected); - assertEquals(g_ctrInvocationCount, 0); + assertEquals(0, g_ctrInvocationCount); } // --- infra diff --git a/test/jdk/java/io/Serializable/records/ConstructorAccessTest.java b/test/jdk/java/io/Serializable/records/ConstructorAccessTest.java index 5057fcc7cbb..c84c7c9519e 100644 --- a/test/jdk/java/io/Serializable/records/ConstructorAccessTest.java +++ b/test/jdk/java/io/Serializable/records/ConstructorAccessTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -26,7 +26,7 @@ * @bug 8246774 * @summary Ensures that the serialization implementation can *always* access * the record constructor - * @run testng ConstructorAccessTest + * @run junit ConstructorAccessTest */ import java.io.ByteArrayInputStream; @@ -38,16 +38,19 @@ import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.Externalizable; import java.io.Serializable; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.fail; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /*implicit*/ record Aux1 (int x) implements Serializable { } /*implicit*/ record Aux2 (int x) implements Serializable { } +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class ConstructorAccessTest { public record A (int x) implements Serializable { } @@ -75,7 +78,6 @@ public class ConstructorAccessTest { private record H (double d) implements ThrowingExternalizable { } - @DataProvider(name = "recordInstances") public Object[][] recordInstances() { return new Object[][] { new Object[] { new A(34) }, @@ -91,7 +93,8 @@ public class ConstructorAccessTest { }; } - @Test(dataProvider = "recordInstances") + @ParameterizedTest + @MethodSource("recordInstances") public void roundTrip(Object objToSerialize) throws Exception { out.println("\n---"); out.println("serializing : " + objToSerialize); diff --git a/test/jdk/java/io/Serializable/records/CycleTest.java b/test/jdk/java/io/Serializable/records/CycleTest.java index 53d1247e808..7b323a78af8 100644 --- a/test/jdk/java/io/Serializable/records/CycleTest.java +++ b/test/jdk/java/io/Serializable/records/CycleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -25,7 +25,7 @@ * @test * @bug 8246774 * @summary Ensures basic behavior of cycles from record components - * @run testng CycleTest + * @run junit CycleTest */ import java.io.ByteArrayInputStream; @@ -34,10 +34,11 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; -import org.testng.annotations.Test; import static java.lang.System.out; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; public class CycleTest { @@ -61,10 +62,10 @@ public class CycleTest { out.println("serializing : " + r); R deserializedObj = serializeDeserialize(r); out.println("deserialized: " + deserializedObj); - assertEquals(deserializedObj.x(), 1); // sanity - assertEquals(deserializedObj.y(), 2); // sanity + assertEquals(1, deserializedObj.x()); // sanity + assertEquals(2, deserializedObj.y()); // sanity assertTrue(deserializedObj.c() instanceof C); // sanity - assertEquals(deserializedObj.c().obj, null); // cycle, expect null + assertEquals(null, deserializedObj.c().obj); // cycle, expect null } /** @@ -84,8 +85,8 @@ public class CycleTest { out.println("deserialized: " + deserializedObj); assertTrue(deserializedObj instanceof C); // sanity assertTrue(deserializedObj.obj != null); // expect non-null, r - assertEquals(((R)deserializedObj.obj).x(), 3); // sanity - assertEquals(((R)deserializedObj.obj).y(), 4); // sanity + assertEquals(3, ((R)deserializedObj.obj).x()); // sanity + assertEquals(4, ((R)deserializedObj.obj).y()); // sanity } record R2 (int x, int y, C c1, C c2) implements Serializable { } @@ -105,8 +106,8 @@ public class CycleTest { out.println("serializing : " + r); R2 deserializedObj = serializeDeserialize(r); out.println("deserialized: " + deserializedObj); - assertEquals(deserializedObj.x(), 5); // sanity - assertEquals(deserializedObj.y(), 6); // sanity + assertEquals(5, deserializedObj.x()); // sanity + assertEquals(6, deserializedObj.y()); // sanity c1 = deserializedObj.c1(); c2 = deserializedObj.c2(); @@ -132,11 +133,11 @@ public class CycleTest { R3 deserializedObj = serializeDeserialize(r3); out.println("deserialized: " + deserializedObj); assertTrue(deserializedObj.r() != null); - assertEquals(deserializedObj.l(), 9); // sanity - assertEquals(deserializedObj.r().x(), 7); // sanity - assertEquals(deserializedObj.r().y(), 8); // sanity + assertEquals(9, deserializedObj.l()); // sanity + assertEquals(7, deserializedObj.r().x()); // sanity + assertEquals(8, deserializedObj.r().y()); // sanity assertTrue(deserializedObj.r().c() instanceof C); // sanity - assertEquals(deserializedObj.r().c().obj, null); // cycle, expect null + assertEquals(null, deserializedObj.r().c().obj); // cycle, expect null } // --- infra diff --git a/test/jdk/java/io/Serializable/records/DifferentStreamFieldsTest.java b/test/jdk/java/io/Serializable/records/DifferentStreamFieldsTest.java index 02175c53bb8..2960cc4f723 100644 --- a/test/jdk/java/io/Serializable/records/DifferentStreamFieldsTest.java +++ b/test/jdk/java/io/Serializable/records/DifferentStreamFieldsTest.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 @@ -26,7 +26,7 @@ * @bug 8246774 * @summary Checks that the appropriate value is given to the canonical ctr * @library /test/lib - * @run testng DifferentStreamFieldsTest + * @run junit DifferentStreamFieldsTest */ import java.io.ByteArrayInputStream; @@ -38,14 +38,19 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import jdk.test.lib.serial.SerialObjectBuilder; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; -import static org.testng.Assert.assertEquals; + +import org.junit.jupiter.api.Assertions; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * Checks that the appropriate value is given to the canonical ctr. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class DifferentStreamFieldsTest { record R01(boolean x) implements Serializable {} @@ -76,7 +81,6 @@ public class DifferentStreamFieldsTest { record R14(R13[]x) implements Serializable {} - @DataProvider(name = "recordTypeAndExpectedValue") public Object[][] recordTypeAndExpectedValue() { return new Object[][]{ new Object[]{R01.class, false}, @@ -96,7 +100,8 @@ public class DifferentStreamFieldsTest { }; } - @Test(dataProvider = "recordTypeAndExpectedValue") + @ParameterizedTest + @MethodSource("recordTypeAndExpectedValue") public void testWithDifferentTypes(Class clazz, Object expectedXValue) throws Exception { out.println("\n---"); @@ -108,7 +113,7 @@ public class DifferentStreamFieldsTest { Object obj = deserialize(bytes); out.println("deserialized: " + obj); Object actualXValue = clazz.getDeclaredMethod("x").invoke(obj); - assertEquals(actualXValue, expectedXValue); + assertEquals(expectedXValue, actualXValue); bytes = SerialObjectBuilder .newBuilder(clazz.getName()) @@ -118,7 +123,7 @@ public class DifferentStreamFieldsTest { obj = deserialize(bytes); out.println("deserialized: " + obj); actualXValue = clazz.getDeclaredMethod("x").invoke(obj); - assertEquals(actualXValue, expectedXValue); + assertEquals(expectedXValue, actualXValue); } // --- all together @@ -137,18 +142,18 @@ public class DifferentStreamFieldsTest { R15 obj = deserialize(bytes); out.println("deserialized: " + obj); - assertEquals(obj.a, false); - assertEquals(obj.b, 0); - assertEquals(obj.c, 0); - assertEquals(obj.d, '\u0000'); - assertEquals(obj.e, 0); - assertEquals(obj.f, 0l); - assertEquals(obj.g, 0f); - assertEquals(obj.h, 0d); - assertEquals(obj.i, null); - assertEquals(obj.j, null); - assertEquals(obj.k, null); - assertEquals(obj.l, null); + assertEquals(false, obj.a); + assertEquals(0, obj.b); + assertEquals(0, obj.c); + assertEquals('\u0000', obj.d); + assertEquals(0, obj.e); + assertEquals(0l, obj.f); + assertEquals(0f, obj.g); + assertEquals(0d, obj.h); + assertEquals(null, obj.i); + assertEquals(null, obj.j); + assertEquals(null, obj.k); + assertEquals(null, obj.l); } @Test @@ -166,9 +171,9 @@ public class DifferentStreamFieldsTest { .build(); var deser1 = deserialize(OOSBytes); - assertEquals(deser1, r); + assertEquals(r, deser1); var deser2 = deserialize(builderBytes); - assertEquals(deser2, deser1); + assertEquals(deser1, deser2); } { record R(int x, int y) implements Serializable {} @@ -176,7 +181,7 @@ public class DifferentStreamFieldsTest { var r = new R(7, 8); byte[] OOSBytes = serialize(r); var deser1 = deserialize(OOSBytes); - assertEquals(deser1, r); + assertEquals(r, deser1); byte[] builderBytes = SerialObjectBuilder .newBuilder(R.class.getName()) @@ -185,7 +190,7 @@ public class DifferentStreamFieldsTest { .build(); var deser2 = deserialize(builderBytes); - assertEquals(deser2, deser1); + assertEquals(deser1, deser2); builderBytes = SerialObjectBuilder .newBuilder(R.class.getName()) @@ -193,7 +198,7 @@ public class DifferentStreamFieldsTest { .addPrimitiveField("x", int.class, 7) .build(); deser2 = deserialize(builderBytes); - assertEquals(deser2, deser1); + assertEquals(deser1, deser2); builderBytes = SerialObjectBuilder .newBuilder(R.class.getName()) @@ -203,12 +208,12 @@ public class DifferentStreamFieldsTest { .addPrimitiveField("z", int.class, 9) // additional fields .build(); deser2 = deserialize(builderBytes); - assertEquals(deser2, deser1); + assertEquals(deser1, deser2); r = new R(0, 0); OOSBytes = serialize(r); deser1 = deserialize(OOSBytes); - assertEquals(deser1, r); + assertEquals(r, deser1); builderBytes = SerialObjectBuilder .newBuilder(R.class.getName()) @@ -216,13 +221,13 @@ public class DifferentStreamFieldsTest { .addPrimitiveField("x", int.class, 0) .build(); deser2 = deserialize(builderBytes); - assertEquals(deser2, deser1); + assertEquals(deser1, deser2); builderBytes = SerialObjectBuilder .newBuilder(R.class.getName()) // no field values .build(); deser2 = deserialize(builderBytes); - assertEquals(deser2, deser1); + assertEquals(deser1, deser2); } } @@ -234,7 +239,7 @@ public class DifferentStreamFieldsTest { var r = new Str("Hello", "World!"); var deser1 = deserialize(serialize(r)); - assertEquals(deser1, r); + assertEquals(r, deser1); byte[] builderBytes = SerialObjectBuilder .newBuilder(Str.class.getName()) @@ -243,7 +248,7 @@ public class DifferentStreamFieldsTest { .build(); var deser2 = deserialize(builderBytes); - assertEquals(deser2, deser1); + assertEquals(deser1, deser2); builderBytes = SerialObjectBuilder .newBuilder(Str.class.getName()) @@ -254,7 +259,7 @@ public class DifferentStreamFieldsTest { .build(); var deser3 = deserialize(builderBytes); - assertEquals(deser3, deser1); + assertEquals(deser1, deser3); } @Test @@ -264,8 +269,8 @@ public class DifferentStreamFieldsTest { record IntArray(int[]ints, long[]longs) implements Serializable {} IntArray r = new IntArray(new int[]{5, 4, 3, 2, 1}, new long[]{9L}); IntArray deser1 = deserialize(serialize(r)); - assertEquals(deser1.ints(), r.ints()); - assertEquals(deser1.longs(), r.longs()); + Assertions.assertArrayEquals(r.ints(), deser1.ints()); + Assertions.assertArrayEquals(r.longs(), deser1.longs()); byte[] builderBytes = SerialObjectBuilder .newBuilder(IntArray.class.getName()) @@ -274,14 +279,14 @@ public class DifferentStreamFieldsTest { .build(); IntArray deser2 = deserialize(builderBytes); - assertEquals(deser2.ints(), deser1.ints()); - assertEquals(deser2.longs(), deser1.longs()); + Assertions.assertArrayEquals(deser1.ints(), deser2.ints()); + Assertions.assertArrayEquals(deser1.longs(), deser2.longs()); } { record StrArray(String[]stringArray) implements Serializable {} StrArray r = new StrArray(new String[]{"foo", "bar"}); StrArray deser1 = deserialize(serialize(r)); - assertEquals(deser1.stringArray(), r.stringArray()); + Assertions.assertArrayEquals(r.stringArray(), deser1.stringArray()); byte[] builderBytes = SerialObjectBuilder .newBuilder(StrArray.class.getName()) @@ -289,7 +294,7 @@ public class DifferentStreamFieldsTest { .build(); StrArray deser2 = deserialize(builderBytes); - assertEquals(deser2.stringArray(), deser1.stringArray()); + Assertions.assertArrayEquals(deser1.stringArray(), deser2.stringArray()); } } @@ -302,7 +307,7 @@ public class DifferentStreamFieldsTest { var r = new NumberHolder(123); var deser1 = deserialize(serialize(r)); - assertEquals(deser1, r); + assertEquals(r, deser1); byte[] builderBytes = SerialObjectBuilder .newBuilder(NumberHolder.class.getName()) @@ -310,7 +315,7 @@ public class DifferentStreamFieldsTest { .build(); var deser2 = deserialize(builderBytes); - assertEquals(deser2, deser1); + assertEquals(deser1, deser2); } { @@ -318,7 +323,7 @@ public class DifferentStreamFieldsTest { var r = new IntegerHolder(123); var deser1 = deserialize(serialize(r)); - assertEquals(deser1, r); + assertEquals(r, deser1); byte[] builderBytes = SerialObjectBuilder .newBuilder(IntegerHolder.class.getName()) @@ -326,7 +331,7 @@ public class DifferentStreamFieldsTest { .build(); var deser2 = deserialize(builderBytes); - assertEquals(deser2, deser1); + assertEquals(deser1, deser2); } } @@ -338,7 +343,7 @@ public class DifferentStreamFieldsTest { var r = new StringHolder("123"); var deser1 = deserialize(serialize(r)); - assertEquals(deser1, r); + assertEquals(r, deser1); byte[] builderBytes = SerialObjectBuilder .newBuilder(StringHolder.class.getName()) @@ -362,7 +367,7 @@ public class DifferentStreamFieldsTest { var r = new IntHolder(123); var deser1 = deserialize(serialize(r)); - assertEquals(deser1, r); + assertEquals(r, deser1); byte[] builderBytes = SerialObjectBuilder .newBuilder(IntHolder.class.getName()) diff --git a/test/jdk/java/io/Serializable/records/ProhibitedMethods.java b/test/jdk/java/io/Serializable/records/ProhibitedMethods.java index d744e9ddbad..815fbacc0f7 100644 --- a/test/jdk/java/io/Serializable/records/ProhibitedMethods.java +++ b/test/jdk/java/io/Serializable/records/ProhibitedMethods.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -26,7 +26,7 @@ * @bug 8246774 * @summary Basic tests for prohibited magic serialization methods * @library /test/lib - * @run testng ProhibitedMethods + * @run junit ProhibitedMethods */ import java.io.ByteArrayInputStream; @@ -49,24 +49,28 @@ import java.math.BigDecimal; import jdk.test.lib.compiler.InMemoryJavaCompiler; import jdk.test.lib.ByteCodeLoader; -import org.testng.Assert; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; import static java.lang.classfile.ClassFile.ACC_PRIVATE; +import static java.lang.constant.ConstantDescs.CD_Object; import static java.lang.constant.ConstantDescs.CD_String; import static java.lang.constant.ConstantDescs.CD_void; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.expectThrows; -import static org.testng.Assert.fail; + +import org.junit.jupiter.api.Assertions; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * Checks that the various prohibited Serialization magic methods, and * Externalizable methods, are not invoked ( effectively ignored ) for * record objects. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class ProhibitedMethods { public interface ThrowingExternalizable extends Externalizable { @@ -100,7 +104,7 @@ public class ProhibitedMethods { * fail("readObjectNoData should not be invoked"); } * } */ - @BeforeTest + @BeforeAll public void setup() { { byte[] byteCode = InMemoryJavaCompiler.compile("Foo", @@ -165,7 +169,6 @@ public class ProhibitedMethods { } } - @DataProvider(name = "recordInstances") public Object[][] recordInstances() { return new Object[][] { new Object[] { newFoo() }, @@ -177,7 +180,8 @@ public class ProhibitedMethods { }; } - @Test(dataProvider = "recordInstances") + @ParameterizedTest + @MethodSource("recordInstances") public void roundTrip(Object objToSerialize) throws Exception { out.println("\n---"); out.println("serializing : " + objToSerialize); @@ -245,8 +249,8 @@ public class ProhibitedMethods { return cf.transformClass(cf.parse(classBytes), ClassTransform.endHandler(clb -> { clb.withMethodBody(name, desc, ACC_PRIVATE, cob -> { cob.loadConstant(name + " should not be invoked"); - cob.invokestatic(Assert.class.describeConstable().orElseThrow(), "fail", - MethodTypeDesc.of(CD_void, CD_String)); + cob.invokestatic(Assertions.class.describeConstable().orElseThrow(), "fail", + MethodTypeDesc.of(CD_Object, CD_String)); cob.return_(); }); })); @@ -266,37 +270,37 @@ public class ProhibitedMethods { Method m = obj.getClass().getDeclaredMethod("writeObject", ObjectOutputStream.class); assertTrue((m.getModifiers() & Modifier.PRIVATE) != 0); m.setAccessible(true); - ReflectiveOperationException t = expectThrows(ROE, () -> + ReflectiveOperationException t = Assertions.assertThrows(ROE, () -> m.invoke(obj, new ObjectOutputStream(OutputStream.nullOutputStream()))); Throwable assertionError = t.getCause(); out.println("caught expected AssertionError: " + assertionError); assertTrue(assertionError instanceof AssertionError, "Expected AssertionError, got:" + assertionError); - assertEquals(assertionError.getMessage(), "writeObject should not be invoked"); + assertEquals("writeObject should not be invoked", assertionError.getMessage()); } { // readObject Method m = obj.getClass().getDeclaredMethod("readObject", ObjectInputStream.class); assertTrue((m.getModifiers() & Modifier.PRIVATE) != 0); m.setAccessible(true); - ReflectiveOperationException t = expectThrows(ROE, () -> + ReflectiveOperationException t = Assertions.assertThrows(ROE, () -> m.invoke(obj, new ObjectInputStream() { })); Throwable assertionError = t.getCause(); out.println("caught expected AssertionError: " + assertionError); assertTrue(assertionError instanceof AssertionError, "Expected AssertionError, got:" + assertionError); - assertEquals(assertionError.getMessage(), "readObject should not be invoked"); + assertEquals("readObject should not be invoked", assertionError.getMessage()); } { // readObjectNoData Method m = obj.getClass().getDeclaredMethod("readObjectNoData"); assertTrue((m.getModifiers() & Modifier.PRIVATE) != 0); m.setAccessible(true); - ReflectiveOperationException t = expectThrows(ROE, () -> m.invoke(obj)); + ReflectiveOperationException t = Assertions.assertThrows(ROE, () -> m.invoke(obj)); Throwable assertionError = t.getCause(); out.println("caught expected AssertionError: " + assertionError); assertTrue(assertionError instanceof AssertionError, "Expected AssertionError, got:" + assertionError); - assertEquals(assertionError.getMessage(), "readObjectNoData should not be invoked"); + assertEquals("readObjectNoData should not be invoked", assertionError.getMessage()); } } } diff --git a/test/jdk/java/io/Serializable/records/ReadResolveTest.java b/test/jdk/java/io/Serializable/records/ReadResolveTest.java index 04de34781f9..2eb77bbf663 100644 --- a/test/jdk/java/io/Serializable/records/ReadResolveTest.java +++ b/test/jdk/java/io/Serializable/records/ReadResolveTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -25,7 +25,7 @@ * @test * @bug 8246774 * @summary Basic tests for readResolve - * @run testng ReadResolveTest + * @run junit ReadResolveTest */ import java.io.ByteArrayInputStream; @@ -35,15 +35,19 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serial; import java.io.Serializable; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.String.format; import static java.lang.System.out; -import static org.testng.Assert.assertEquals; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * Tests records being used as a serial proxy. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class ReadResolveTest { static class C1 implements Serializable { @@ -94,7 +98,6 @@ public class ReadResolveTest { } } - @DataProvider(name = "objectsToSerialize") public Object[][] objectsToSerialize() { return new Object[][] { new Object[] { new C1(3,4) }, @@ -103,13 +106,14 @@ public class ReadResolveTest { }; } - @Test(dataProvider = "objectsToSerialize") + @ParameterizedTest + @MethodSource("objectsToSerialize") public void testSerialize(Object objectToSerialize) throws Exception { out.println("\n---"); out.println("serializing : " + objectToSerialize); Object deserializedObj = serializeDeserialize(objectToSerialize); out.println("deserialized: " + deserializedObj); - assertEquals(deserializedObj, objectToSerialize); + assertEquals(objectToSerialize, deserializedObj); } // -- null replacement @@ -128,7 +132,7 @@ public class ReadResolveTest { out.println("serializing : " + objectToSerialize); Object deserializedObj = serializeDeserialize(objectToSerialize); out.println("deserialized: " + deserializedObj); - assertEquals(deserializedObj, null); + assertEquals(null, deserializedObj); } // --- infra diff --git a/test/jdk/java/io/Serializable/records/RecordClassTest.java b/test/jdk/java/io/Serializable/records/RecordClassTest.java index 401512056e6..ba920ce92e5 100644 --- a/test/jdk/java/io/Serializable/records/RecordClassTest.java +++ b/test/jdk/java/io/Serializable/records/RecordClassTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -25,7 +25,7 @@ * @test * @bug 8246774 * @summary Basic tests for serializing and deserializing record classes - * @run testng RecordClassTest + * @run junit RecordClassTest */ import java.io.ByteArrayInputStream; @@ -38,15 +38,18 @@ import java.io.ObjectOutput; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; import java.io.Serializable; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.fail; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.fail; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * Serializes and deserializes record classes. Ensures that the SUID is 0. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class RecordClassTest { record Foo () implements Serializable { } @@ -74,7 +77,6 @@ public class RecordClassTest { record Wubble (Wobble wobble, Wibble wibble, String s) implements ThrowingExternalizable { } - @DataProvider(name = "recordClasses") public Object[][] recordClasses() { return new Object[][] { new Object[] { Foo.class , 0L }, @@ -87,7 +89,8 @@ public class RecordClassTest { } /** Tests that the serialized and deserialized instances are equal. */ - @Test(dataProvider = "recordClasses") + @ParameterizedTest + @MethodSource("recordClasses") public void testClassSerialization(Class recordClass, long unused) throws Exception { @@ -95,21 +98,22 @@ public class RecordClassTest { out.println("serializing : " + recordClass); var deserializedClass = serializeDeserialize(recordClass); out.println("deserialized: " + deserializedClass); - assertEquals(recordClass, deserializedClass); assertEquals(deserializedClass, recordClass); + assertEquals(recordClass, deserializedClass); } /** Tests that the SUID is always 0 unless explicitly declared. */ - @Test(dataProvider = "recordClasses") + @ParameterizedTest + @MethodSource("recordClasses") public void testSerialVersionUID(Class recordClass, long expectedUID) { out.println("\n---"); ObjectStreamClass osc = ObjectStreamClass.lookup(recordClass); out.println("ObjectStreamClass::lookup : " + osc); - assertEquals(osc.getSerialVersionUID(), expectedUID); + assertEquals(expectedUID, osc.getSerialVersionUID()); osc = ObjectStreamClass.lookupAny(recordClass); out.println("ObjectStreamClass::lookupAny: " + osc); - assertEquals(osc.getSerialVersionUID(), expectedUID); + assertEquals(expectedUID, osc.getSerialVersionUID()); } // --- not Serializable @@ -120,7 +124,6 @@ public class RecordClassTest { record NotSerializable3(T t) { } - @DataProvider(name = "notSerRecordClasses") public Object[][] notSerRecordClasses() { return new Object[][] { new Object[] { NotSerializable1.class }, @@ -130,16 +133,17 @@ public class RecordClassTest { } /** Tests that the generated SUID is always 0 for all non-Serializable record classes. */ - @Test(dataProvider = "notSerRecordClasses") + @ParameterizedTest + @MethodSource("notSerRecordClasses") public void testSerialVersionUIDNonSer(Class recordClass) { out.println("\n---"); ObjectStreamClass osc = ObjectStreamClass.lookup(recordClass); out.println("ObjectStreamClass::lookup : " + osc); - assertEquals(osc, null); + assertEquals(null, osc); osc = ObjectStreamClass.lookupAny(recordClass); out.println("ObjectStreamClass::lookupAny: " + osc); - assertEquals(osc.getSerialVersionUID(), 0L); + assertEquals(0L, osc.getSerialVersionUID()); } // --- infra diff --git a/test/jdk/java/io/Serializable/records/SerialPersistentFieldsTest.java b/test/jdk/java/io/Serializable/records/SerialPersistentFieldsTest.java index 16266806850..471e94b6ed7 100644 --- a/test/jdk/java/io/Serializable/records/SerialPersistentFieldsTest.java +++ b/test/jdk/java/io/Serializable/records/SerialPersistentFieldsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -26,7 +26,7 @@ * @bug 8246774 * @summary Basic tests for prohibited magic serialPersistentFields * @library /test/lib - * @run testng SerialPersistentFieldsTest + * @run junit SerialPersistentFieldsTest */ import java.io.ByteArrayInputStream; @@ -52,9 +52,6 @@ import java.math.BigDecimal; import jdk.test.lib.ByteCodeLoader; import jdk.test.lib.compiler.InMemoryJavaCompiler; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; import static java.lang.classfile.ClassFile.ACC_FINAL; import static java.lang.classfile.ClassFile.ACC_PRIVATE; @@ -65,12 +62,18 @@ import static java.lang.constant.ConstantDescs.CD_void; import static java.lang.constant.ConstantDescs.CLASS_INIT_NAME; import static java.lang.constant.ConstantDescs.INIT_NAME; import static java.lang.constant.ConstantDescs.MTD_void; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * Checks that the serialPersistentFields declaration is effectively ignored. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class SerialPersistentFieldsTest { ClassLoader serializableRecordLoader; @@ -88,7 +91,7 @@ public class SerialPersistentFieldsTest { * }; * } */ - @BeforeTest + @BeforeAll public void setup() { { // R1 byte[] byteCode = InMemoryJavaCompiler.compile("R1", @@ -174,7 +177,6 @@ public class SerialPersistentFieldsTest { return newRecord("R5", new Class[]{int.class}, new Object[]{x}); } - @DataProvider(name = "recordInstances") public Object[][] recordInstances() { return new Object[][] { new Object[] { newR1() }, @@ -185,14 +187,15 @@ public class SerialPersistentFieldsTest { }; } - @Test(dataProvider = "recordInstances") + @ParameterizedTest + @MethodSource("recordInstances") public void roundTrip(Object objToSerialize) throws Exception { out.println("\n---"); out.println("serializing : " + objToSerialize); var objDeserialized = serializeDeserialize(objToSerialize); out.println("deserialized: " + objDeserialized); - assertEquals(objToSerialize, objDeserialized); assertEquals(objDeserialized, objToSerialize); + assertEquals(objToSerialize, objDeserialized); } byte[] serialize(T obj) throws IOException { @@ -290,7 +293,8 @@ public class SerialPersistentFieldsTest { // -- infra sanity -- /** Checks to ensure correct operation of the test's generation logic. */ - @Test(dataProvider = "recordInstances") + @ParameterizedTest + @MethodSource("recordInstances") public void wellFormedGeneratedClasses(Object obj) throws Exception { out.println("\n---"); out.println(obj); diff --git a/test/jdk/java/io/Serializable/records/SerialVersionUIDTest.java b/test/jdk/java/io/Serializable/records/SerialVersionUIDTest.java index abc0c63b0f2..2c133392dcb 100644 --- a/test/jdk/java/io/Serializable/records/SerialVersionUIDTest.java +++ b/test/jdk/java/io/Serializable/records/SerialVersionUIDTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -25,7 +25,7 @@ * @test * @bug 8246774 * @summary Basic tests for SUID in the serial stream - * @run testng SerialVersionUIDTest + * @run junit SerialVersionUIDTest */ import java.io.ByteArrayInputStream; @@ -39,13 +39,16 @@ import java.io.Serializable; import java.util.ArrayList; import java.util.List; import java.util.stream.LongStream; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.io.ObjectStreamConstants.*; import static java.lang.System.out; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class SerialVersionUIDTest { record R1 () implements Serializable { @@ -64,7 +67,6 @@ public class SerialVersionUIDTest { private static final long serialVersionUID = 5678L; } - @DataProvider(name = "recordObjects") public Object[][] recordObjects() { return new Object[][] { new Object[] { new R1(), 1L }, @@ -78,7 +80,8 @@ public class SerialVersionUIDTest { /** * Tests that a declared SUID for a record class is inserted into the stream. */ - @Test(dataProvider = "recordObjects") + @ParameterizedTest + @MethodSource("recordObjects") public void testSerialize(Object objectToSerialize, long expectedUID) throws Exception { @@ -90,17 +93,16 @@ public class SerialVersionUIDTest { DataInputStream dis = new DataInputStream(bais); // sanity - assertEquals(dis.readShort(), STREAM_MAGIC); - assertEquals(dis.readShort(), STREAM_VERSION); - assertEquals(dis.readByte(), TC_OBJECT); - assertEquals(dis.readByte(), TC_CLASSDESC); - assertEquals(dis.readUTF(), objectToSerialize.getClass().getName()); + assertEquals(STREAM_MAGIC, dis.readShort()); + assertEquals(STREAM_VERSION, dis.readShort()); + assertEquals(TC_OBJECT, dis.readByte()); + assertEquals(TC_CLASSDESC, dis.readByte()); + assertEquals(objectToSerialize.getClass().getName(), dis.readUTF()); // verify that the UID is as expected - assertEquals(dis.readLong(), expectedUID); + assertEquals(expectedUID, dis.readLong()); } - @DataProvider(name = "recordClasses") public Object[][] recordClasses() { List list = new ArrayList<>(); List> recordClasses = List.of(R1.class, R2.class, R3.class, R4.class, R5.class); @@ -115,14 +117,15 @@ public class SerialVersionUIDTest { * Tests that matching of the serialVersionUID values ( stream value * and runtime class value ) is waived for record classes. */ - @Test(dataProvider = "recordClasses") + @ParameterizedTest + @MethodSource("recordClasses") public void testSerializeFromClass(Class cl, long suid) throws Exception { out.println("\n---"); byte[] bytes = byteStreamFor(cl.getName(), suid); Object obj = deserialize(bytes); - assertEquals(obj.getClass(), cl); + assertEquals(cl, obj.getClass()); assertTrue(obj.getClass().isRecord()); } diff --git a/test/jdk/java/io/Serializable/records/StreamRefTest.java b/test/jdk/java/io/Serializable/records/StreamRefTest.java index b0c72ec8a96..d0d3e353bdb 100644 --- a/test/jdk/java/io/Serializable/records/StreamRefTest.java +++ b/test/jdk/java/io/Serializable/records/StreamRefTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, 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 @@ -25,7 +25,7 @@ * @test * @bug 8246774 * @summary Tests for stream references - * @run testng StreamRefTest + * @run junit StreamRefTest */ import java.io.ByteArrayInputStream; @@ -36,11 +36,12 @@ import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; -import org.testng.annotations.Test; import static java.lang.System.out; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.expectThrows; + +import org.junit.jupiter.api.Assertions; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; /** * Tests for stream references. @@ -123,14 +124,14 @@ public class StreamRefTest { updateIntValue(3, -3, bytes, 40); var byteStream = new ObjectInputStream(new ByteArrayInputStream(bytes)); - InvalidObjectException ioe = expectThrows(IOE, () -> deserializeOne(byteStream)); + InvalidObjectException ioe = Assertions.assertThrows(IOE, () -> deserializeOne(byteStream)); out.println("caught expected IOE: " + ioe); Throwable t = ioe.getCause(); assertTrue(t instanceof IllegalArgumentException, "Expected IAE, got:" + t); out.println("expected cause IAE: " + t); B b1 = (B)deserializeOne(byteStream); - assertEquals(b1.a, null); + assertEquals(null, b1.a); } @Test @@ -144,14 +145,14 @@ public class StreamRefTest { updateIntValue(3, -3, bytes, 96); var byteStream = new ObjectInputStream(new ByteArrayInputStream(bytes)); - InvalidObjectException ioe = expectThrows(IOE, () -> deserializeOne(byteStream)); + InvalidObjectException ioe = Assertions.assertThrows(IOE, () -> deserializeOne(byteStream)); out.println("caught expected IOE: " + ioe); Throwable t = ioe.getCause(); assertTrue(t instanceof IllegalArgumentException, "Expected IAE, got:" + t); out.println("expected cause IAE: " + t); A a1 = (A)deserializeOne(byteStream); - assertEquals(a1, null); + assertEquals(null, a1); } // --- @@ -211,7 +212,7 @@ public class StreamRefTest { throws IOException { ByteArrayInputStream bais = new ByteArrayInputStream(bytes, offset, 4); DataInputStream dis = new DataInputStream(bais); - assertEquals(dis.readInt(), expectedValue); + assertEquals(expectedValue, dis.readInt()); } static void updateIntValue(int expectedValue, int newValue, byte[] bytes, int offset) diff --git a/test/jdk/java/io/Serializable/records/ThrowingConstructorTest.java b/test/jdk/java/io/Serializable/records/ThrowingConstructorTest.java index 8e43a11a832..ee05930f29e 100644 --- a/test/jdk/java/io/Serializable/records/ThrowingConstructorTest.java +++ b/test/jdk/java/io/Serializable/records/ThrowingConstructorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -25,7 +25,7 @@ * @test * @bug 8246774 * @summary Tests constructor invocation exceptions are handled appropriately - * @run testng ThrowingConstructorTest + * @run junit ThrowingConstructorTest */ import java.io.ByteArrayInputStream; @@ -35,17 +35,20 @@ import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.expectThrows; + +import org.junit.jupiter.api.Assertions; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * If the constructor invocation throws an exception, an * `InvalidObjectException` is thrown with that exception as its cause. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class ThrowingConstructorTest { /** "big switch" that can be used to allow/disallow record construction @@ -84,7 +87,6 @@ public class ThrowingConstructorTest { static final Class IOE = InvalidObjectException.class; - @DataProvider(name = "exceptionInstances") public Object[][] exceptionInstances() { Object[][] objs = new Object[][] { new Object[] { new R1(), NullPointerException.class, "thrown from R1" }, @@ -98,7 +100,8 @@ public class ThrowingConstructorTest { return objs; } - @Test(dataProvider = "exceptionInstances") + @ParameterizedTest + @MethodSource("exceptionInstances") public void testExceptions(Object objectToSerialize, Class expectedExType, String expectedExMessage) @@ -107,13 +110,13 @@ public class ThrowingConstructorTest { out.println("\n---"); out.println("serializing: " + objectToSerialize); byte[] bytes = serialize(objectToSerialize); - InvalidObjectException ioe = expectThrows(IOE, () -> deserialize(bytes)); + InvalidObjectException ioe = Assertions.assertThrows(IOE, () -> deserialize(bytes)); out.println("caught expected IOE: " + ioe); Throwable t = ioe.getCause(); assertTrue(t.getClass().equals(expectedExType), "Expected:" + expectedExType + ", got:" + t); out.println("expected cause " + expectedExType +" : " + t); - assertEquals(t.getMessage(), expectedExMessage); + assertEquals(expectedExMessage, t.getMessage()); } // -- errors ( pass through unwrapped ) @@ -143,7 +146,6 @@ public class ThrowingConstructorTest { } } - @DataProvider(name = "errorInstances") public Object[][] errorInstances() { Object[][] objs = new Object[][] { new Object[] { new R4(), OutOfMemoryError.class, "thrown from R4" }, @@ -157,7 +159,8 @@ public class ThrowingConstructorTest { return objs; } - @Test(dataProvider = "errorInstances") + @ParameterizedTest + @MethodSource("errorInstances") public void testErrors(Object objectToSerialize, Class expectedExType, String expectedExMessage) @@ -166,11 +169,11 @@ public class ThrowingConstructorTest { out.println("\n---"); out.println("serializing: " + objectToSerialize); byte[] bytes = serialize(objectToSerialize); - Throwable t = expectThrows(expectedExType, () -> deserialize(bytes)); + Throwable t = Assertions.assertThrows(expectedExType, () -> deserialize(bytes)); assertTrue(t.getClass().equals(expectedExType), "Expected:" + expectedExType + ", got:" + t); out.println("caught expected " + expectedExType +" : " + t); - assertEquals(t.getMessage(), expectedExMessage); + assertEquals(expectedExMessage, t.getMessage()); } // --- infra diff --git a/test/jdk/java/io/Serializable/records/UnsharedTest.java b/test/jdk/java/io/Serializable/records/UnsharedTest.java index c96010c83ab..114e2dc6e10 100644 --- a/test/jdk/java/io/Serializable/records/UnsharedTest.java +++ b/test/jdk/java/io/Serializable/records/UnsharedTest.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 @@ -25,7 +25,7 @@ * @test * @bug 8238763 8246774 * @summary ObjectInputStream readUnshared method handling of Records - * @run testng UnsharedTest + * @run junit UnsharedTest */ import java.io.ByteArrayInputStream; @@ -35,10 +35,11 @@ import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; -import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.expectThrows; +import org.junit.jupiter.api.Assertions; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; /** * Tests OOS::writeUnshared and OIS::readUnshared to verify that records @@ -56,16 +57,16 @@ public class UnsharedTest { { // shared - sanity to ensure the second foo is a ref var byteStream = serialize(foo, foo); var foo1 = (Foo) deserializeOne(byteStream); - assertEquals(foo1.x, foo.x); + assertEquals(foo.x, foo1.x); var foo2 = (Foo) deserializeOne(byteStream); - assertEquals(foo2.x, foo.x); + assertEquals(foo.x, foo2.x); assertTrue(foo2 == foo1); } { // unshared var byteStream = serialize(foo, foo); var foo1 = (Foo) deserializeOneUnshared(byteStream); - assertEquals(foo1.x, foo.x); - var expected = expectThrows(IOE, () -> deserializeOne(byteStream)); + assertEquals(foo.x, foo1.x); + var expected = Assertions.assertThrows(IOE, () -> deserializeOne(byteStream)); assertTrue(expected.getMessage().contains("cannot read back reference to unshared object")); } } @@ -76,17 +77,17 @@ public class UnsharedTest { { // shared - sanity to ensure the second foo is NOT a ref var byteStream = serializeUnshared(foo, foo); var foo1 = (Foo) deserializeOne(byteStream); - assertEquals(foo1.x, foo.x); + assertEquals(foo.x, foo1.x); var foo2 = (Foo) deserializeOne(byteStream); - assertEquals(foo2.x, foo.x); + assertEquals(foo.x, foo2.x); assertTrue(foo2 != foo1); } { // unshared var byteStream = serializeUnshared(foo, foo); var foo1 = (Foo) deserializeOneUnshared(byteStream); - assertEquals(foo1.x, foo.x); + assertEquals(foo.x, foo1.x); var foo2 = (Foo) deserializeOneUnshared(byteStream); - assertEquals(foo2.x, foo.x); + assertEquals(foo.x, foo2.x); assertTrue(foo2 != foo1); } } diff --git a/test/jdk/java/io/Serializable/records/WriteReplaceTest.java b/test/jdk/java/io/Serializable/records/WriteReplaceTest.java index c64d6355dd2..2e253c166a0 100644 --- a/test/jdk/java/io/Serializable/records/WriteReplaceTest.java +++ b/test/jdk/java/io/Serializable/records/WriteReplaceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -25,7 +25,7 @@ * @test * @bug 8246774 * @summary Basic tests for writeReplace - * @run testng WriteReplaceTest + * @run junit WriteReplaceTest */ import java.io.ByteArrayInputStream; @@ -34,11 +34,15 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; -import static org.testng.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class WriteReplaceTest { record R1 () implements Serializable { @@ -71,7 +75,6 @@ public class WriteReplaceTest { } } - @DataProvider(name = "recordObjects") public Object[][] recordObjects() { return new Object[][] { new Object[] { new R1(), R1.class }, @@ -81,7 +84,8 @@ public class WriteReplaceTest { }; } - @Test(dataProvider = "recordObjects") + @ParameterizedTest + @MethodSource("recordObjects") public void testSerialize(Object objectToSerialize, Class expectedType) throws Exception { @@ -90,9 +94,9 @@ public class WriteReplaceTest { Object deserializedObj = serializeDeserialize(objectToSerialize); out.println("deserialized: " + deserializedObj); if (objectToSerialize.getClass().equals(expectedType)) - assertEquals(deserializedObj, objectToSerialize); + assertEquals(objectToSerialize, deserializedObj); else - assertEquals(deserializedObj.getClass(), expectedType); + assertEquals(expectedType, deserializedObj.getClass()); } // -- null replacement @@ -108,7 +112,7 @@ public class WriteReplaceTest { out.println("serializing : " + objectToSerialize); Object deserializedObj = serializeDeserialize(objectToSerialize); out.println("deserialized: " + deserializedObj); - assertEquals(deserializedObj, null); + assertEquals(null, deserializedObj); } // --- infra diff --git a/test/jdk/java/io/Serializable/records/migration/AbstractTest.java b/test/jdk/java/io/Serializable/records/migration/AbstractTest.java index e0bbc574500..488f4a33acd 100644 --- a/test/jdk/java/io/Serializable/records/migration/AbstractTest.java +++ b/test/jdk/java/io/Serializable/records/migration/AbstractTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, 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 @@ -34,8 +34,9 @@ import java.net.URL; import java.net.URLClassLoader; import java.nio.file.Path; import jdk.test.lib.compiler.CompilerUtils; -import org.testng.annotations.BeforeTest; -import static org.testng.Assert.*; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; /** * An abstract superclass for tests that require to serialize and deserialize @@ -54,7 +55,7 @@ public class AbstractTest { static final Path RECORD_SRC_DIR = Path.of(TEST_SRC, "record"); static final Path RECORD_DEST_DIR = Path.of("record"); - @BeforeTest + @BeforeAll public void setup() throws IOException { assertTrue(CompilerUtils.compile(PLAIN_SRC_DIR, PLAIN_DEST_DIR, "--class-path", TEST_CLASSES_DIR.toString())); diff --git a/test/jdk/java/io/Serializable/records/migration/AssignableFromTest.java b/test/jdk/java/io/Serializable/records/migration/AssignableFromTest.java index 6097e2477df..117a8474c67 100644 --- a/test/jdk/java/io/Serializable/records/migration/AssignableFromTest.java +++ b/test/jdk/java/io/Serializable/records/migration/AssignableFromTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, 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 @@ -29,24 +29,26 @@ * @modules jdk.compiler * @compile AssignableFrom.java Point.java * DefaultValues.java SuperStreamFields.java - * @run testng AssignableFromTest + * @run junit AssignableFromTest */ import java.math.BigDecimal; import java.math.BigInteger; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; -import static org.testng.Assert.assertEquals; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * Basic test to check that stream field values that are not the exact * declared param/field type, but assignable to a declared supertype, * are bound/assigned correctly. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class AssignableFromTest extends AbstractTest { - @DataProvider(name = "plainInstances") public Object[][] plainInstances() { return new Object[][] { new Object[] { newPlainAssignableFrom(Byte.valueOf((byte)11)) }, @@ -59,7 +61,8 @@ public class AssignableFromTest extends AbstractTest { } /** Serialize non-record (plain) instances, deserialize as a record. */ - @Test(dataProvider = "plainInstances") + @ParameterizedTest + @MethodSource("plainInstances") public void testPlainToRecord(AssignableFrom objToSerialize) throws Exception { assert !objToSerialize.getClass().isRecord(); out.println("serialize : " + objToSerialize); @@ -68,13 +71,12 @@ public class AssignableFromTest extends AbstractTest { assert objDeserialized.getClass().isRecord(); out.println("deserialized: " + objDeserialized); - assertEquals(objToSerialize.number(), objDeserialized.number()); assertEquals(objDeserialized.number(), objToSerialize.number()); + assertEquals(objToSerialize.number(), objDeserialized.number()); assertEquals(objDeserialized.number().getClass(), objDeserialized.number().getClass()); } - @DataProvider(name = "recordInstances") public Object[][] recordInstances() { return new Object[][] { new Object[] { newRecordAssignableFrom(Byte.valueOf((byte)21)) }, @@ -87,7 +89,8 @@ public class AssignableFromTest extends AbstractTest { } /** Serialize record instances, deserialize as non-record (plain). */ - @Test(dataProvider = "recordInstances") + @ParameterizedTest + @MethodSource("recordInstances") public void testRecordToPlain(AssignableFrom objToSerialize) throws Exception { assert objToSerialize.getClass().isRecord(); out.println("serialize : " + objToSerialize); @@ -96,8 +99,8 @@ public class AssignableFromTest extends AbstractTest { assert !objDeserialized.getClass().isRecord(); out.println("deserialized: " + objDeserialized); - assertEquals(objToSerialize.number(), objDeserialized.number()); assertEquals(objDeserialized.number(), objToSerialize.number()); + assertEquals(objToSerialize.number(), objDeserialized.number()); assertEquals(objDeserialized.number().getClass(), objDeserialized.number().getClass()); } diff --git a/test/jdk/java/io/Serializable/records/migration/DefaultValuesTest.java b/test/jdk/java/io/Serializable/records/migration/DefaultValuesTest.java index 4af684156c6..357c9400777 100644 --- a/test/jdk/java/io/Serializable/records/migration/DefaultValuesTest.java +++ b/test/jdk/java/io/Serializable/records/migration/DefaultValuesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, 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 @@ -28,21 +28,24 @@ * @library /test/lib * @modules jdk.compiler * @compile AssignableFrom.java Point.java DefaultValues.java SuperStreamFields.java - * @run testng DefaultValuesTest + * @run junit DefaultValuesTest */ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; -import org.testng.annotations.Test; import static java.io.ObjectStreamConstants.*; import static java.lang.System.out; -import static org.testng.Assert.*; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; /** * Basic test to check that default primitive / reference values are * presented to the record's canonical constructor, for fields not in * the stream. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class DefaultValuesTest extends AbstractTest { /** @@ -77,13 +80,13 @@ public class DefaultValuesTest extends AbstractTest { Point point = deserializeAsPlain(bytes); out.println("deserialized: " + point); - assertEquals(point.x(), 0); - assertEquals(point.y(), 0); + assertEquals(0, point.x()); + assertEquals(0, point.y()); point = deserializeAsRecord(bytes); out.println("deserialized: " + point); - assertEquals(point.x(), 0); - assertEquals(point.y(), 0); + assertEquals(0, point.x()); + assertEquals(0, point.y()); } // --- @@ -115,8 +118,8 @@ public class DefaultValuesTest extends AbstractTest { DefaultValues o1 = deserializeAsRecord(bytes); out.println("deserialized: " + o1); - assertEquals(o1.point().x(), point.x()); // sanity - assertEquals(o1.point().y(), point.y()); // sanity + assertEquals(point.x(), o1.point().x()); // sanity + assertEquals(point.y(), o1.point().y()); // sanity assertTrue(o1.bool() == Defaults.bool); assertTrue(o1.by() == Defaults.by); assertTrue(o1.ch() == Defaults.ch); diff --git a/test/jdk/java/io/Serializable/records/migration/SuperStreamFieldsTest.java b/test/jdk/java/io/Serializable/records/migration/SuperStreamFieldsTest.java index 6090d71003e..35e75341dbf 100644 --- a/test/jdk/java/io/Serializable/records/migration/SuperStreamFieldsTest.java +++ b/test/jdk/java/io/Serializable/records/migration/SuperStreamFieldsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, 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 @@ -28,20 +28,23 @@ * @library /test/lib * @modules jdk.compiler * @compile AssignableFrom.java Point.java DefaultValues.java SuperStreamFields.java - * @run testng SuperStreamFieldsTest + * @run junit SuperStreamFieldsTest */ -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static java.lang.System.out; -import static org.testng.Assert.assertEquals; + +import org.junit.jupiter.api.Assertions; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * Tests that superclass fields in the stream are discarded. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class SuperStreamFieldsTest extends AbstractTest { - @DataProvider(name = "plainInstances") public Object[][] plainInstances() { return new Object[][] { new Object[] { newPlainSuperStreamFields("cat", new int[] { 1 }, 1) }, @@ -51,7 +54,8 @@ public class SuperStreamFieldsTest extends AbstractTest { } /** Serializes non-record (plain) instance, deserializes as a record. */ - @Test(dataProvider = "plainInstances") + @ParameterizedTest + @MethodSource("plainInstances") public void testPlainToRecord(SuperStreamFields objToSerialize) throws Exception { assert !objToSerialize.getClass().isRecord(); out.println("serialize : " + objToSerialize); @@ -60,12 +64,11 @@ public class SuperStreamFieldsTest extends AbstractTest { assert objDeserialized.getClass().isRecord(); out.println("deserialized: " + objDeserialized); - assertEquals(objToSerialize.str(), objDeserialized.str()); - assertEquals(objToSerialize.x(), objDeserialized.x()); - assertEquals(objToSerialize.y(), objDeserialized.y()); + assertEquals(objDeserialized.str(), objToSerialize.str()); + Assertions.assertArrayEquals(objDeserialized.x(), objToSerialize.x()); + assertEquals(objDeserialized.y(), objToSerialize.y()); } - @DataProvider(name = "recordInstances") public Object[][] recordInstances() { return new Object[][] { new Object[] { newRecordSuperStreamFields("goat", new int[] { 56 }, 66) }, @@ -75,7 +78,8 @@ public class SuperStreamFieldsTest extends AbstractTest { } /** Serializes record instance, deserializes as non-record (plain). */ - @Test(dataProvider = "recordInstances") + @ParameterizedTest + @MethodSource("recordInstances") public void testRecordToPlain(SuperStreamFields objToSerialize) throws Exception { assert objToSerialize.getClass().isRecord(); out.println("serialize : " + objToSerialize); @@ -84,9 +88,9 @@ public class SuperStreamFieldsTest extends AbstractTest { assert !objDeserialized.getClass().isRecord(); out.println("deserialized: " + objDeserialized); - assertEquals(objToSerialize.str(), objDeserialized.str()); - assertEquals(objToSerialize.x(), objDeserialized.x()); - assertEquals(objToSerialize.y(), objDeserialized.y()); + assertEquals(objDeserialized.str(), objToSerialize.str()); + Assertions.assertArrayEquals(objDeserialized.x(), objToSerialize.x()); + assertEquals(objDeserialized.y(), objToSerialize.y()); } From d02abfe765a1e67c5e37f3450aa5a0d8fb97a208 Mon Sep 17 00:00:00 2001 From: Khalid Boulanouare Date: Tue, 16 Dec 2025 20:37:57 +0000 Subject: [PATCH 026/390] 8158801: [TEST_BUG] Mixing tests fail because of focus workaround trick Reviewed-by: aivanov, prr, psadhukhan --- test/jdk/ProblemList.txt | 29 +------- .../GlassPaneOverlappingTestBase.java | 69 +++++++++---------- .../AWT_Mixing/JComboBoxOverlapping.java | 4 +- .../JInternalFrameMoveOverlapping.java | 4 +- .../AWT_Mixing/JInternalFrameOverlapping.java | 3 +- .../AWT_Mixing/JMenuBarOverlapping.java | 7 +- .../AWT_Mixing/JPopupMenuOverlapping.java | 6 +- .../AWT_Mixing/JScrollPaneOverlapping.java | 3 +- .../AWT_Mixing/JSplitPaneOverlapping.java | 3 +- .../AWT_Mixing/MixingFrameResizing.java | 5 +- .../AWT_Mixing/MixingPanelsResizing.java | 27 ++++++-- .../Mixing/AWT_Mixing/OpaqueOverlapping.java | 7 +- .../AWT_Mixing/OverlappingTestBase.java | 13 +++- .../AWT_Mixing/SimpleOverlappingTestBase.java | 59 +++++++++++----- 14 files changed, 132 insertions(+), 107 deletions(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 974e719c1c9..a81e48f3883 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -152,7 +152,6 @@ java/awt/event/InputEvent/EventWhenTest/EventWhenTest.java 8168646 generic-all java/awt/List/KeyEventsTest/KeyEventsTest.java 8201307 linux-all java/awt/List/NoEvents/ProgrammaticChange.java 8201307 linux-all java/awt/Paint/ListRepaint.java 8201307 linux-all -java/awt/Mixing/AWT_Mixing/HierarchyBoundsListenerMixingTest.java 8049405 macosx-all java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java 8370584 windows-x64 java/awt/Mixing/AWT_Mixing/OpaqueOverlappingChoice.java 8048171 generic-all java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java 8159451 linux-all,windows-all,macosx-all @@ -161,33 +160,7 @@ java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java 6986109 windows-al java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java 8049405 generic-all java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java 8049405 macosx-all java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java 8049405 macosx-all -java/awt/Mixing/AWT_Mixing/JButtonInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JButtonOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JColorChooserOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JEditorPaneInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JEditorPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JLabelInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JLabelOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JListInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JListOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JPanelInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JPanelOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JProgressBarInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JProgressBarOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JScrollBarInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JScrollBarOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JSliderInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JSliderOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JSpinnerInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JSpinnerOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JTableInGlassPaneOverlapping.java 8158801,8357360 windows-all,linux-all -java/awt/Mixing/AWT_Mixing/JTableOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JTextAreaInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JTextAreaOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JTextFieldInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JTextFieldOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JToggleButtonInGlassPaneOverlapping.java 8158801 windows-all -java/awt/Mixing/AWT_Mixing/JToggleButtonOverlapping.java 8158801 windows-all +java/awt/Mixing/AWT_Mixing/JTableInGlassPaneOverlapping.java 8357360 windows-all,linux-all java/awt/Mixing/NonOpaqueInternalFrame.java 7124549 macosx-all java/awt/Focus/ActualFocusedWindowTest/ActualFocusedWindowRetaining.java 6829264 generic-all java/awt/datatransfer/DragImage/MultiResolutionDragImageTest.java 8080982 generic-all diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/GlassPaneOverlappingTestBase.java b/test/jdk/java/awt/Mixing/AWT_Mixing/GlassPaneOverlappingTestBase.java index f67e71b1b19..f5dd838eff2 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/GlassPaneOverlappingTestBase.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/GlassPaneOverlappingTestBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -25,12 +25,11 @@ import java.awt.Container; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.event.InputEvent; import java.lang.reflect.InvocationTargetException; + import javax.swing.JFrame; import javax.swing.SpringLayout; import javax.swing.SwingUtilities; -import test.java.awt.regtesthelpers.Util; /** * Base class for testing overlapping of Swing and AWT component put into GlassPane. @@ -46,7 +45,6 @@ public abstract class GlassPaneOverlappingTestBase extends SimpleOverlappingTest */ protected boolean testResize = true; private JFrame f = null; - private volatile Point ancestorLoc; /** * Setups GlassPane with lightweight component returned by {@link SimpleOverlappingTestBase#getSwingComponent() } @@ -83,6 +81,7 @@ public abstract class GlassPaneOverlappingTestBase extends SimpleOverlappingTest testedComponent.setBounds(0, 0, testedComponent.getPreferredSize().width, testedComponent.getPreferredSize().height); glassPane.add(testedComponent); + f.setLocationRelativeTo(null); f.setVisible(true); } @@ -94,6 +93,11 @@ public abstract class GlassPaneOverlappingTestBase extends SimpleOverlappingTest super(defaultClickValidation); } + @Override + protected final boolean isMultiFramesTest() { + return false; + } + /** * Run test by {@link OverlappingTestBase#clickAndBlink(java.awt.Robot, java.awt.Point) } validation for current lightweight component. *

Also resize component and repeat validation in the resized area. @@ -106,40 +110,33 @@ public abstract class GlassPaneOverlappingTestBase extends SimpleOverlappingTest if (!super.performTest()) { return false; } - if (testResize) { - wasLWClicked = false; - try { - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - testedComponent.setBounds(0, 0, testedComponent.getPreferredSize().width, testedComponent.getPreferredSize().height + 20); - ancestorLoc = f.getLocationOnScreen(); - } - }); - } catch (InterruptedException ex) { - fail(ex.getMessage()); - } catch (InvocationTargetException ex) { - fail(ex.getMessage()); - } - Point lLoc = testedComponent.getLocationOnScreen(); - lLoc.translate(1, testedComponent.getPreferredSize().height + 1); - - /* this is a workaround for certain jtreg(?) focus issue: - tests fail starting after failing mixing tests but always pass alone. - */ - Util.waitForIdle(robot); - ancestorLoc.translate(isOel7orLater() ? 5 : f.getWidth() / 2 - 15, 2); - robot.mouseMove(ancestorLoc.x, ancestorLoc.y); - Util.waitForIdle(robot); - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.delay(50); - robot.mouseRelease(InputEvent.BUTTON1_MASK); - Util.waitForIdle(robot); - - clickAndBlink(robot, lLoc); - return wasLWClicked; - } else { + if (!testResize) { return true; } + + wasLWClicked = false; + try { + SwingUtilities.invokeAndWait(new Runnable() { + + public void run() { + testedComponent.setBounds(0, 0, + testedComponent.getPreferredSize().width, + testedComponent.getPreferredSize().height + 20); + } + }); + } catch (InterruptedException | InvocationTargetException ex) { + fail(ex.getMessage()); + } + Point lLoc = testedComponent.getLocationOnScreen(); + lLoc.translate(1, testedComponent.getPreferredSize().height + 1); + clickAndBlink(robot, lLoc); + + return wasLWClicked; + } + + @Override + protected void cleanup() { + f.dispose(); } } diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java b/test/jdk/java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java index cc02e9afbeb..d71fa7b3522 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/JComboBoxOverlapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -64,7 +64,6 @@ public class JComboBoxOverlapping extends OverlappingTestBase { frame = new JFrame("Mixing : Dropdown Overlapping test"); frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(), BoxLayout.Y_AXIS)); frame.setSize(200, 200); - frame.setVisible(true); cb = new JComboBox(petStrings); cb.setPreferredSize(new Dimension(frame.getContentPane().getWidth(), 20)); @@ -79,6 +78,7 @@ public class JComboBoxOverlapping extends OverlappingTestBase { frame.add(cb); propagateAWTControls(frame); + frame.setLocationRelativeTo(null); frame.setVisible(true); } diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java b/test/jdk/java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java index 443ff70727d..6f27aba85da 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/JInternalFrameMoveOverlapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -34,7 +34,6 @@ import test.java.awt.regtesthelpers.Util; /** * AWT/Swing overlapping test for {@link javax.swing.JInternalFrame } component during move. - *

See CR6768230 for details and base class for test info. */ /* * @test @@ -117,6 +116,7 @@ public class JInternalFrameMoveOverlapping extends OverlappingTestBase { JFrame frame = new JFrame("Test Window"); frame.setSize(300, 300); frame.setContentPane(desktopPane); + frame.setLocationRelativeTo(null); frame.setVisible(true); locTopFrame = topFrame.getLocationOnScreen(); diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java b/test/jdk/java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java index 4cb9425abe7..8d619e34c35 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/JInternalFrameOverlapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -75,6 +75,7 @@ public class JInternalFrameOverlapping extends OverlappingTestBase { JFrame frame = new JFrame("Test Window"); frame.setSize(300, 300); frame.setContentPane(desktopPane); + frame.setLocationRelativeTo(null); frame.setVisible(true); JInternalFrame bottomFrame = new JInternalFrame("bottom frame", false, false, false, false); bottomFrame.setSize(220, 220); diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java b/test/jdk/java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java index 792831c2d8d..f3a213e5144 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/JMenuBarOverlapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -22,7 +22,6 @@ */ -import java.awt.Color; import java.awt.GridLayout; import java.awt.Point; import java.awt.Robot; @@ -30,12 +29,14 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; + import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JSeparator; import javax.swing.SwingUtilities; + import test.java.awt.regtesthelpers.Util; /** @@ -72,7 +73,6 @@ public class JMenuBarOverlapping extends OverlappingTestBase { frame = new JFrame("Mixing : Dropdown Overlapping test"); frame.setLayout(new GridLayout(0,1)); frame.setSize(200, 200); - frame.setVisible(true); menuBar = new JMenuBar(); JMenu menu = new JMenu("Test Menu"); @@ -104,6 +104,7 @@ public class JMenuBarOverlapping extends OverlappingTestBase { frame.setJMenuBar(menuBar); propagateAWTControls(frame); + frame.setLocationRelativeTo(null); frame.setVisible(true); } diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java b/test/jdk/java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java index d4b50287dc6..e80475088ac 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/JPopupMenuOverlapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -22,17 +22,18 @@ */ -import java.awt.Color; import java.awt.Point; import java.awt.Robot; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.lang.reflect.InvocationTargetException; + import javax.swing.JFrame; import javax.swing.JMenuItem; import javax.swing.JPopupMenu; import javax.swing.SpringLayout; import javax.swing.SwingUtilities; + import test.java.awt.regtesthelpers.Util; /** @@ -82,6 +83,7 @@ public class JPopupMenuOverlapping extends OverlappingTestBase { item.addActionListener(menuListener); } propagateAWTControls(frame); + frame.setLocationRelativeTo(null); frame.setVisible(true); loc = frame.getContentPane().getLocationOnScreen(); } diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/JScrollPaneOverlapping.java b/test/jdk/java/awt/Mixing/AWT_Mixing/JScrollPaneOverlapping.java index f22eacba82d..91538b75c13 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/JScrollPaneOverlapping.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/JScrollPaneOverlapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -95,6 +95,7 @@ public class JScrollPaneOverlapping extends OverlappingTestBase { }); f.getContentPane().add(scrollPane); + f.setLocationRelativeTo(null); f.setVisible(true); propagateAWTControls(p); // JButton b = new JButton("Space extender"); diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java b/test/jdk/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java index 7e1cb9434e4..5875a04b62b 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/JSplitPaneOverlapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -89,6 +89,7 @@ public class JSplitPaneOverlapping extends OverlappingTestBase { frame.getContentPane().add(splitPane); frame.pack(); + frame.setLocationRelativeTo(null); frame.setVisible(true); } diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java b/test/jdk/java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java index 545566970f8..8c19a80bd43 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/MixingFrameResizing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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,9 +26,11 @@ import java.awt.Dimension; import java.awt.Point; import java.awt.Robot; import java.awt.event.InputEvent; + import javax.swing.JFrame; import javax.swing.SpringLayout; import javax.swing.SwingUtilities; + import test.java.awt.regtesthelpers.Util; /** @@ -65,6 +67,7 @@ public class MixingFrameResizing extends OverlappingTestBase { frame = new JFrame("Mixing : Frame Resizing test"); frame.setLayout(new SpringLayout()); frame.setSize(50, 50); + frame.setLocationRelativeTo(null); frame.setVisible(true); propagateAWTControls(frame); Util.waitTillShown(frame); diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java b/test/jdk/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java index 39a59dc2a5c..1bb9b442dd8 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/MixingPanelsResizing.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -22,10 +22,23 @@ */ -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Button; +import java.awt.Color; +import java.awt.Panel; +import java.awt.Point; +import java.awt.Robot; +import java.awt.Toolkit; import java.awt.event.InputEvent; -import javax.swing.*; -import java.io.*; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; + import test.java.awt.regtesthelpers.Util; /** @@ -130,6 +143,7 @@ public class MixingPanelsResizing { frame.add(jPanel, BorderLayout.NORTH); frame.pack(); + frame.setLocationRelativeTo(null); frame.setVisible(true); } }); @@ -298,6 +312,7 @@ public class MixingPanelsResizing { failureMessage = whyFailed; mainThread.interrupt(); }//fail() + + static class TestPassedException extends RuntimeException { + } }// class JButtonInGlassPane -class TestPassedException extends RuntimeException { -} diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java b/test/jdk/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java index 4975cc165c2..03abb58f673 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -56,13 +56,13 @@ public class OpaqueOverlapping extends OverlappingTestBase { { useClickValidation = false; - failMessage = "Opacity test mismatchs"; + failMessage = "Opacity test mismatches"; // CR 6994264 (Choice autohides dropdown on Solaris 10) skipClassNames = new String[] { "Choice" }; } private String testSeq; - private final static String checkSeq = "010000101"; + private static final String checkSeq = "010000101"; private Point heavyLoc; private JButton light; private Frame frame = null; @@ -89,6 +89,7 @@ public class OpaqueOverlapping extends OverlappingTestBase { panel.add(light); frame.add(panel); frame.setBounds(50, 50, 400, 400); + frame.setLocationRelativeTo(null); frame.setVisible(true); currentAwtControl.addMouseListener(new MouseAdapter() { diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/OverlappingTestBase.java b/test/jdk/java/awt/Mixing/AWT_Mixing/OverlappingTestBase.java index 794578a5907..3d4adecbd17 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/OverlappingTestBase.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/OverlappingTestBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -34,6 +34,7 @@ import java.awt.Robot; import java.awt.Scrollbar; import java.awt.TextField; import java.awt.Toolkit; +import java.awt.Window; import java.awt.event.InputEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; @@ -171,6 +172,7 @@ public abstract class OverlappingTestBase { frame.getContentPane().setBackground(AWT_BACKGROUND_COLOR); frame.setSize(size, size); frame.setUndecorated(true); + frame.setLocationRelativeTo(null); frame.setVisible(true); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); p[0] = frame.getLocation(); @@ -259,6 +261,9 @@ public abstract class OverlappingTestBase { embedder.setBackground(Color.RED); embedder.setPreferredSize(new Dimension(150, 150)); container.add(embedder); + if (container instanceof Window) { + ((Window) container).setLocationRelativeTo(null); + } container.setVisible(true); // create peer long frameWindow = 0; @@ -301,6 +306,7 @@ public abstract class OverlappingTestBase { EmbeddedFrame eframe = (EmbeddedFrame) eframeCtor.newInstance(frameWindow); setupControl(eframe); eframe.setSize(new Dimension(150, 150)); + eframe.setLocationRelativeTo(null); eframe.setVisible(true); // System.err.println(eframe.getSize()); } catch (Exception ex) { @@ -682,6 +688,7 @@ public abstract class OverlappingTestBase { failureMessage = whyFailed; mainThread.interrupt(); }//fail() + + static class TestPassedException extends RuntimeException { + } }// class LWComboBox -class TestPassedException extends RuntimeException { -} diff --git a/test/jdk/java/awt/Mixing/AWT_Mixing/SimpleOverlappingTestBase.java b/test/jdk/java/awt/Mixing/AWT_Mixing/SimpleOverlappingTestBase.java index 928a5c437cb..0dd42a36cd0 100644 --- a/test/jdk/java/awt/Mixing/AWT_Mixing/SimpleOverlappingTestBase.java +++ b/test/jdk/java/awt/Mixing/AWT_Mixing/SimpleOverlappingTestBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -21,10 +21,21 @@ * questions. */ -import java.awt.*; -import java.awt.event.*; -import java.util.regex.*; -import javax.swing.*; +import java.awt.Point; +import java.awt.Robot; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.SpringLayout; + import test.java.awt.regtesthelpers.Util; /** @@ -55,6 +66,10 @@ public abstract class SimpleOverlappingTestBase extends OverlappingTestBase { this.useDefaultClickValidation = defaultClickValidation; } + protected boolean isMultiFramesTest(){ + return true; + } + public SimpleOverlappingTestBase() { this(true); } @@ -114,6 +129,7 @@ public abstract class SimpleOverlappingTestBase extends OverlappingTestBase { propagateAWTControls(f); + f.setLocationRelativeTo(null); f.setVisible(true); } @@ -140,21 +156,29 @@ public abstract class SimpleOverlappingTestBase extends OverlappingTestBase { /* this is a workaround for certain jtreg(?) focus issue: tests fail starting after failing mixing tests but always pass alone. */ - JFrame ancestor = (JFrame)(testedComponent.getTopLevelAncestor()); - if( ancestor != null ) { - Point ancestorLoc = ancestor.getLocationOnScreen(); - ancestorLoc.translate(isOel7orLater() ? 5 : - ancestor.getWidth() / 2 - 15, 2); - robot.mouseMove(ancestorLoc.x, ancestorLoc.y); - Util.waitForIdle(robot); - robot.mousePress(InputEvent.BUTTON1_MASK); - robot.delay(50); - robot.mouseRelease(InputEvent.BUTTON1_MASK); - Util.waitForIdle(robot); + JFrame ancestor = (JFrame) (testedComponent.getTopLevelAncestor()); + if (ancestor != null) { + final CountDownLatch latch = new CountDownLatch(1); + ancestor.addFocusListener(new FocusAdapter() { + @Override public void focusGained(FocusEvent e) { + latch.countDown(); + } + }); + ancestor.requestFocus(); + try { + if (!latch.await(1L, TimeUnit.SECONDS)) { + throw new RuntimeException( + "Ancestor frame didn't receive focus"); + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } } clickAndBlink(robot, lLoc); - Util.waitForIdle(robot); + if (ancestor != null && isMultiFramesTest()) { + ancestor.dispose(); + } return wasLWClicked; } @@ -172,5 +196,4 @@ public abstract class SimpleOverlappingTestBase extends OverlappingTestBase { } return false; } - } From fb99ba6ccd6e6d7a0e717a1b9f2a80402af5c661 Mon Sep 17 00:00:00 2001 From: Damon Nguyen Date: Tue, 16 Dec 2025 21:19:33 +0000 Subject: [PATCH 027/390] 8373119: JDK 26 RDP1 L10n resource files update Reviewed-by: jlu, asemenyuk, almatvee --- .../launcher/resources/launcher_de.properties | 5 +- .../launcher/resources/launcher_ja.properties | 6 +- .../resources/launcher_zh_CN.properties | 8 +- .../keytool/resources/keytool_de.properties | 2 +- .../keytool/resources/keytool_ja.properties | 2 +- .../resources/keytool_zh_CN.properties | 2 +- .../util/resources/security_de.properties | 5 +- .../util/resources/security_ja.properties | 3 + .../util/resources/security_zh_CN.properties | 3 + .../javac/resources/compiler_de.properties | 69 ++++--- .../javac/resources/compiler_ja.properties | 69 ++++--- .../javac/resources/compiler_zh_CN.properties | 69 ++++--- .../tools/javac/resources/javac_de.properties | 24 ++- .../tools/javac/resources/javac_ja.properties | 26 +-- .../javac/resources/javac_zh_CN.properties | 26 +-- .../javac/resources/launcher_de.properties | 3 + .../javac/resources/launcher_ja.properties | 3 + .../javac/resources/launcher_zh_CN.properties | 3 + .../resources/jarsigner_de.properties | 1 + .../resources/jarsigner_ja.properties | 1 + .../resources/jarsigner_zh_CN.properties | 1 + .../sun/tools/jar/resources/jar_de.properties | 2 + .../sun/tools/jar/resources/jar_ja.properties | 2 + .../tools/jar/resources/jar_zh_CN.properties | 2 + .../html/resources/standard_de.properties | 6 + .../html/resources/standard_ja.properties | 6 + .../html/resources/standard_zh_CN.properties | 6 + .../toolkit/resources/doclets_de.properties | 8 +- .../toolkit/resources/doclets_ja.properties | 4 + .../resources/doclets_zh_CN.properties | 4 + .../tool/resources/javadoc_de.properties | 2 +- .../tools/jlink/resources/jlink_de.properties | 3 +- .../tools/jlink/resources/jlink_ja.properties | 3 +- .../jlink/resources/jlink_zh_CN.properties | 3 +- .../jlink/resources/plugins_de.properties | 12 +- .../jlink/resources/plugins_ja.properties | 12 +- .../jlink/resources/plugins_zh_CN.properties | 12 +- .../resources/LinuxResources_de.properties | 6 - .../resources/LinuxResources_ja.properties | 6 - .../resources/LinuxResources_zh_CN.properties | 6 - .../resources/MacResources_de.properties | 31 ++- .../resources/MacResources_ja.properties | 31 ++- .../resources/MacResources_zh_CN.properties | 33 ++-- .../resources/HelpResources_de.properties | 176 +++++++++++++++-- .../resources/HelpResources_ja.properties | 179 ++++++++++++++++-- .../resources/HelpResources_zh_CN.properties | 177 +++++++++++++++-- .../resources/MainResources_de.properties | 106 ++++++----- .../resources/MainResources_ja.properties | 106 ++++++----- .../resources/MainResources_zh_CN.properties | 106 ++++++----- .../resources/WinResources_de.properties | 8 - .../resources/WinResources_ja.properties | 8 - .../resources/WinResources_zh_CN.properties | 8 - 52 files changed, 976 insertions(+), 429 deletions(-) diff --git a/src/java.base/share/classes/sun/launcher/resources/launcher_de.properties b/src/java.base/share/classes/sun/launcher/resources/launcher_de.properties index 79b5968b210..e80869b868c 100644 --- a/src/java.base/share/classes/sun/launcher/resources/launcher_de.properties +++ b/src/java.base/share/classes/sun/launcher/resources/launcher_de.properties @@ -30,8 +30,8 @@ java.launcher.opt.vmselect =\ {0}\t zur Auswahl der "{1}" VM\n java.launcher.opt.hotspot =\ {0}\t ist ein Synonym für die "{1}" VM [verworfen]\n # Translators please note do not translate the options themselves -java.launcher.opt.footer = \ -cp \n -classpath \n --class-path \n Eine durch "{0}" getrennte Liste mit Verzeichnissen, JAR-Archiven\n und ZIP-Archiven, in denen nach Klassendateien gesucht wird.\n -p \n --module-path ...\n Eine durch "{0}" getrennte Liste mit Elementen, von denen jedes Element ein Dateipfad ist\n zu einem Modul oder einem Verzeichnis mit Modulen ist. Jedes Modul ist entweder\n ein modulares JAR oder ein entpacktes Modulverzeichnis.\n --upgrade-module-path ...\n Eine durch "{0}" getrennte Liste mit Elementen, von denen jedes Element ein Dateipfad ist\n zu einem Modul oder einem Verzeichnis mit Modulen ist,\n um upgradefähige Module im Laufzeitimage zu ersetzen. Jedes Modul ist entweder\n ein modulares JAR oder ein entpacktes Modulverzeichnis.\n --add-modules [,...]\n Root-Module, die zusätzlich zum anfänglichen Modul aufgelöst werden sollen.\n kann auch wie folgt lauten: ALL-DEFAULT, ALL-SYSTEM,\n ALL-MODULE-PATH.\n --enable-native-access [,...]\n Damit kann der Code in Modulen auf Code und Daten außerhalb der JRE zugreifen.\n kann auch ALL-UNNAMED sein, um den Code im Classpath anzugeben.\n --illegal-native-access=\n Zugriff auf Code und Daten außerhalb der JRE\n durch Code in Modulen zulassen oder verweigern, für die der native Zugriff nicht explizit aktiviert ist.\n ist "deny", "warn" oder "allow". Der Standardwert ist "warn".\n Diese Option wird in einem zukünftigen Release entfernt.\n --list-modules\n Listet beobachtbare Module auf und beendet den Vorgang\n -d \n --describe-module \n Beschreibt ein Modul und beendet den Vorgang\n --dry-run Erstellt eine VM und lädt die Hauptklasse, führt aber nicht die Hauptmethode aus.\n Die Option "--dry-run" kann nützlich sein, um die\n Befehlszeilenoptionen, wie die Modulsystemkonfiguration, zu validieren.\n --validate-modules\n Validiert alle Module und beendet den Vorgang\n Die Option "--validate-modules" kann nützlich sein, um\n Konflikte und andere Fehler mit Modulen auf dem Modulpfad zu ermitteln.\n -D=\n Legt eine Systemeigenschaft fest\n -verbose:[class|module|gc|jni]\n Aktiviert die Verbose-Ausgabe für das angegebene Subsystem\n -version Gibt die Produktversion an den Fehlerstream aus und beendet den Vorgang\n --version Gibt die Produktversion an den Outputstream aus und beendet den Vorgang\n -showversion Gibt die Produktversion an den Fehlerstream aus und setzt den Vorgang fort\n --show-version\n Gibt die Produktversion an den Outputstream aus und setzt den Vorgang fort\n --show-module-resolution\n Zeigt die Modulauflösungsausgabe beim Start an\n -? -h -help\n Gibt diese Hilfemeldung an den Fehlerstream aus\n --help Gibt diese Hilfemeldung an den Outputstream aus\n -X Gibt Hilfe zu zusätzlichen Optionen an den Fehlerstream aus\n --help-extra Gibt Hilfe zu zusätzlichen Optionen an den Outputstream aus\n -ea[:...|:]\n -enableassertions[:...|:]\n Aktiviert Assertions mit angegebener \ -Granularität\n -da[:...|:]\n -disableassertions[:...|:]\n Deaktiviert Assertions mit angegebener Granularität\n -esa | -enablesystemassertions\n Aktiviert System-Assertions\n -dsa | -disablesystemassertions\n Deaktiviert System-Assertions\n -agentlib:[=]\n Lädt die native Agent Library . Beispiel: -agentlib:jdwp\n siehe auch -agentlib:jdwp=help\n -agentpath:[=]\n Lädt die native Agent Library mit dem vollständigen Pfadnamen\n -javaagent:[=]\n Lädt den Java-Programmiersprachen-Agent, siehe java.lang.instrument\n -splash:\n Zeigt den Startbildschirm mit einem angegebenen Bild an\n Skalierte HiDPI-Bilder werden automatisch unterstützt und verwendet,\n falls verfügbar. Der nicht skalierte Bilddateiname (Beispiel: image.ext)\n muss immer als Argument an die Option "-splash" übergeben werden.\n Das am besten geeignete angegebene skalierte Bild wird\n automatisch ausgewählt.\n Weitere Informationen finden Sie in der Dokumentation zur SplashScreen-API\n @argument files\n Eine oder mehrere Argumentdateien mit Optionen\n --disable-@files\n Verhindert die weitere Erweiterung von Argumentdateien\n --enable-preview\n Lässt zu, das Klassen von Vorschaufeatures dieses Release abhängig sind\nUm ein Argument für eine lange Option anzugeben, können Sie --= oder\n-- verwenden.\n +java.launcher.opt.footer = \ -cp \n -classpath \n --class-path \n Eine durch "{0}" getrennte Liste mit Verzeichnissen, JAR-Archiven\n und ZIP-Archiven, in denen nach Klassendateien gesucht wird.\n -p \n --module-path ...\n Eine durch "{0}" getrennte Liste mit Elementen, von denen jedes Element ein Dateipfad ist\n zu einem Modul oder einem Verzeichnis mit Modulen ist. Jedes Modul ist entweder\n ein modulares JAR oder ein entpacktes Modulverzeichnis.\n --upgrade-module-path ...\n Eine durch "{0}" getrennte Liste mit Elementen, von denen jedes Element ein Dateipfad ist\n zu einem Modul oder einem Verzeichnis mit Modulen ist,\n um upgradefähige Module im Laufzeitimage zu ersetzen. Jedes Modul ist entweder\n ein modulares JAR oder ein entpacktes Modulverzeichnis.\n --add-modules [,...]\n Root-Module, die zusätzlich zum anfänglichen Modul aufgelöst werden sollen.\n kann auch wie folgt lauten: ALL-DEFAULT, ALL-SYSTEM,\n ALL-MODULE-PATH.\n --enable-native-access [,...]\n Damit kann der Code in Modulen auf Code und Daten außerhalb der JRE zugreifen.\n kann auch ALL-UNNAMED sein, um den Code im Classpath anzugeben.\n --illegal-native-access=\n Zugriff auf Code und Daten außerhalb der JRE\n durch Code in Modulen zulassen oder verweigern, für die der native Zugriff nicht explizit aktiviert ist.\n ist "deny", "warn" oder "allow". Der Standardwert ist "warn".\n Diese Option wird in einem zukünftigen Release entfernt.\n --enable-final-field-mutation [,...]\n Zulassen, dass die endgültigen Instanzfelder durch Code in den angegebenen Modulen mutiert werden.\n kann auch ALL-UNNAMED sein, um den Code im Classpath anzugeben.\n --illegal-final-field-mutation=\n Erlauben oder verweigern Sie die Mutation von endgültigen Feldern durch Code in Modulen, für die die Mutation\n von endgültigen Feldern nicht explizit aktiviert ist.\n ist "deny", "warn", "debug" oder "allow". Der Standardwert ist "warn".\n Diese Option wird in einem zukünftigen Release entfernt.\n --list-modules\n Listet beobachtbare Module auf und beendet den Vorgang\n -d \n --describe-module \n Beschreibt ein Modul und beendet den Vorgang\n --dry-run Erstellt eine VM und lädt die Hauptklasse, führt aber nicht die Hauptmethode aus.\n Die Option "--dry-run" kann nützlich sein, um die\n Befehlszeilenoptionen, wie die Modulsystemkonfiguration, zu validieren.\n --validate-modules\n Validiert alle Module und beendet den Vorgang\n Die Option "--validate-modules" kann nützlich sein, um\n Konflikte und andere Fehler mit Modulen auf dem Modulpfad zu ermitteln.\n -D=\n Legt eine Systemeigenschaft fest\n -verbose:[class|module|gc|jni]\n Aktiviert die Verbose-Ausgabe für das angegebene Subsystem\n -version Gibt die Produktversion an den Fehlerstream aus und beendet den Vorgang\n --version Gibt die Produktversion an den Outputstream aus und beendet den Vorgang\n -showversion Gibt die Produktversion an den Fehlerstream aus und \ +setzt den Vorgang fort\n --show-version\n Gibt die Produktversion an den Outputstream aus und setzt den Vorgang fort\n --show-module-resolution\n Zeigt die Modulauflösungsausgabe beim Start an\n -? -h -help\n Gibt diese Hilfemeldung an den Fehlerstream aus\n --help Gibt diese Hilfemeldung an den Outputstream aus\n -X Gibt Hilfe zu zusätzlichen Optionen an den Fehlerstream aus\n --help-extra Gibt Hilfe zu zusätzlichen Optionen an den Outputstream aus\n -ea[:...|:]\n -enableassertions[:...|:]\n Aktiviert Assertions mit angegebener Granularität\n -da[:...|:]\n -disableassertions[:...|:]\n Deaktiviert Assertions mit angegebener Granularität\n -esa | -enablesystemassertions\n Aktiviert System-Assertions\n -dsa | -disablesystemassertions\n Deaktiviert System-Assertions\n -agentlib:[=]\n Lädt die native Agent Library . Beispiel: -agentlib:jdwp\n siehe auch -agentlib:jdwp=help\n -agentpath:[=]\n Lädt die native Agent Library mit dem vollständigen Pfadnamen\n -javaagent:[=]\n Lädt den Java-Programmiersprachen-Agent, siehe java.lang.instrument\n -splash:\n Zeigt den Startbildschirm mit einem angegebenen Bild an\n Skalierte HiDPI-Bilder werden automatisch unterstützt und verwendet,\n falls verfügbar. Der nicht skalierte Bilddateiname (Beispiel: image.ext)\n muss immer als Argument an die Option "-splash" übergeben werden.\n Das am besten geeignete angegebene skalierte Bild wird\n automatisch ausgewählt.\n Weitere Informationen finden Sie in der Dokumentation zur SplashScreen-API\n @argument files\n Eine oder mehrere Argumentdateien mit Optionen\n --disable-@files\n Verhindert die weitere Erweiterung von Argumentdateien\n --enable-preview\n Lässt zu, das Klassen von Vorschaufeatures dieses Release abhängig sind\nUm ein Argument für eine lange Option anzugeben, können Sie --= oder\n-- verwenden.\n # Translators please note do not translate the options themselves java.launcher.X.usage=\n -Xbatch Deaktiviert die Hintergrundkompilierung\n -Xbootclasspath/a:\n An das Ende des Bootstrap Classpaths anhängen\n -Xcheck:jni Führt zusätzliche Prüfungen für JNI-Funktionen aus\n -Xcomp Erzwingt die Kompilierung von Methoden beim ersten Aufruf\n -Xdebug Führt keine Aktion aus. Ist veraltet und wird in einem zukünftigen Release entfernt.\n -Xdiag Zeigt zusätzliche Diagnosemeldungen an\n -Xint Nur Ausführung im interpretierten Modus\n -Xinternalversion\n Zeigt detailliertere JVM-Versionsinformationen an als die\n Option -version\n -Xlog: Konfiguriert oder aktiviert Logging mit dem einheitlichen Java Virtual\n Machine-(JVM-)Logging-Framework. Verwenden Sie -Xlog:help\n für weitere Einzelheiten.\n -Xloggc: Protokolliert den GC-Status in einer Datei mit Zeitstempeln.\n Diese Option ist veraltet und kann in einem\n zukünftigen Release entfernt werden. Wird durch -Xlog:gc: ersetzt.\n -Xmixed Ausführung im gemischten Modus (Standard)\n -Xmn Legt die anfängliche und maximale Größe (in Byte) des Heaps\n für die Young Generation (Nursery) fest\n -Xms Legt die minimale und die anfängliche Java-Heap-Größe fest\n -Xmx Legt die maximale Java-Heap-Größe fest\n -Xnoclassgc Deaktiviert die Klassen-Garbage Collection\n -Xrs Reduziert die Verwendung von BS-Signalen durch Java/VM (siehe Dokumentation)\n -Xshare:auto Verwendet freigegebene Klassendaten, wenn möglich (Standard)\n -Xshare:off Versucht nicht, freigegebene Klassendaten zu verwenden\n -Xshare:on Erfordert die Verwendung freigegebener Klassendaten, verläuft sonst nicht erfolgreich.\n Diese Testoption kann zeitweise zu\n Fehlern führen. Sie darf nicht in Produktionsumgebungen verwendet werden.\n -XshowSettings Zeigt alle Einstellungen an und fährt fort\n -XshowSettings:all\n Zeigt alle Einstellungen als Verbose-Ausgabe an und fährt fort\n -XshowSettings:locale\n Zeigt alle gebietsschemabezogenen Einstellungen an und fährt fort\n -XshowSettings:properties\n Zeigt alle Eigenschaftseinstellungen an und fährt fort\n -XshowSettings:vm\n Zeigt alle VM-bezogenen Einstellungen an und fährt fort\n -XshowSettings:security\n Zeigt alle Sicherheitseinstellungen an und fährt fort\n -XshowSettings:security:all\n Zeigt alle Sicherheitseinstellungen an und fährt fort\n -XshowSettings:security:properties\n Zeigt Sicherheitseigenschaften an und fährt fort\n -XshowSettings:security:providers\n Zeigt statische Sicherheitsprovidereinstellungen an und fährt fort\n -XshowSettings:security:tls\n Zeigt TLS-bezogene Sicherheitseinstellungen an und fährt fort\n -XshowSettings:system\n (Nur Linux) Zeigt die Konfiguration des Hostsystems oder Containers an\n und fährt fort\n -Xss Legt die Stackgröße des Java-Threads fest\n Die tatsächliche Größe kann auf ein Vielfaches der\n Systemseitengröße aufgerundet werden, wenn für das Betriebssystem erforderlich.\n -Xverify Legt den Modus der Bytecodeverifizierung fest\n \ @@ -58,6 +58,7 @@ java.launcher.jar.error3=kein Hauptmanifestattribut, in {0} java.launcher.jar.error4=Fehler beim Laden des Java-Agents in {0} java.launcher.jar.error5=Fehler: Beim Versuch, Datei {0} zu schließen, ist ein unerwarteter Fehler aufgetreten java.launcher.jar.error.illegal.ena.value=Fehler: Ungültiger Wert "{0}" für das Manifestattribut "Enable-Native-Access". Nur ''ALL-UNNAMED'' ist zulässig +java.launcher.jar.error.illegal.effm.value=Fehler: Ungültiger Wert "{0}" für das Manifestattribut "Enable-Final-Field-Mutation". Nur "ALL-UNNAMED" ist zulässig java.launcher.init.error=Initialisierungsfehler java.launcher.javafx.error1=Fehler: Die JavaFX-Methode launchApplication hat die falsche Signatur, sie\nmuss als statisch deklariert werden und einen Wert vom Typ VOID zurückgeben java.launcher.module.error1=Modul {0} weist kein ModuleMainClass-Attribut auf. Verwenden Sie -m / diff --git a/src/java.base/share/classes/sun/launcher/resources/launcher_ja.properties b/src/java.base/share/classes/sun/launcher/resources/launcher_ja.properties index 04b68db3a8e..49712b21c52 100644 --- a/src/java.base/share/classes/sun/launcher/resources/launcher_ja.properties +++ b/src/java.base/share/classes/sun/launcher/resources/launcher_ja.properties @@ -31,8 +31,9 @@ java.launcher.opt.hotspot =\ {0}\t は"{1}" VMのシノニムです [非 # Translators please note do not translate the options themselves java.launcher.opt.footer = \ -cp <ディレクトリおよびzip/jarファイルのクラス検索パス>\n -classpath <ディレクトリおよびzip/jarファイルのクラス検索パス>\n --class-path <ディレクトリおよびzip/jarファイルのクラス検索パス>\n "{0}"区切りリスト(ディレクトリ、JARアーカイブ、\n ZIPアーカイブ)で、クラス・ファイルの検索用。\n -p \n --module-path ...\n 要素を"{0}"で区切ったリストで、各要素は次へのファイル・パスです:\n モジュール、またはモジュールが格納されているディレクトリ。各モジュールは次のいずれかです:\n モジュラJARまたは展開形式のモジュール・ディレクトリ。\n --upgrade-module-path ...\n 要素を"{0}"で区切ったリストで、各要素は次へのファイル・パスです:\n モジュール、またはモジュールが格納されているディレクトリで、次のものを置き換えます:\n ランタイム・イメージのアップグレード可能なモジュール。各モジュールは次のいずれかです:\n モジュラJARまたは展開形式のモジュール・ディレクトリ。\n --add-modules [,...]\n 初期モジュールに加えて解決するルート・モジュール。\n には次も指定できます: ALL-DEFAULT、ALL-SYSTEM、\n ALL-MODULE-PATH.\n --enable-native-access [,...]\n モジュール内のコードをJavaランタイムの外のコードおよびデータにアクセスさせることができます。\n は、クラス・パス上のコードを指定するためにALL-UNNAMEDにもできます。\n --illegal-native-access=\n Javaランタイムの外のコードおよびデータへのアクセスを許可または拒否します\n (ネイティブ・アクセスが明示的に有効化されていないモジュール内のコードによる)。\n \ -は、"deny"、"warn"または"allow"のいずれかです。デフォルト値は"warn"です。\n このオプションは、将来のリリースで削除される予定です。\n --list-modules\n 参照可能なモジュールをリストし終了します\n -d \n --describe-module \n モジュールを説明し終了します\n --dry-run VMを作成しメイン・クラスをロードしますが、メイン・メソッドは実行しません。\n --dry-runオプションは、次の検証に役立つ場合があります:\n モジュール・システム構成などのコマンド行オプション。\n --validate-modules\n すべてのモジュールを検証し終了します\n --validate-modulesオプションは、次の検索に役立つ場合があります:\n モジュール・パス上のモジュールでの競合およびその他のエラー。\n -D=\n システム・プロパティを設定します\n -verbose:[class|module|gc|jni]\n 特定のサブシステムで詳細出力を有効にする\n -version 製品バージョンをエラー・ストリームに出力して終了します\n --version 製品バージョンを出力ストリームに出力して終了します\n -showversion 製品バージョンをエラー・ストリームに出力して続行します\n --show-version\n 製品バージョンを出力ストリームに出力して続行します\n --show-module-resolution\n 起動時にモジュール解決出力を表示します\n -? -h -help\n このヘルプ・メッセージをエラー・ストリームに出力します\n --help このヘルプ・メッセージを出力ストリームに出力します\n -X 追加オプションのヘルプをエラー・ストリームに出力します\n --help-extra 追加オプションのヘルプを出力ストリームに出力します\n -ea[:...|:]\n -enableassertions[:...|:]\n 指定した粒度でアサーションを有効にします\n -da[:...|:]\n \ --disableassertions[:...|:]\n 指定した粒度でアサーションを無効にします\n -esa | -enablesystemassertions\n システム・アサーションを有効にします\n -dsa | -disablesystemassertions\n システム・アサーションを無効にします\n -agentlib:[=]\n ネイティブ・エージェント・ライブラリをロードします。例: -agentlib:jdwp\n -agentlib:jdwp=helpも参照してください\n -agentpath:[=]\n フルパス名を使用して、ネイティブ・エージェント・ライブラリをロードします\n -javaagent:[=]\n Javaプログラミング言語エージェントをロードします。java.lang.instrumentを参照してください\n -splash:\n 指定されたイメージを含むスプラッシュ画面を表示します\n HiDPIスケールのイメージが自動的にサポートされて使用されます\n (可能な場合)。スケーリングされないイメージのファイル名(image.extなど)を\n 引数として-splashオプションに必ず渡す必要があります。\n 指定された最も適切なスケーリング済イメージが選択されます\n (自動的)。\n 詳細は、SplashScreen APIのドキュメントを参照してください\n @argumentファイル\n オプションを含む1つ以上の引数ファイル\n --disable-@files\n さらなる引数ファイル拡張を無効にします\n --enable-preview\n クラスをこのリリースのプレビュー機能に依存させることができます\n長いオプションの引数を指定する場合、--=または\n-- を使用できます。\n +は、"deny"、"warn"または"allow"のいずれかです。デフォルト値は"warn"です。\n このオプションは、将来のリリースで削除される予定です。\n --enable-final-field-mutation [,...]\n 指定されたモジュールのコードで、finalインスタンス・フィールドを変更できます。\n は、クラス・パス上のコードを指定するためにALL-UNNAMEDにもできます。\n --illegal-final-field-mutation=\n finalのモジュール内のコードによるfinalフィールド変更を許可または拒否します\n フィールド変更は明示的に有効化されていません。\n は、"deny"、"warn"、"debug"または"allow"のいずれかです。デフォルト値は"warn"です。\n このオプションは、将来のリリースで削除される予定です。\n --list-modules\n 参照可能なモジュールをリストし終了します\n -d \n --describe-module \n モジュールを説明し終了します\n --dry-run VMを作成しメイン・クラスをロードしますが、メイン・メソッドは実行しません。\n --dry-runオプションは、次の検証に役立つ場合があります:\n モジュール・システム構成などのコマンド行オプション。\n --validate-modules\n すべてのモジュールを検証し終了します\n --validate-modulesオプションは、次の検索に役立つ場合があります:\n モジュール・パス上のモジュールでの競合およびその他のエラー。\n -D=\n システム・プロパティを設定します\n -verbose:[class|module|gc|jni]\n 特定のサブシステムで詳細出力を有効にする\n -version 製品バージョンをエラー・ストリームに出力して終了します\n --version 製品バージョンを出力ストリームに出力して終了します\n -showversion 製品バージョンをエラー・ストリームに出力して続行します\n --show-version\n \ + 製品バージョンを出力ストリームに出力して続行します\n --show-module-resolution\n 起動時にモジュール解決出力を表示します\n -? -h -help\n このヘルプ・メッセージをエラー・ストリームに出力します\n --help このヘルプ・メッセージを出力ストリームに出力します\n -X 追加オプションのヘルプをエラー・ストリームに出力します\n --help-extra 追加オプションのヘルプを出力ストリームに出力します\n -ea[:...|:]\n -enableassertions[:...|:]\n 指定した粒度でアサーションを有効にします\n -da[:...|:]\n -disableassertions[:...|:]\n 指定した粒度でアサーションを無効にします\n -esa | -enablesystemassertions\n システム・アサーションを有効にします\n -dsa | -disablesystemassertions\n システム・アサーションを無効にします\n -agentlib:[=]\n ネイティブ・エージェント・ライブラリをロードします。例: -agentlib:jdwp\n -agentlib:jdwp=helpも参照してください\n -agentpath:[=]\n フルパス名を使用して、ネイティブ・エージェント・ライブラリをロードします\n -javaagent:[=]\n Javaプログラミング言語エージェントをロードします。java.lang.instrumentを参照してください\n -splash:\n 指定されたイメージを含むスプラッシュ画面を表示します\n HiDPIスケールのイメージが自動的にサポートされて使用されます\n (可能な場合)。スケーリングされないイメージのファイル名(image.extなど)を\n 引数として-splashオプションに必ず渡す必要があります。\n 指定された最も適切なスケーリング済イメージが選択されます\n (自動的)。\n 詳細は、SplashScreen APIのドキュメントを参照してください\n @argumentファイル\n \ +オプションを含む1つ以上の引数ファイル\n --disable-@files\n さらなる引数ファイル拡張を無効にします\n --enable-preview\n クラスをこのリリースのプレビュー機能に依存させることができます\n長いオプションの引数を指定する場合、--=または\n-- を使用できます。\n # Translators please note do not translate the options themselves java.launcher.X.usage=\n -Xbatch バックグラウンド・コンパイルを無効にします\n -Xbootclasspath/a:\n ブートストラップ・クラス・パスの最後に追加します\n -Xcheck:jni JNI関数に対する追加のチェックを実行します\n -Xcomp 初回呼出し時にメソッドのコンパイルを強制します\n -Xdebug 何も実行されません。将来のリリースで削除されるため、非推奨になりました。\n -Xdiag 追加の診断メッセージを表示します\n -Xint インタプリタ・モードの実行のみ\n -Xinternalversion\n -versionオプションより詳細なJVMバージョン情報を\n 表示します\n -Xlog: Java Virtual Machine (JVM)統合ロギング・フレームワークでの\n ロギングを構成または有効化します。詳細は、-Xlog:helpを\n 使用してください。\n -Xloggc: タイムスタンプが付いたファイルにGCステータスのログを記録します\n このオプションは非推奨であり、将来のリリースで削除される\n 可能性があります。-Xlog:gc:で置換されています。\n -Xmixed 混合モードの実行(デフォルト)\n -Xmn 若い世代(ナーサリ)のヒープの初期サイズおよび最大サイズ\n (バイト単位)を設定します\n -Xms Javaの最小および初期のヒープ・サイズを設定します\n -Xmx Javaの最大ヒープ・サイズを設定します\n -Xnoclassgc クラスのガベージ・コレクションを無効にします\n -Xrs Java/VMによるOSシグナルの使用を削減します(ドキュメントを参照)\n -Xshare:auto 可能であれば共有クラス・データを使用します(デフォルト)\n -Xshare:off 共有クラス・データの使用を試みません\n -Xshare:on 共有クラス・データの使用を必須にし、できなければ失敗します。\n \ @@ -60,6 +61,7 @@ java.launcher.jar.error3={0}にメイン・マニフェスト属性がありま java.launcher.jar.error4={0}内のJavaエージェントのロード中にエラーが発生しました java.launcher.jar.error5=エラー: ファイル{0}を閉じるときに、予期しないエラーが発生しました java.launcher.jar.error.illegal.ena.value=エラー: Enable-Native-Accessマニフェスト属性の値"{0}"が不正です。''ALL-UNNAMED''のみ許可されます +java.launcher.jar.error.illegal.effm.value=エラー: Enable-Final-Field-Mutationマニフェスト属性の値"{0}"が不正です。''ALL-UNNAMED''のみ許可されます java.launcher.init.error=初期化エラー java.launcher.javafx.error1=エラー: JavaFX launchApplicationメソッドに誤ったシグネチャがあり、\nstaticを宣言してvoid型の値を返す必要があります java.launcher.module.error1=モジュール{0}にModuleMainClass属性がありません。-m /を使用してください diff --git a/src/java.base/share/classes/sun/launcher/resources/launcher_zh_CN.properties b/src/java.base/share/classes/sun/launcher/resources/launcher_zh_CN.properties index ec466bf3019..b3c0268f953 100644 --- a/src/java.base/share/classes/sun/launcher/resources/launcher_zh_CN.properties +++ b/src/java.base/share/classes/sun/launcher/resources/launcher_zh_CN.properties @@ -30,8 +30,9 @@ java.launcher.opt.vmselect =\ {0}\t 选择 "{1}" VM\n java.launcher.opt.hotspot =\ {0}\t 是 "{1}" VM 的同义词 [已过时]\n # Translators please note do not translate the options themselves -java.launcher.opt.footer = \ -cp <目录和 zip/jar 文件的类搜索路径>\n -classpath <目录和 zip/jar 文件的类搜索路径>\n --class-path <目录和 zip/jar 文件的类搜索路径>\n 以 "{0}" 分隔的用于搜索类文件的目录、JAR 档案\n 和 ZIP 档案列表。\n -p <模块路径>\n --module-path <模块路径>...\n 以 "{0}" 分隔的元素列表,每个元素都是\n 模块或包含模块的目录的文件路径。每个模块都是\n 模块化 JAR 或展开的模块目录。\n --upgrade-module-path <模块路径>...\n 以 "{0}" 分隔的元素列表,每个元素都是\n 模块或包含模块(用于替换运行时映像中的\n 可升级模块)的目录的文件路径。每个模块都是\n 模块化 JAR 或展开的模块目录。\n --add-modules <模块名称>[,<模块名称>...]\n 除了初始模块之外要解析的根模块。\n <模块名称> 还可以为 ALL-DEFAULT, ALL-SYSTEM,\n ALL-MODULE-PATH.\n --enable-native-access [,...]\n 允许模块中的代码访问 Java 运行时之外的代码和数据。\n 也可以是 ALL-UNNAMED,以指示类路径上的代码。\n --illegal-native-access=\n 允许或拒绝模块中没有明确为其启用本机访问的\n 代码访问 Java 运行时之外的代码和数据。\n 为 "deny"、"warn" 或 "allow" 之一。默认值为 "warn"。\n 此选项将在未来发行版中删除。\n --list-modules\n 列出可观察模块并退出\n -d \n --describe-module <模块名称>\n 描述模块并退出\n --dry-run 创建 VM 并加载主类, 但不执行 main 方法。\n 此 --dry-run 选项对于验证诸如\n 模块系统配置这样的命令行选项可能非常有用。\n --validate-modules\n 验证所有模块并退出\n --validate-modules 选项对于查找\n 模块路径中模块的冲突及其他错误可能非常有用。\n -D<名称>=<值>\n 设置系统属性\n -verbose:[class|module|gc|jni]\n 为给定子系统启用详细输出\n -version 将产品版本输出到错误流并退出\n --version \ -将产品版本输出到输出流并退出\n -showversion 将产品版本输出到错误流并继续\n --show-version\n 将产品版本输出到输出流并继续\n --show-module-resolution\n 在启动过程中显示模块解析输出\n -? -h -help\n 将此帮助消息输出到错误流\n --help 将此帮助消息输出到输出流\n -X 将额外选项的帮助输出到错误流\n --help-extra 将额外选项的帮助输出到输出流\n -ea[:<程序包名称>...|:<类名>]\n -enableassertions[:<程序包名称>...|:<类名>]\n 按指定的粒度启用断言\n -da[:<程序包名称>...|:<类名>]\n -disableassertions[:<程序包名称>...|:<类名>]\n 按指定的粒度禁用断言\n -esa | -enablesystemassertions\n 启用系统断言\n -dsa | -disablesystemassertions\n 禁用系统断言\n -agentlib:<库名>[=<选项>]\n 加载本机代理库 <库名>, 例如 -agentlib:jdwp\n 另请参阅 -agentlib:jdwp=help\n -agentpath:<路径名>[=<选项>]\n 按完整路径名加载本机代理库\n -javaagent:[=<选项>]\n 加载 Java 编程语言代理, 请参阅 java.lang.instrument\n -splash:<图像路径>\n 使用指定的图像显示启动屏幕\n 自动支持和使用 HiDPI 缩放图像\n (如果可用)。应始终将未缩放的图像文件名 (例如, image.ext)\n 作为参数传递给 -splash 选项。\n 将自动选取提供的最合适的缩放\n 图像。\n 有关详细信息, 请参阅 SplashScreen API 文档\n @argument 文件\n 一个或多个包含选项的参数文件\n --disable-@files\n 阻止进一步扩展参数文件\n --enable-preview\n 允许类依赖于此发行版的预览功能\n要为长选项指定参数, 可以使用 --<名称>=<值> 或\n--<名称> <值>。\n +java.launcher.opt.footer = \ -cp <目录和 zip/jar 文件的类搜索路径>\n -classpath <目录和 zip/jar 文件的类搜索路径>\n --class-path <目录和 zip/jar 文件的类搜索路径>\n 以 "{0}" 分隔的用于搜索类文件的目录、JAR 档案\n 和 ZIP 档案列表。\n -p <模块路径>\n --module-path <模块路径>...\n 以 "{0}" 分隔的元素列表,每个元素都是\n 模块或包含模块的目录的文件路径。每个模块都是\n 模块化 JAR 或展开的模块目录。\n --upgrade-module-path <模块路径>...\n 以 "{0}" 分隔的元素列表,每个元素都是\n 模块或包含模块(用于替换运行时映像中的\n 可升级模块)的目录的文件路径。每个模块都是\n 模块化 JAR 或展开的模块目录。\n --add-modules <模块名称>[,<模块名称>...]\n 除了初始模块之外要解析的根模块。\n <模块名称> 还可以为 ALL-DEFAULT, ALL-SYSTEM,\n ALL-MODULE-PATH.\n --enable-native-access [,...]\n 允许模块中的代码访问 Java 运行时之外的代码和数据。\n 也可以是 ALL-UNNAMED,以指示类路径上的代码。\n --illegal-native-access=\n 允许或拒绝模块中没有明确为其启用本机访问的\n 代码访问 Java 运行时之外的代码和数据。\n 为 "deny"、"warn" 或 "allow" 之一。默认值为 "warn"。\n 此选项将在未来发行版中删除。\n --enable-final-field-mutation [,...]\n 允许指定模块中的代码变更最终实例字段。\n 也可以是 ALL-UNNAMED,以指示类路径上的代码。\n --illegal-final-field-mutation=\n 允许或拒绝模块中的代码在未明确启用最终字段变更时\n 变更最终字段。\n 为 "deny"、"warn"、"debug" 或 "allow" 之一。默认值为 "warn"。\n 此选项将在未来发行版中删除。\n --list-modules\n 列出可观察模块并退出\n -d \n --describe-module <模块名称>\n 描述模块并退出\n --dry-run 创建 VM 并加载主类, 但不执行 main 方法。\n 此 --dry-run \ +选项对于验证诸如\n 模块系统配置这样的命令行选项可能非常有用。\n --validate-modules\n 验证所有模块并退出\n --validate-modules 选项对于查找\n 模块路径中模块的冲突及其他错误可能非常有用。\n -D<名称>=<值>\n 设置系统属性\n -verbose:[class|module|gc|jni]\n 为给定子系统启用详细输出\n -version 将产品版本输出到错误流并退出\n --version 将产品版本输出到输出流并退出\n -showversion 将产品版本输出到错误流并继续\n --show-version\n 将产品版本输出到输出流并继续\n --show-module-resolution\n 在启动过程中显示模块解析输出\n -? -h -help\n 将此帮助消息输出到错误流\n --help 将此帮助消息输出到输出流\n -X 将额外选项的帮助输出到错误流\n --help-extra 将额外选项的帮助输出到输出流\n -ea[:<程序包名称>...|:<类名>]\n -enableassertions[:<程序包名称>...|:<类名>]\n 按指定的粒度启用断言\n -da[:<程序包名称>...|:<类名>]\n -disableassertions[:<程序包名称>...|:<类名>]\n 按指定的粒度禁用断言\n -esa | -enablesystemassertions\n 启用系统断言\n -dsa | -disablesystemassertions\n 禁用系统断言\n -agentlib:<库名>[=<选项>]\n 加载本机代理库 <库名>, 例如 -agentlib:jdwp\n 另请参阅 -agentlib:jdwp=help\n -agentpath:<路径名>[=<选项>]\n 按完整路径名加载本机代理库\n -javaagent:[=<选项>]\n 加载 Java 编程语言代理, 请参阅 java.lang.instrument\n -splash:<图像路径>\n 使用指定的图像显示启动屏幕\n 自动支持和使用 HiDPI 缩放图像\n (如果可用)。应始终将未缩放的图像文件名 (例如, image.ext)\n 作为参数传递给 -splash 选项。\n 将自动选取提供的最合适的缩放\n 图像。\n 有关详细信息, 请参阅 SplashScreen API 文档\n @argument 文件\n 一个或多个包含选项的参数文件\n --disable-@files\n 阻止进一步扩展参数文件\n --enable-preview\n \ +允许类依赖于此发行版的预览功能\n要为长选项指定参数, 可以使用 --<名称>=<值> 或\n--<名称> <值>。\n # Translators please note do not translate the options themselves java.launcher.X.usage=\n -Xbatch 禁用后台编译\n -Xbootclasspath/a:<以 {0} 分隔的目录和 zip/jar 文件>\n 附加在引导类路径末尾\n -Xcheck:jni 对 JNI 函数执行其他检查\n -Xcomp 强制在首次调用时编译方法\n -Xdebug 不执行任何操作;已过时,将在未来发行版中删除。\n -Xdiag 显示附加诊断消息\n -Xint 仅解释模式执行\n -Xinternalversion\n 显示比 -version 选项更详细的\n JVM 版本信息\n -Xlog: 配置或启用采用 Java 虚拟\n 机 (Java Virtual Machine, JVM) 统一记录框架进行事件记录。使用 -Xlog:help\n 可了解详细信息。\n -Xloggc: 将 GC 状态记录在文件中(带时间戳)。\n 此选项已过时,可能会在\n 将来的发行版中删除。它将替换为 -Xlog:gc:。\n -Xmixed 混合模式执行(默认值)\n -Xmn 为年轻代(新生代)设置初始和最大堆大小\n (以字节为单位)\n -Xms 设置最小和初始 Java 堆大小\n -Xmx 设置最大 Java 堆大小\n -Xnoclassgc 禁用类垃圾收集\n -Xrs 减少 Java/VM 对操作系统信号的使用(请参见文档)\n -Xshare:auto 在可能的情况下使用共享类数据(默认值)\n -Xshare:off 不尝试使用共享类数据\n -Xshare:on 要求使用共享类数据,否则将失败。\n 这是一个测试选项,可能导致间歇性\n 故障。不应在生产环境中使用它。\n -XshowSettings 显示所有设置并继续\n -XshowSettings:all\n 详细显示所有设置并继续\n -XshowSettings:locale\n 显示所有与区域设置相关的设置并继续\n -XshowSettings:properties\n 显示所有属性设置并继续\n -XshowSettings:vm\n 显示所有与 vm 相关的设置并继续\n -XshowSettings:security\n 显示所有安全设置并继续\n -XshowSettings:security:all\n 显示所有安全设置并继续\n -XshowSettings:security:properties\n 显示安全属性并继续\n -XshowSettings:security:providers\n 显示静态安全提供方设置并继续\n -XshowSettings:security:tls\n 显示与 TLS \ @@ -49,7 +50,7 @@ java.launcher.cls.error2=错误: 在类 {0} 中找不到 main 方法, 请将 mai java.launcher.cls.error3=错误: 缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序 java.launcher.cls.error4=错误: 加载主类 {0} 时出现 LinkageError\n\t{1} java.launcher.cls.error5=错误: 无法初始化主类 {0}\n原因: {1}: {2} -java.launcher.cls.error6=错误:在类 {0} 中未找到非专用零参数构造器\n请从现有构造器中删除专用,或者定义为:\n public {0}() +java.launcher.cls.error6=错误:在类 {0} 中未找到非专用零参数构造器\n请从现有构造器中删除 private,或者定义为:\n public {0}() java.launcher.cls.error7=错误:无法调用非静态内部类 {0} 构造器\n请将内部类设为静态或将内部类移出到单独的源文件 java.launcher.cls.error8=错误:无法实例化抽象类 {0}\n请使用具体类 java.launcher.jar.error1=错误: 尝试打开文件{0}时出现意外错误 @@ -58,6 +59,7 @@ java.launcher.jar.error3={0}中没有主清单属性 java.launcher.jar.error4=在 {0} 中加载 Java 代理时出错 java.launcher.jar.error5=错误:尝试关闭文件 {0} 时出现意外错误 java.launcher.jar.error.illegal.ena.value=错误:Enable-Native-Access 清单属性的值 "{0}" 非法。仅允许使用 ''ALL-UNNAMED'' +java.launcher.jar.error.illegal.effm.value=错误:Enable-Final-Field-Mutation 清单属性的值 "{0}" 非法。仅允许使用 ''ALL-UNNAMED'' java.launcher.init.error=初始化错误 java.launcher.javafx.error1=错误: JavaFX launchApplication 方法具有错误的签名, 必须\n将方法声明为静态方法并返回空类型的值 java.launcher.module.error1=模块 {0} 不具有 ModuleMainClass 属性,请使用 -m <模块>/<主类> diff --git a/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_de.properties b/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_de.properties index 1c7a9cd17cf..a452dd34e9d 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_de.properties +++ b/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_de.properties @@ -313,7 +313,7 @@ Unable.to.parse.denyAfter.string.in.exception.message=denyAfter-Datumszeichenfol whose.sigalg.weak=%1$s verwendet den Signaturalgorithmus %2$s. Dies gilt als Sicherheitsrisiko. whose.key.disabled=%1$s verwendet %2$s. Dies gilt als Sicherheitsrisiko und ist deaktiviert. whose.key.weak=%1$s verwendet %2$s. Das gilt als Sicherheitsrisiko. Dieser Schlüssel wird in einem zukünftigen Update deaktiviert. -jks.storetype.warning=Der %1$s-Keystore verwendet ein proprietäres Format. Es wird empfohlen, auf PKCS12 zu migrieren, das ein Industriestandardformat mit "keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12" ist. +jks.storetype.warning=%1$s verwendet veraltete kryptografische Algorithmen und wird in einer zukünftigen Version entfernt. Migrieren Sie zu PKCS12 mit:\nkeytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12 migrate.keystore.warning="%1$s" zu %4$s migriert. Der %2$s-Keystore wurde als "%3$s" gesichert. backup.keystore.warning=Der ursprüngliche Keystore "%1$s" wird als "%3$s" gesichert... importing.keystore.status=Keystore %1$s wird in %2$s importiert... diff --git a/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_ja.properties b/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_ja.properties index 63ba4f220dd..a3d7771eb38 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_ja.properties +++ b/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_ja.properties @@ -313,7 +313,7 @@ Unable.to.parse.denyAfter.string.in.exception.message=例外メッセージのde whose.sigalg.weak=%1$sは%2$s署名アルゴリズムを使用しており、これはセキュリティ・リスクとみなされます。 whose.key.disabled=%1$sは%2$sを使用しており、これはセキュリティ・リスクとみなされ、無効化されています。 whose.key.weak=%1$sは%2$sを使用しており、これはセキュリティ・リスクとみなされます。これは将来の更新で無効化されます。 -jks.storetype.warning=%1$sキーストアは独自の形式を使用しています。"keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12"を使用する業界標準の形式であるPKCS12に移行することをお薦めします。 +jks.storetype.warning=%1$sは古い暗号化アルゴリズムを使用しているため、将来のリリースで削除されます。次を使用してPKCS12に移行します:\nkeytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12 migrate.keystore.warning="%1$s"が%4$sに移行されました。%2$sキーストアは"%3$s"としてバックアップされます。 backup.keystore.warning=元のキーストア"%1$s"は"%3$s"としてバックアップされます... importing.keystore.status=キーストア%1$sを%2$sにインポートしています... diff --git a/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_zh_CN.properties b/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_zh_CN.properties index 1f96aa12c57..435e74e468f 100644 --- a/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_zh_CN.properties +++ b/src/java.base/share/classes/sun/security/tools/keytool/resources/keytool_zh_CN.properties @@ -313,7 +313,7 @@ Unable.to.parse.denyAfter.string.in.exception.message=无法解析异常错误 whose.sigalg.weak=%1$s 使用的 %2$s 签名算法存在安全风险。 whose.key.disabled=%1$s 使用的 %2$s 被视为存在安全风险而且被禁用。 whose.key.weak=%1$s 使用的 %2$s 被视为存在安全风险。它将在未来的更新中被禁用。 -jks.storetype.warning=%1$s 密钥库使用专用格式。建议使用 "keytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12" 迁移到行业标准格式 PKCS12。 +jks.storetype.warning=%1$s 使用的加密算法已过时,将在未来发行版中删除。请使用以下命令迁移到 PKCS12:\nkeytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12 migrate.keystore.warning=已将 "%1$s" 迁移到 %4$s。将 %2$s 密钥库作为 "%3$s" 进行了备份。 backup.keystore.warning=已将原始密钥库 "%1$s" 备份为 "%3$s"... importing.keystore.status=正在将密钥库 %1$s 导入到 %2$s... diff --git a/src/java.base/share/classes/sun/security/util/resources/security_de.properties b/src/java.base/share/classes/sun/security/util/resources/security_de.properties index a431268831b..63c7fdca472 100644 --- a/src/java.base/share/classes/sun/security/util/resources/security_de.properties +++ b/src/java.base/share/classes/sun/security/util/resources/security_de.properties @@ -43,7 +43,7 @@ provided.null.OID.map=Null-OID-Zuordnung angegeben NEWLINE=\n invalid.null.action.provided=Ungültige Nullaktion angegeben invalid.null.Class.provided=Ungültige Nullklasse angegeben -Subject.=Subjekt:\n +Subject.=Subject:\n .Principal.=\tPrincipal:\u0020 .Public.Credential.=\tÖffentliche Zugangsdaten:\u0020 .Private.Credential.=\tPrivate Zugangsdaten:\u0020 @@ -74,3 +74,6 @@ line.number.expected.expect.found.actual.=Zeile {0}: [{1}] erwartet, [{2}] gefun # sun.security.pkcs11.SunPKCS11 PKCS11.Token.providerName.Password.=Kennwort für PKCS11-Token [{0}]:\u0020 + +# sun.security.util.Password +warning.input.may.be.visible.on.screen=[Warnung: Eingabe ist möglicherweise auf dem Bildschirm sichtbar]\u0020 diff --git a/src/java.base/share/classes/sun/security/util/resources/security_ja.properties b/src/java.base/share/classes/sun/security/util/resources/security_ja.properties index ff13b37cf3b..00d22e054a5 100644 --- a/src/java.base/share/classes/sun/security/util/resources/security_ja.properties +++ b/src/java.base/share/classes/sun/security/util/resources/security_ja.properties @@ -74,3 +74,6 @@ line.number.expected.expect.found.actual.=行{0}: [{1}]ではなく[{2}]が検 # sun.security.pkcs11.SunPKCS11 PKCS11.Token.providerName.Password.=PKCS11トークン[{0}]パスワード:\u0020 + +# sun.security.util.Password +warning.input.may.be.visible.on.screen=[警告: 入力が画面に表示される場合があります]\u0020 diff --git a/src/java.base/share/classes/sun/security/util/resources/security_zh_CN.properties b/src/java.base/share/classes/sun/security/util/resources/security_zh_CN.properties index 6a4ec11de77..a322cb7b1e8 100644 --- a/src/java.base/share/classes/sun/security/util/resources/security_zh_CN.properties +++ b/src/java.base/share/classes/sun/security/util/resources/security_zh_CN.properties @@ -74,3 +74,6 @@ line.number.expected.expect.found.actual.=行号 {0}: 应为 [{1}], 找到 [{2}] # sun.security.pkcs11.SunPKCS11 PKCS11.Token.providerName.Password.=PKCS11 标记 [{0}] 密码:\u0020 + +# sun.security.util.Password +warning.input.may.be.visible.on.screen=[警告:输入可能显示在屏幕上]\u0020 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_de.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_de.properties index 0787c839cb4..b8fa413adba 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_de.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_de.properties @@ -292,10 +292,10 @@ compiler.err.annotation.decl.not.allowed.here=Annotationsschnittstellendeklarati compiler.err.cant.inherit.from.final=Erben aus finalem {0}-Element nicht möglich # 0: symbol or name -compiler.err.cant.ref.before.ctor.called={0} kann nicht referenziert werden, bevor der Supertypkonstruktor aufgerufen wurde +compiler.err.cant.ref.before.ctor.called=Referenz zu {0} darf nur nach einem expliziten Konstruktoraufruf angezeigt werden # 0: symbol or name -compiler.err.cant.assign.initialized.before.ctor.called=Initialisiertes Feld "{0}" kann nicht zugewiesen werden, bevor der Supertypkonstruktor aufgerufen wurde +compiler.err.cant.assign.initialized.before.ctor.called=Zuweisung zu initialisiertem Feld "{0}" darf nur nach einem expliziten Konstruktoraufruf angezeigt werden compiler.err.cant.select.static.class.from.param.type=Statische Klasse kann nicht aus einem parametrisierten Typ ausgewählt werden @@ -649,11 +649,14 @@ compiler.err.limit.string.overflow=UTF8-Darstellung für Zeichenfolge "{0}..." i compiler.err.malformed.fp.lit=Nicht wohlgeformtes Gleitkommaliteral -compiler.err.method.does.not.override.superclass=Methode überschreibt oder implementiert keine Methode aus einem Supertyp +# 0: symbol, 1: symbol +compiler.err.method.does.not.override.superclass={0} in {1} überschreibt oder implementiert keine Methode aus einem Supertyp -compiler.err.static.methods.cannot.be.annotated.with.override=Statische Methoden können nicht mit @Override-Annotation versehen werden +# 0: symbol, 1: symbol +compiler.err.static.methods.cannot.be.annotated.with.override=Statische Methode {0} in {1} kann nicht mit @Override-Annotation versehen werden -compiler.err.missing.meth.body.or.decl.abstract=Methodenbody fehlt oder als abstrakt deklarieren +# 0: symbol, 1: symbol +compiler.err.missing.meth.body.or.decl.abstract=In Methode {0} in {1} fehlt ein Methodenbody, oder sie muss als abstrakt deklariert werden compiler.err.missing.ret.stmt=Rückgabeanweisung fehlt @@ -1139,6 +1142,7 @@ compiler.err.multi-module.outdir.cannot.be.exploded.module=Im Modus für mehrere # 0: path # lint: path +# flags: default-enabled compiler.warn.outdir.is.in.exploded.module=Das Ausgabeverzeichnis befindet sich in einem entpackten Modul: {0} # 0: file object @@ -1198,6 +1202,7 @@ compiler.warn.output.file.clash=Ausgabedatei mehrmals geschrieben: {0} ## The following string will appear before all messages keyed as: ## "compiler.note". +# flags: mandatory compiler.note.compressed.diags=Einige Meldungen wurden vereinfacht. Wiederholen Sie die Kompilierung mit -Xdiags:verbose, um die vollständige Ausgabe abzurufen # 0: boolean, 1: symbol @@ -1378,17 +1383,17 @@ compiler.warn.incubating.modules=Inkubatormodul(e) verwendet: {0} # 0: symbol, 1: symbol # lint: deprecation -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated={0} in {1} ist veraltet # 0: symbol, 1: symbol # lint: removal -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated.for.removal={0} in {1} ist veraltet und wurde zum Entfernen markiert # 0: symbol # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.is.preview={0} ist eine Vorschau-API, die in einem zukünftigen Release entfernt werden kann. # 0: symbol @@ -1396,7 +1401,7 @@ compiler.err.is.preview={0} ist eine Vorschau-API, die standardmäßig deaktivie # 0: symbol # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.is.preview.reflective={0} ist eine reflektive Vorschau-API, die in einem zukünftigen Release entfernt werden kann. # 0: symbol, 1: symbol @@ -1405,12 +1410,12 @@ compiler.warn.restricted.method={0}.{1} ist eine eingeschränkte Methode.\n(Eing # 0: symbol # lint: deprecation -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated.module=Modul {0} ist veraltet # 0: symbol # lint: removal -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated.for.removal.module=Modul {0} ist veraltet und wurde zum Entfernen markiert # 0: symbol @@ -1583,10 +1588,12 @@ compiler.warn.static.not.qualified.by.type2={0} (statisch) darf nicht als Member # 0: string, 1: fragment # lint: options +# flags: default-enabled compiler.warn.source.no.bootclasspath=Bootstrap Classpath ist nicht zusammen mit -source {0} festgelegt\n{1} # 0: string, 1: fragment # lint: options +# flags: default-enabled compiler.warn.source.no.system.modules.path=Systemmodulpfad ist nicht zusammen mit -source {0} festgelegt\n{1} # 0: string @@ -1603,10 +1610,12 @@ compiler.misc.source.no.system.modules.path.with.target=Wenn Sie den Speicherort # 0: string # lint: options +# flags: default-enabled compiler.warn.option.obsolete.source=Quellwert {0} ist veraltet und wird in einem zukünftigen Release entfernt # 0: target # lint: options +# flags: default-enabled compiler.warn.option.obsolete.target=Zielwert {0} ist veraltet und wird in einem zukünftigen Release entfernt # 0: string, 1: string @@ -1616,12 +1625,17 @@ compiler.err.option.removed.source=Quelloption {0} wird nicht mehr unterstützt. compiler.err.option.removed.target=Zieloption {0} wird nicht mehr unterstützt. Verwenden Sie {1} oder höher. # lint: options +# flags: default-enabled compiler.warn.option.obsolete.suppression=Verwenden Sie -Xlint:-options, um Warnungen zu veralteten Optionen zu unterdrücken. # 0: name, 1: number, 2: number, 3: number, 4: number # lint: classfile compiler.warn.future.attr={0}-Attribut, das in Klassendateien der Version {1}.{2} eingeführt wurde, wird in Klassendateien der Version {3}.{4} ignoriert +# 0: symbol, 1: file object +# lint: classfile +compiler.warn.inconsistent.inner.classes=InnerClasses-Attribut für {0} in {1} inkonsistent mit Quellcode\n({1} muss möglicherweise mit {0} neu kompiliert werden) + # lint: requires-automatic compiler.warn.requires.automatic=Erfordert Direktive für ein automatisches Modul @@ -1706,17 +1720,21 @@ compiler.warn.try.resource.not.referenced=Automatisch schließbare Ressource {0} # lint: try compiler.warn.try.resource.throws.interrupted.exc=Automatisch schließbare Ressource {0} umfasst die Mitgliedsmethode close(), die InterruptedException auslösen könnte +# 0: type +# lint: try +compiler.warn.try.resource.can.throw.interrupted.exc=close()-Methode kann InterruptedException in automatisch schließbarer Klasse {0} auslösen + # lint: unchecked compiler.warn.unchecked.assign=Nicht geprüfte Zuweisung: {0} zu {1} # 0: symbol, 1: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.assign.to.var=Nicht geprüfte Zuweisung zu Variable {0} als Mitglied des Raw-Typs {1} # 0: symbol, 1: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.call.mbr.of.raw.type=Nicht geprüfter Aufruf von {0} als Mitglied des Raw-Typs {1} # lint: unchecked @@ -1724,17 +1742,17 @@ compiler.warn.unchecked.cast.to.type=Nicht geprüftes Casting zu Typ {0} # 0: kind name, 1: name, 2: object, 3: object, 4: kind name, 5: symbol # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.meth.invocation.applied=Nicht geprüfter Methodenaufruf: {0} {1} in {4} {5} wird auf die angegebenen Typen angewendet\nErforderlich: {2}\nErmittelt: {3} # 0: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.generic.array.creation=Nicht geprüfte Erstellung eines generischen Arrays für varargs-Parameter des Typs {0} # 0: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.varargs.non.reifiable.type=Möglich Heap-Beschädigung aus parametrisiertem vararg-Typ {0} # 0: symbol @@ -1772,6 +1790,10 @@ compiler.err.no.zipfs.for.archive=Kein Dateisystemprovider zur Verarbeitung dies # lint: divzero compiler.warn.div.zero=Division durch Null +# 0: type, 1: long, 2: number +# lint: lossy-conversions +compiler.warn.bit.shift.out.of.range=Das Verschieben von {0} um {1} Bit entspricht einer Verschiebung um {2} Bit + # lint: empty compiler.warn.empty.if=Leere Anweisung nach "if" @@ -2023,7 +2045,7 @@ compiler.misc.prob.found.req=Inkompatible Typen: {0} # 0: message segment, 1: type, 2: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.prob.found.req={0}\nErforderlich: {2}\nErmittelt: {1} # 0: type, 1: type @@ -2297,12 +2319,12 @@ compiler.err.override.incompatible.ret={0}\nRückgabetyp {1} ist nicht mit {2} k # 0: message segment, 1: type, 2: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.override.unchecked.ret={0}\nRückgabetyp erfordert eine nicht geprüfte Konvertierung von {1} in {2} # 0: message segment, 1: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.override.unchecked.thrown={0}\nAußer Kraft gesetzte Methode löst nicht {1} aus # 0: symbol @@ -2377,16 +2399,17 @@ compiler.err.preview.feature.disabled.classfile=Klassendatei für {0} verwendet # 0: message segment (feature) # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.preview.feature.use={0} ist ein Vorschaufeature, das in einem zukünftigen Release entfernt werden kann. # 0: message segment (feature) # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.preview.feature.use.plural={0} sind ein Vorschaufeature, das in einem zukünftigen Release entfernt werden kann. # 0: file object (classfile), 1: string (expected version) # lint: preview +# flags: mandatory compiler.warn.preview.feature.use.classfile=Klassendatei für {0} verwendet Vorschaufeatures von Java SE {1}. compiler.misc.feature.modules=Module @@ -2783,6 +2806,7 @@ compiler.err.bad.name.for.option=Ungültiger Name im Wert für {0}-Option: "{1}" # 0: option name, 1: symbol # lint: options +# flags: default-enabled compiler.warn.module.for.option.not.found=Modulname in {0}-Option nicht gefunden: {1} compiler.err.addmods.all.module.path.invalid=--add-modules ALL-MODULE-PATH kann nur beim Kompilieren des unbenannten Moduls oder beim Kompilieren im Kontext eines automatischen Moduls verwendet werden @@ -2794,6 +2818,7 @@ compiler.err.add.exports.with.release=Export eines Packages aus Systemmodul {0} compiler.err.add.reads.with.release=Hinzufügen von Lese-Edges für Systemmodul {0} ist mit --release nicht zulässig # lint: options +# flags: default-enabled compiler.warn.addopens.ignored=--add-opens hat zur Kompilierungszeit keine Auswirkungen compiler.misc.locn.module_source_path=Modulquellpfad @@ -3060,7 +3085,7 @@ compiler.err.incorrect.number.of.nested.patterns=Falsche Anzahl verschachtelter # 0: kind name, 1: symbol # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.declared.using.preview={0} {1} ist mit einem Vorschaufeature deklariert, das in einem zukünftigen Release entfernt werden kann. # lint: identity diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_ja.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_ja.properties index 291d8aeeec5..89bdc893a43 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_ja.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_ja.properties @@ -292,10 +292,10 @@ compiler.err.annotation.decl.not.allowed.here=ここでは注釈インタフェ compiler.err.cant.inherit.from.final=final {0}からは継承できません # 0: symbol or name -compiler.err.cant.ref.before.ctor.called=スーパータイプのコンストラクタの呼出し前は{0}を参照できません +compiler.err.cant.ref.before.ctor.called={0}への参照は、明示的なコンストラクタの呼出しの後にのみ表示されます # 0: symbol or name -compiler.err.cant.assign.initialized.before.ctor.called=スーパータイプのコンストラクタの呼出し前は、初期化されたフィールド''{0}''を割り当てられません +compiler.err.cant.assign.initialized.before.ctor.called=初期化されたフィールド''{0}''への割当ては、明示的なコンストラクタの呼出しの後にのみ表示されます compiler.err.cant.select.static.class.from.param.type=パラメータにされた型からstaticクラスを選択することはできません @@ -649,11 +649,14 @@ compiler.err.limit.string.overflow=文字列"{0}..."のUTF8表現が、定数プ compiler.err.malformed.fp.lit=浮動小数点リテラルが不正です -compiler.err.method.does.not.override.superclass=メソッドはスーパータイプのメソッドをオーバーライドまたは実装しません +# 0: symbol, 1: symbol +compiler.err.method.does.not.override.superclass={1}の{0}はスーパータイプのメソッドをオーバーライドまたは実装しません -compiler.err.static.methods.cannot.be.annotated.with.override=staticメソッドは@Overrideで注釈付けすることはできません +# 0: symbol, 1: symbol +compiler.err.static.methods.cannot.be.annotated.with.override={1}のstaticメソッド{0}は@Overrideで注釈付けすることはできません -compiler.err.missing.meth.body.or.decl.abstract=メソッド本体がないか、abstractとして宣言されています +# 0: symbol, 1: symbol +compiler.err.missing.meth.body.or.decl.abstract={1}のメソッド{0}にメソッド本体がないか、abstractを宣言する必要があります compiler.err.missing.ret.stmt=return文が指定されていません @@ -1139,6 +1142,7 @@ compiler.err.multi-module.outdir.cannot.be.exploded.module=複数モジュール # 0: path # lint: path +# flags: default-enabled compiler.warn.outdir.is.in.exploded.module=出力ディレクトリは展開したモジュール内です: {0} # 0: file object @@ -1198,6 +1202,7 @@ compiler.warn.output.file.clash=出力ファイルへの書込みが複数回あ ## The following string will appear before all messages keyed as: ## "compiler.note". +# flags: mandatory compiler.note.compressed.diags=一部のメッセージは簡略化されています。-Xdiags:verboseで再コンパイルして完全な出力を取得してください # 0: boolean, 1: symbol @@ -1378,17 +1383,17 @@ compiler.warn.incubating.modules=実験的なモジュールを使用してい # 0: symbol, 1: symbol # lint: deprecation -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated={1}の{0}は推奨されません # 0: symbol, 1: symbol # lint: removal -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated.for.removal={1}の{0}は推奨されておらず、削除用にマークされています # 0: symbol # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.is.preview={0}はプレビューAPIであり、今後のリリースで削除される可能性があります。 # 0: symbol @@ -1396,7 +1401,7 @@ compiler.err.is.preview={0}はプレビューAPIであり、デフォルトで # 0: symbol # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.is.preview.reflective={0}はリフレクティブ・プレビューAPIであり、今後のリリースで削除される可能性があります。 # 0: symbol, 1: symbol @@ -1405,12 +1410,12 @@ compiler.warn.restricted.method={0}.{1}は制限されたメソッドです。\n # 0: symbol # lint: deprecation -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated.module=モジュール{0}は推奨されません # 0: symbol # lint: removal -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated.for.removal.module=モジュール{0}は推奨されておらず、削除用にマークされています # 0: symbol @@ -1583,10 +1588,12 @@ compiler.warn.static.not.qualified.by.type2=static {0}を匿名クラスのメ # 0: string, 1: fragment # lint: options +# flags: default-enabled compiler.warn.source.no.bootclasspath=ブートストラップ・クラス・パスが-source {0}と一緒に設定されていません\n{1} # 0: string, 1: fragment # lint: options +# flags: default-enabled compiler.warn.source.no.system.modules.path=システム・モジュールの場所が-source {0}と一緒に設定されていません\n{1} # 0: string @@ -1603,10 +1610,12 @@ compiler.misc.source.no.system.modules.path.with.target=システム・モジュ # 0: string # lint: options +# flags: default-enabled compiler.warn.option.obsolete.source=ソース値{0}は廃止されていて、今後のリリースで削除される予定です # 0: target # lint: options +# flags: default-enabled compiler.warn.option.obsolete.target=ターゲット値{0}は廃止されていて、今後のリリースで削除される予定です # 0: string, 1: string @@ -1616,12 +1625,17 @@ compiler.err.option.removed.source=ソース・オプション{0}は現在サポ compiler.err.option.removed.target=ターゲット・オプション{0}は現在サポートされていません。{1}以降を使用してください。 # lint: options +# flags: default-enabled compiler.warn.option.obsolete.suppression=廃止されたオプションについての警告を表示しないようにするには、-Xlint:オプションを使用します。 # 0: name, 1: number, 2: number, 3: number, 4: number # lint: classfile compiler.warn.future.attr=バージョン{1}.{2}のクラス・ファイルで導入された{0}属性は、バージョン{3}.{4}のクラス・ファイルでは無視されます +# 0: symbol, 1: file object +# lint: classfile +compiler.warn.inconsistent.inner.classes={1}の{0}のInnerClasses属性はソース・コードと一貫性がありません\n({1}は{0}で再コンパイルする必要がある場合があります) + # lint: requires-automatic compiler.warn.requires.automatic=自動モジュールにはディレクティブが必要です @@ -1706,17 +1720,21 @@ compiler.warn.try.resource.not.referenced=自動クローズ可能なリソー # lint: try compiler.warn.try.resource.throws.interrupted.exc=自動クローズ可能なリソース{0}に、InterruptedExceptionをスローする可能性があるメンバー・メソッドclose()があります +# 0: type +# lint: try +compiler.warn.try.resource.can.throw.interrupted.exc=close()メソッドは、自動クローズ可能なクラス{0}でInterruptedExceptionをスローできます + # lint: unchecked compiler.warn.unchecked.assign={0}から{1}への無検査代入です # 0: symbol, 1: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.assign.to.var=raw型{1}のメンバーとして変数{0}への無検査代入です # 0: symbol, 1: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.call.mbr.of.raw.type=raw型{1}のメンバーとしての{0}への無検査呼出しです # lint: unchecked @@ -1724,17 +1742,17 @@ compiler.warn.unchecked.cast.to.type=型{0}への無検査キャストです # 0: kind name, 1: name, 2: object, 3: object, 4: kind name, 5: symbol # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.meth.invocation.applied=無検査メソッド呼出し: {4} {5}の{0} {1}は指定された型に適用されます\n期待値: {2}\n検出値: {3} # 0: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.generic.array.creation=型{0}の可変引数パラメータに対する総称型配列の無検査作成です # 0: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.varargs.non.reifiable.type=パラメータ化された可変引数型{0}からのヒープ汚染の可能性があります # 0: symbol @@ -1772,6 +1790,10 @@ compiler.err.no.zipfs.for.archive=このファイルの処理に使用できる # lint: divzero compiler.warn.div.zero=ゼロで除算 +# 0: type, 1: long, 2: number +# lint: lossy-conversions +compiler.warn.bit.shift.out.of.range={0}を{1}ビットでシフトすることは、{2}ビットでシフトすることと同等です + # lint: empty compiler.warn.empty.if=if以降が空の文です @@ -2023,7 +2045,7 @@ compiler.misc.prob.found.req=不適合な型: {0} # 0: message segment, 1: type, 2: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.prob.found.req={0}\n期待値: {2}\n検出値: {1} # 0: type, 1: type @@ -2297,12 +2319,12 @@ compiler.err.override.incompatible.ret={0}\n戻り値の型{1}は{2}と互換性 # 0: message segment, 1: type, 2: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.override.unchecked.ret={0}\n戻り値の型は{1}から{2}への無検査変換が必要です # 0: message segment, 1: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.override.unchecked.thrown={0}\nオーバーライドされたメソッドは{1}をスローしません # 0: symbol @@ -2377,16 +2399,17 @@ compiler.err.preview.feature.disabled.classfile={0}のクラス・ファイル # 0: message segment (feature) # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.preview.feature.use={0}はプレビュー機能であり、今後のリリースで削除される可能性があります。 # 0: message segment (feature) # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.preview.feature.use.plural={0}はプレビュー機能であり、今後のリリースで削除される可能性があります。 # 0: file object (classfile), 1: string (expected version) # lint: preview +# flags: mandatory compiler.warn.preview.feature.use.classfile={0}のクラス・ファイルはJava SE {1}のプレビュー機能を使用します。 compiler.misc.feature.modules=モジュール @@ -2783,6 +2806,7 @@ compiler.err.bad.name.for.option={0}オプションの値に含まれる名前 # 0: option name, 1: symbol # lint: options +# flags: default-enabled compiler.warn.module.for.option.not.found={0}オプション内にモジュール名が見つかりません: {1} compiler.err.addmods.all.module.path.invalid=--add-modules ALL-MODULE-PATHは、名前のないモジュールのコンパイル時または自動モジュールのコンテキストでのコンパイル時のみ使用できます @@ -2794,6 +2818,7 @@ compiler.err.add.exports.with.release=システム・モジュール{0}からの compiler.err.add.reads.with.release=システム・モジュール{0}の読取りエッジの追加は--releaseを指定して実行できません # lint: options +# flags: default-enabled compiler.warn.addopens.ignored=--add-opensは、コンパイル時には無効です compiler.misc.locn.module_source_path=モジュール・ソース・パス @@ -3060,7 +3085,7 @@ compiler.err.incorrect.number.of.nested.patterns=ネスト・パターンの数 # 0: kind name, 1: symbol # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.declared.using.preview={0} {1}はプレビュー機能を使用して宣言されており、今後のリリースで削除される可能性があります。 # lint: identity diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties index 268ce26bd49..861f371632d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler_zh_CN.properties @@ -292,10 +292,10 @@ compiler.err.annotation.decl.not.allowed.here=此处不允许批注接口声明 compiler.err.cant.inherit.from.final=无法从最终{0}进行继承 # 0: symbol or name -compiler.err.cant.ref.before.ctor.called=无法在调用超类型构造器之前引用{0} +compiler.err.cant.ref.before.ctor.called=对 {0} 的引用只能在显式调用构造器后显示 # 0: symbol or name -compiler.err.cant.assign.initialized.before.ctor.called=无法在调用超类型构造器之前分配初始化字段 ''{0}'' +compiler.err.cant.assign.initialized.before.ctor.called=对初始化字段 ''{0}'' 的分配只能在显式调用构造器后显示 compiler.err.cant.select.static.class.from.param.type=无法从参数化的类型中选择静态类 @@ -649,11 +649,14 @@ compiler.err.limit.string.overflow=对于常量池来说, 字符串 "{0}..." 的 compiler.err.malformed.fp.lit=浮点文字的格式错误 -compiler.err.method.does.not.override.superclass=方法不会覆盖或实现超类型的方法 +# 0: symbol, 1: symbol +compiler.err.method.does.not.override.superclass={1} 中的 {0} 不会覆盖或实现超类型中的方法 -compiler.err.static.methods.cannot.be.annotated.with.override=不能使用 @Override 对静态方法进行批注 +# 0: symbol, 1: symbol +compiler.err.static.methods.cannot.be.annotated.with.override=不能使用 @Override 对 {1} 中的静态方法 {0} 进行批注 -compiler.err.missing.meth.body.or.decl.abstract=缺少方法主体, 或声明抽象 +# 0: symbol, 1: symbol +compiler.err.missing.meth.body.or.decl.abstract={1} 中的方法 {0} 缺少方法主体,或者应声明为抽象方法 compiler.err.missing.ret.stmt=缺少返回语句 @@ -1139,6 +1142,7 @@ compiler.err.multi-module.outdir.cannot.be.exploded.module=在多模块模式下 # 0: path # lint: path +# flags: default-enabled compiler.warn.outdir.is.in.exploded.module=输出目录位于展开的模块中: {0} # 0: file object @@ -1198,6 +1202,7 @@ compiler.warn.output.file.clash=多次写入输出文件:{0} ## The following string will appear before all messages keyed as: ## "compiler.note". +# flags: mandatory compiler.note.compressed.diags=某些消息已经过简化; 请使用 -Xdiags:verbose 重新编译以获得完整输出 # 0: boolean, 1: symbol @@ -1378,17 +1383,17 @@ compiler.warn.incubating.modules=使用 incubating 模块: {0} # 0: symbol, 1: symbol # lint: deprecation -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated={1}中的{0}已过时 # 0: symbol, 1: symbol # lint: removal -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated.for.removal={1} 中的 {0} 已过时, 且标记为待删除 # 0: symbol # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.is.preview={0} 是预览 API,可能会在未来发行版中删除。 # 0: symbol @@ -1396,7 +1401,7 @@ compiler.err.is.preview={0} 是预览 API,默认情况下处于禁用状态。 # 0: symbol # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.is.preview.reflective={0} 是反射预览 API,可能会在未来发行版中删除。 # 0: symbol, 1: symbol @@ -1405,12 +1410,12 @@ compiler.warn.restricted.method={0}.{1} 是受限制的方法。\n(受限制 # 0: symbol # lint: deprecation -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated.module=模块 {0} 已过时 # 0: symbol # lint: removal -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.has.been.deprecated.for.removal.module=模块 {0} 已过时, 且标记为待删除 # 0: symbol @@ -1583,10 +1588,12 @@ compiler.warn.static.not.qualified.by.type2=static {0} 不应用作匿名类的 # 0: string, 1: fragment # lint: options +# flags: default-enabled compiler.warn.source.no.bootclasspath=未与 -source {0} 一起设置引导类路径\n{1} # 0: string, 1: fragment # lint: options +# flags: default-enabled compiler.warn.source.no.system.modules.path=未与 -source {0} 一起设置系统模块的位置\n{1} # 0: string @@ -1603,10 +1610,12 @@ compiler.misc.source.no.system.modules.path.with.target=不设置系统模块的 # 0: string # lint: options +# flags: default-enabled compiler.warn.option.obsolete.source=源值 {0} 已过时,将在未来发行版中删除 # 0: target # lint: options +# flags: default-enabled compiler.warn.option.obsolete.target=目标值 {0} 已过时,将在未来发行版中删除 # 0: string, 1: string @@ -1616,12 +1625,17 @@ compiler.err.option.removed.source=不再支持源选项 {0}。请使用 {1} 或 compiler.err.option.removed.target=不再支持目标选项 {0}。请使用 {1} 或更高版本。 # lint: options +# flags: default-enabled compiler.warn.option.obsolete.suppression=要隐藏有关已过时选项的警告, 请使用 -Xlint:-options。 # 0: name, 1: number, 2: number, 3: number, 4: number # lint: classfile compiler.warn.future.attr={1}.{2} 版类文件中引入的 {0} 属性在 {3}.{4} 版类文件中被忽略 +# 0: symbol, 1: file object +# lint: classfile +compiler.warn.inconsistent.inner.classes={1} 中 {0} 的 InnerClasses 属性与源代码不一致\n(可能需要使用 {0} 重新编译 {1}) + # lint: requires-automatic compiler.warn.requires.automatic=需要自动模块的指令 @@ -1706,17 +1720,21 @@ compiler.warn.try.resource.not.referenced=不能在相应的 try 语句的正文 # lint: try compiler.warn.try.resource.throws.interrupted.exc=可自动关闭的资源{0}包含的成员方法 close() 可能抛出 InterruptedException +# 0: type +# lint: try +compiler.warn.try.resource.can.throw.interrupted.exc=在可自动关闭的类 {0} 中,close() 方法可能抛出 InterruptedException + # lint: unchecked compiler.warn.unchecked.assign=未经检查的分配: 将{0}分配给{1} # 0: symbol, 1: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.assign.to.var=对作为原始类型{1}的成员的变量{0}的分配未经过检查 # 0: symbol, 1: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.call.mbr.of.raw.type=对作为原始类型{1}的成员的{0}的调用未经过检查 # lint: unchecked @@ -1724,17 +1742,17 @@ compiler.warn.unchecked.cast.to.type=向类型{0}的转换未经过检查 # 0: kind name, 1: name, 2: object, 3: object, 4: kind name, 5: symbol # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.meth.invocation.applied=方法调用未经过检查: 将{4} {5}中的{0} {1}应用到给定的类型\n需要: {2}\n找到: {3} # 0: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.generic.array.creation=对于类型为{0}的 varargs 参数, 泛型数组创建未经过检查 # 0: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.unchecked.varargs.non.reifiable.type=参数化 vararg 类型{0}的堆可能已受污染 # 0: symbol @@ -1772,6 +1790,10 @@ compiler.err.no.zipfs.for.archive=没有任何文件系统提供方可处理此 # lint: divzero compiler.warn.div.zero=除数为零 +# 0: type, 1: long, 2: number +# lint: lossy-conversions +compiler.warn.bit.shift.out.of.range=按 {1} 位移动 {0} 相当于按 {2} 位移动 + # lint: empty compiler.warn.empty.if=if 之后没有语句 @@ -2023,7 +2045,7 @@ compiler.misc.prob.found.req=不兼容的类型: {0} # 0: message segment, 1: type, 2: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.prob.found.req={0}\n需要: {2}\n找到: {1} # 0: type, 1: type @@ -2297,12 +2319,12 @@ compiler.err.override.incompatible.ret={0}\n返回类型{1}与{2}不兼容 # 0: message segment, 1: type, 2: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.override.unchecked.ret={0}\n返回类型需要从{1}到{2}的未经检查的转换 # 0: message segment, 1: type # lint: unchecked -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.override.unchecked.thrown={0}\n被覆盖的方法未抛出{1} # 0: symbol @@ -2377,16 +2399,17 @@ compiler.err.preview.feature.disabled.classfile={0} 的类文件使用 Java SE { # 0: message segment (feature) # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.preview.feature.use={0} 是预览功能,可能会在未来发行版中删除。 # 0: message segment (feature) # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.preview.feature.use.plural={0} 是预览功能,可能会在未来发行版中删除。 # 0: file object (classfile), 1: string (expected version) # lint: preview +# flags: mandatory compiler.warn.preview.feature.use.classfile={0} 的类文件使用 Java SE {1} 的预览功能。 compiler.misc.feature.modules=模块 @@ -2783,6 +2806,7 @@ compiler.err.bad.name.for.option={0} 选项的值中有错误的名称: ''{1}'' # 0: option name, 1: symbol # lint: options +# flags: default-enabled compiler.warn.module.for.option.not.found=找不到 {0} 选项中的模块名称: {1} compiler.err.addmods.all.module.path.invalid=--add-modules ALL-MODULE-PATH 只能在编译未命名模块或在自动模块的上下文中编译时使用 @@ -2794,6 +2818,7 @@ compiler.err.add.exports.with.release=不允许在使用 --release 时从系统 compiler.err.add.reads.with.release=不允许在使用 --release 时为系统模块 {0} 添加读取维边: # lint: options +# flags: default-enabled compiler.warn.addopens.ignored=--add-opens 在编译时没有任何效果 compiler.misc.locn.module_source_path=模块源路径 @@ -3060,7 +3085,7 @@ compiler.err.incorrect.number.of.nested.patterns=嵌套模式数不正确\n需 # 0: kind name, 1: symbol # lint: preview -# flags: aggregate +# flags: aggregate, mandatory, default-enabled compiler.warn.declared.using.preview={0} {1} 是使用预览功能声明的,可能会在未来发行版中删除。 # lint: identity diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_de.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_de.properties index 1a00fad1dd0..b36ad3d00ac 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_de.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_de.properties @@ -60,6 +60,8 @@ javac.opt.target=Generiert Klassendateien, die sich für das angegebene Java SE- javac.opt.release=Kompiliert für das angegebene Java SE-Release.\nUnterstützte Releases: \n {0} javac.opt.source=Liefert Quellkompatibilität mit dem angegebenen Release von Java SE.\nUnterstützte Releases: \n {0} javac.opt.Werror=Kompilierung beenden, wenn Warnungen auftreten +javac.opt.arg.Werror=(,)* +javac.opt.Werror.custom=Geben Sie Lint-Kategorien, für die die Kompilierung durch Warnungen beendet werden soll,\ndurch Komma getrennt an. \nStellen Sie einem Schlüssel "-" voran, um die angegebene Kategorie auszuschließen. Verwenden Sie --help-lint, um die unterstützten Schlüssel anzuzeigen. javac.opt.A=Optionen zur Übergabe an die Annotationsprozessoren javac.opt.implicit=Gibt an, ob Klassendateien für implizit referenzierte Dateien generiert werden javac.opt.pkginfo=Gibt an, wie package-info-Dateien behandelt werden sollen @@ -97,12 +99,12 @@ javac.opt.arg.pathname= javac.opt.arg.file= javac.opt.Xbootclasspath.p=Dem Bootstrap Classpath voranstellen javac.opt.Xbootclasspath.a=An Bootstrap Classpath anhängen -javac.opt.Xlint=Empfohlene Warnungskategorien aktivieren -javac.opt.Xlint.all=Alle Warnungskategorien aktivieren -javac.opt.Xlint.none=Alle Warnungskategorien deaktivieren +javac.opt.Xlint=Aktivieren Sie empfohlene Lint-Warnungskategorien. In diesem Release werden alle\nverfügbaren Lint-Warnungskategorien empfohlen. +javac.opt.Xlint.all=Alle Lint-Warnungskategorien aktivieren +javac.opt.Xlint.none=Alle Lint-Warnungskategorien deaktivieren #L10N: do not localize: -Xlint javac.opt.arg.Xlint=(,)* -javac.opt.Xlint.custom=Durch Komma getrennte Warnungskategorien, die aktiviert oder deaktiviert werden sollen.\nStellen Sie einem Schlüssel "-" voran, um die angegebene Warnung zu deaktivieren.\nVerwenden Sie "--help-lint", um die unterstützten Schlüssel anzuzeigen. +javac.opt.Xlint.custom=Lint-Warnungskategorien, die aktiviert oder deaktiviert werden sollen, durch Komma getrennt. \nStellen Sie einem Schlüssel "-" voran, um die angegebene Kategorie zu deaktivieren. Verwenden Sie\n''--help-lint'', um unterstützte Schlüssel und die standardmäßig aktivierten\nKategorien anzuzeigen. javac.opt.Xlint.desc.auxiliaryclass=Warnt vor Auxiliary-Klassen, die in einer Quelldatei verborgen sind und aus anderen Dateien heraus verwendet werden. javac.opt.Xlint.desc.cast=Warnt vor unnötigen Umwandlungen mit Cast. @@ -129,7 +131,7 @@ javac.opt.Xlint.desc.finally=Warnt vor Finally-Klauseln, die nicht normal beende javac.opt.Xlint.desc.incubating=Warnt vor der Verwendung von Inkubatormodulen. -javac.opt.Xlint.desc.lossy-conversions=Warnung über möglichen Verlust von Konvertierungen in zusammengesetzten Zuweisungen. +javac.opt.Xlint.desc.lossy-conversions=Warnung über möglichen Verlust von Konvertierungen in zusammengesetzten Zuweisungen und Bitverschiebungsvorgängen. javac.opt.Xlint.desc.module=Warnt vor Problemen im Zusammenhang mit dem Modulsystem. @@ -175,11 +177,10 @@ javac.opt.Xlint.desc.preview=Warnt vor Verwendung von Vorschausprachfeatures. javac.opt.Xlint.desc.restricted=Warnt vor der Verwendung eingeschränkter Methoden. -# L10N: do not localize: identity synchronization -javac.opt.Xlint.desc.synchronization=Warnt vor Synchronisierungsversuchen mit Instanzen wertbasierter Klassen.\n Dieser Schlüssel ist ein veralteter Alias für die Kategorie "identity", die dieselben Verwendungen und\n Effekte hat. Benutzern wird empfohlen, die Kategorie "identity" für alle zukünftigen\n und vorhandenen Verwendungen von "synchronization" zu verwenden. - javac.opt.Xlint.desc.identity=Warnt vor Verwendungen wertbasierter Klassen, wenn eine Identitätsklasse erwartet wird. +javac.opt.Xlint.alias.of=Veralteter Alias für "{0}" mit identischem Effekt. Benutzern wird empfohlen,\n "{0}" anstatt "{1}" für alle aktuellen und zukünftigen Verwendungen zu nutzen. + javac.opt.Xdoclint=Empfohlene Prüfungen für Probleme in javadoc-Kommentaren aktivieren # L10N: do not localize: all none javac.opt.Xdoclint.subopts = (all|none|[-])[/] @@ -195,14 +196,17 @@ javac.opt.Xdoclint.package.desc=Aktiviert oder deaktiviert Prüfungen in bestimm javac.opt.Xstdout=Leitet die Standardausgabe um javac.opt.X=Gibt Hilfe zu zusätzlichen Optionen aus javac.opt.help=Gibt diese Hilfemeldung aus -javac.opt.help.lint=Gibt die unterstützten Schlüssel für -Xlint aus +javac.opt.help.lint=Gibt die unterstützten Schlüssel für -Xlint und -Werror aus javac.opt.help.lint.header=Die unterstützten Schlüssel für -Xlint sind: +javac.opt.help.lint.enabled.by.default=Die folgenden Lint-Warnungskategorien sind standardmäßig aktiviert: +javac.opt.help.lint.footer=Kategorien und die zugehörigen Aliasnamen können austauschbar verwendet werden. Beispiel: Das Kennzeichen\n"-Xlint:{0},{1}" wäre redundant. javac.opt.print=Gibt eine Textdarstellung der angegebenen Typen aus javac.opt.printRounds=Gibt Informationen zu Durchläufen der Annotationsverarbeitung aus javac.opt.printProcessorInfo=Gibt Informationen dazu aus, welche Annotationen ein Prozessor\nverarbeiten soll javac.opt.userpathsfirst=Durchsucht classpath und sourcepath vor anstatt nach bootclasspath nach Klassen javac.opt.prefer=Gibt an, welche Datei gelesen werden soll, wenn sowohl eine Quell- als auch eine Klassendatei für eine implizit kompilierte Klasse gefunden werden -javac.opt.preview=Aktiviert Vorschausprachfeatures.\nWird in Verbindung mit -source oder --release verwendet. +# L10N: do not localize: ''preview'' +javac.opt.preview=Aktiviert Vorschausprachfeatures. \nDeaktiviert auch die Lint-Kategorie ''preview''. \nWird in Verbindung mit -source oder --release verwendet. javac.opt.AT=Liest Optionen und Dateinamen aus Datei javac.opt.diags=Wählt einen Diagnosemodus aus javac.opt.addExports=Gibt an, dass ein Package als aus seinem definierenden Modul in\nweitere Module oder, wenn ALL-UNNAMED lautet, in alle unbenannten Module\nexportiert betrachtet werden soll. diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties index 3b967d368ae..0ea1796a8e6 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_ja.properties @@ -59,7 +59,9 @@ javac.opt.profile=使用されているAPIが、指定したプロファイル javac.opt.target=指定されたJava SEリリースに適したクラス・ファイルを生成します。サポートされているリリース: \n {0} javac.opt.release=指定されたJava SEリリースに対してコンパイルします。サポートされているリリース: \n {0} javac.opt.source=指定されたJava SEリリースとソースの互換性を保持します。サポートされているリリース: \n {0} -javac.opt.Werror=警告が発生した場合にコンパイルを終了する +javac.opt.Werror=警告が発生した場合にコンパイルを終了します +javac.opt.arg.Werror=(,)* +javac.opt.Werror.custom=コンパイルを終了する警告のlintカテゴリを\nコンマで区切って指定します。\n指定したカテゴリを除外するには、キーの前に''-''を指定します。\nサポートされているキーを表示するには--help-lintを使用します。 javac.opt.A=注釈プロセッサに渡されるオプション javac.opt.implicit=暗黙的に参照されるファイルについてクラス・ファイルを生成するかどうかを指定する javac.opt.pkginfo=package-infoファイルの処理を指定する @@ -97,12 +99,12 @@ javac.opt.arg.pathname= javac.opt.arg.file= javac.opt.Xbootclasspath.p=ブートストラップ・クラス・パスの先頭に付加する javac.opt.Xbootclasspath.a=ブートストラップ・クラス・パスに追加する -javac.opt.Xlint=推奨の警告カテゴリを有効にします -javac.opt.Xlint.all=すべての警告カテゴリを有効にします -javac.opt.Xlint.none=すべての警告カテゴリを無効にします +javac.opt.Xlint=推奨lint警告カテゴリを有効にします。このリリースでは、\n使用可能なすべてのlint警告カテゴリが推奨されます。 +javac.opt.Xlint.all=すべてのlint警告カテゴリを有効にします +javac.opt.Xlint.none=すべてのlint警告カテゴリを無効にします #L10N: do not localize: -Xlint javac.opt.arg.Xlint=(,)* -javac.opt.Xlint.custom=有効または無効にする警告カテゴリ(カンマ区切り)。\n指定した警告を無効にするには、キーの前に''-''を指定します。\nサポートされているキーを表示するには--help-lintを使用します。 +javac.opt.Xlint.custom=有効または無効にするLint警告カテゴリ(カンマ区切り)。\n指定されたカテゴリを無効にするには、キーの前に''-''を指定します。サポートされているキーと\nデフォルトで有効になっているカテゴリを表示するには、\n''--help-lint''を使用します。 javac.opt.Xlint.desc.auxiliaryclass=ソース・ファイルで非表示になっているが他のファイルから使用されている補助クラスについて警告します。 javac.opt.Xlint.desc.cast=不要なキャストの使用について警告します。 @@ -129,7 +131,7 @@ javac.opt.Xlint.desc.finally=正常に完了しないfinally節について警 javac.opt.Xlint.desc.incubating=実験的なモジュールの使用について警告します。 -javac.opt.Xlint.desc.lossy-conversions=複合代入における精度が失われる可能性がある変換についての警告。 +javac.opt.Xlint.desc.lossy-conversions=複合代入およびビット・シフト操作における精度が失われている可能性がある変換についての警告。 javac.opt.Xlint.desc.module=モジュール・システム関連の問題について警告します。 @@ -175,11 +177,10 @@ javac.opt.Xlint.desc.preview=プレビュー言語機能の使用について警 javac.opt.Xlint.desc.restricted=制限されたメソッドの使用について警告します。 -# L10N: do not localize: identity synchronization -javac.opt.Xlint.desc.synchronization=値ベース・クラスのインスタンスでの同期の試行について警告します。\n このキーは、''identity''の非推奨のエイリアスであり、同じ使用方法と効果を\n 持ちます。ユーザーには、今後および既存の''synchronization''の使用に対して''identity''カテゴリを\n 使用することをお薦めします。 - javac.opt.Xlint.desc.identity=アイデンティティ・クラスが必要な場所での値ベース・クラスの使用について警告します。 +javac.opt.Xlint.alias.of=同じ効果を持つ''{0}''の非推奨の別名。ユーザーは現在および将来のすべての使用で\n ''{1}''のかわりに''{0}''の使用が推奨されます。 + javac.opt.Xdoclint=javadocコメントの問題に関する推奨チェックを有効にします # L10N: do not localize: all none javac.opt.Xdoclint.subopts = (all|none|[-])[/] @@ -195,14 +196,17 @@ javac.opt.Xdoclint.package.desc=特定のパッケージのチェックを有効 javac.opt.Xstdout=標準出力をリダイレクトする javac.opt.X=追加オプションのヘルプを出力します javac.opt.help=このヘルプ・メッセージを出力します -javac.opt.help.lint=-Xlintにサポートされているキーを出力します +javac.opt.help.lint=-Xlintおよび-Werrorにサポートされているキーを出力します javac.opt.help.lint.header=-Xlintにサポートされているキーは次のとおりです: +javac.opt.help.lint.enabled.by.default=次のlint警告カテゴリはデフォルトで有効になっています: +javac.opt.help.lint.footer=カテゴリとその別名は同じ意味で使用できます。たとえば、フラグ\n''-Xlint:{0},{1}''は冗長です。 javac.opt.print=指定した型のテキスト表示を出力する javac.opt.printRounds=注釈処理の往復についての情報を印刷する javac.opt.printProcessorInfo=プロセッサが処理を依頼される注釈についての情報を印刷する javac.opt.userpathsfirst=ブート・クラスパスの後ではなく、ブート・クラスパスの前にクラスのクラスパスおよびソース・パスを検索する javac.opt.prefer=暗黙的にコンパイルされるクラスについて、ソース・ファイルとクラス・ファイルの両方が見つかった際どちらを読み込むか指定する -javac.opt.preview=プレビュー言語機能を有効にします。-sourceまたは--releaseとともに使用されます。 +# L10N: do not localize: ''preview'' +javac.opt.preview=プレビュー言語機能を有効にします。\nまた、''preview'' lintカテゴリも無効にします。\n-sourceまたは--releaseとともに使用されます。 javac.opt.AT=ファイルからの読取りオプションおよびファイル名 javac.opt.diags=診断モードの選択 javac.opt.addExports=がALL-UNNAMEDである場合、その定義モジュールから、追加モジュールまたは\n すべての名前のないモジュールにエクスポート済とみなされるようにパッケージを指定します。 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties index a24b5511c9c..0cbfac7e778 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac_zh_CN.properties @@ -59,7 +59,9 @@ javac.opt.profile=检查使用的 API 在指定的配置文件中是否可用。 javac.opt.target=生成适合指定的 Java SE 发行版的类文件。支持的发行版:{0} javac.opt.release=为指定的 Java SE 发行版编译。支持的发行版:{0} javac.opt.source=提供与指定的 Java SE 发行版的源兼容性。支持的发行版:{0} -javac.opt.Werror=出现警告时终止编译 +javac.opt.Werror=出现任何警告时终止编译 +javac.opt.arg.Werror=(,)* +javac.opt.Werror.custom=指定出现警告时应终止编译的 lint 类别,\n以逗号分隔。\n在关键字前面加上 ''-'' 可排除指定的类别。\n使用 --help-lint 可查看支持的关键字。 javac.opt.A=传递给批注处理程序的选项 javac.opt.implicit=指定是否为隐式引用文件生成类文件 javac.opt.pkginfo=指定 package-info 文件的处理 @@ -97,12 +99,12 @@ javac.opt.arg.pathname= javac.opt.arg.file= javac.opt.Xbootclasspath.p=置于引导类路径之前 javac.opt.Xbootclasspath.a=置于引导类路径之后 -javac.opt.Xlint=启用建议的警告类别 -javac.opt.Xlint.all=启用所有警告类别 -javac.opt.Xlint.none=禁用所有警告类别 +javac.opt.Xlint=启用建议的 lint 警告类别。在此发行版中,\n建议使用所有可用的 lint 警告类别。 +javac.opt.Xlint.all=启用所有 lint 警告类别 +javac.opt.Xlint.none=禁用所有 lint 警告类别 #L10N: do not localize: -Xlint javac.opt.arg.Xlint=(,)* -javac.opt.Xlint.custom=要启用或禁用的警告类别(以逗号分隔)。\n在关键字前面加上 ''-'' 可禁用指定的警告。\n使用 --help-lint 可查看受支持的关键字。 +javac.opt.Xlint.custom=要启用或禁用的 lint 警告类别(以逗号分隔)。\n在关键字前面加上 ''-'' 可禁用指定的类别。\n使用 ''--help-lint'' 可显示支持的关键字和\n默认情况下启用的类别。 javac.opt.Xlint.desc.auxiliaryclass=有关辅助类在源文件中隐藏, 但在其他文件中使用的警告。 javac.opt.Xlint.desc.cast=有关使用了不必要转换的警告。 @@ -129,7 +131,7 @@ javac.opt.Xlint.desc.finally=有关 finally 子句未正常终止的警告。 javac.opt.Xlint.desc.incubating=有关使用 incubating 模块的警告。 -javac.opt.Xlint.desc.lossy-conversions=有关复合赋值中的转换可能会有损失的警告。 +javac.opt.Xlint.desc.lossy-conversions=有关复合赋值和移位操作中的转换可能会有损失的警告。 javac.opt.Xlint.desc.module=有关模块系统相关问题的警告。 @@ -175,11 +177,10 @@ javac.opt.Xlint.desc.preview=有关使用预览语言功能的警告。 javac.opt.Xlint.desc.restricted=有关使用受限制方法的警告。 -# L10N: do not localize: identity synchronization -javac.opt.Xlint.desc.synchronization=有关尝试在基于值的类的实例上同步的警告。\n 此密钥是 ''identity'' 的已过时别名,具有相同的用法和\n 效果。建议用户在 ''synchronization'' 的所有未来和现有\n 用法中使用 ''identity'' 类别。 - javac.opt.Xlint.desc.identity=有关在需要身份类的情况下使用基于值的类的警告。 +javac.opt.Xlint.alias.of=具有相同效果的 ''{0}'' 的别名已过时。建议用户当前和将来\n 都使用 ''{0}'' 而不是 ''{1}''。 + javac.opt.Xdoclint=为 javadoc 注释中的问题启用建议的检查 # L10N: do not localize: all none javac.opt.Xdoclint.subopts = (all|none|[-])[/] @@ -195,14 +196,17 @@ javac.opt.Xdoclint.package.desc=在特定的程序包中启用或禁用检查。 javac.opt.Xstdout=重定向标准输出 javac.opt.X=输出额外选项的帮助 javac.opt.help=输出此帮助消息 -javac.opt.help.lint=输出 -Xlint 支持的关键字 +javac.opt.help.lint=输出 -Xlint 和 -Werror 支持的关键字 javac.opt.help.lint.header=-Xlint 支持的关键字包括: +javac.opt.help.lint.enabled.by.default=默认情况下会启用以下 lint 警告类别: +javac.opt.help.lint.footer=类别及其别名可以互换使用;例如,标记\n''-Xlint:{0},{1}'' 将是冗余的。 javac.opt.print=输出指定类型的文本表示 javac.opt.printRounds=输出有关批注处理循环的信息 javac.opt.printProcessorInfo=输出有关请求处理程序处理哪些批注的信息 javac.opt.userpathsfirst=在引导类路径之前而不是之后搜索类的类路径和源路径 javac.opt.prefer=指定读取文件, 当同时找到隐式编译类的源文件和类文件时 -javac.opt.preview=启用预览语言功能。要与 -source 或 --release 一起使用。 +# L10N: do not localize: ''preview'' +javac.opt.preview=启用预览语言功能。\n还禁用''preview''lint 类别。\n要与 -source 或 --release 一起使用。 javac.opt.AT=从文件读取选项和文件名 javac.opt.diags=选择诊断模式 javac.opt.addExports=指定被视为已从其定义模块导出到其他模块或者导出到所有\n 未命名模块 (如果 为 ALL-UNNAMED) 的程序包。 diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_de.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_de.properties index 1edda5da22f..bb0f14ab833 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_de.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_de.properties @@ -111,6 +111,9 @@ launcher.err.cant.access.main.method=kein Zugriff auf Methode "main" in Klasse: # 0: string launcher.err.cant.find.constructor=No-Argument-Konstruktor nicht gefunden in Klasse: {0} +# 0: string +launcher.err.cant.use.private.constructor=Kein nicht privater Null-Argument-Konstruktor in Klasse {0} gefunden\nEntfernen Sie die Eigenschaft "private" aus dem vorhandenen Konstruktor, oder definieren Sie ihn als:\n public {0}() + # 0: string launcher.err.cant.access.constructor=Kein Zugriff auf No-Argument-Konstruktor in Klasse: {0} diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_ja.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_ja.properties index be1feb4a8a9..ed940e731bd 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_ja.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_ja.properties @@ -111,6 +111,9 @@ launcher.err.cant.access.main.method=クラスのメイン・メソッドにア # 0: string launcher.err.cant.find.constructor=クラスに引数なしのコンストラクタが見つかりません: {0} +# 0: string +launcher.err.cant.use.private.constructor=非privateのゼロ引数コンストラクタがクラス{0}に見つかりません\n既存のコンストラクタからprivateを削除するか、次のように定義してください:\n public {0}() + # 0: string launcher.err.cant.access.constructor=クラスの引数なしのコンストラクタにアクセスできません: {0} diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_zh_CN.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_zh_CN.properties index 5367036d82f..1fafa95c146 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_zh_CN.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/launcher_zh_CN.properties @@ -111,6 +111,9 @@ launcher.err.cant.access.main.method=无法访问类 {0} 中的 main 方法 # 0: string launcher.err.cant.find.constructor=在类 {0} 中找不到无参数构造器 +# 0: string +launcher.err.cant.use.private.constructor=在类 {0} 中未找到 non-private 零参数构造器\n请从现有构造器中删除 private,或者定义为:\n public {0}() + # 0: string launcher.err.cant.access.constructor=无法访问类 {0} 中的无参数构造器 diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_de.properties b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_de.properties index c5d9f41ee85..2b76f1408fa 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_de.properties +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_de.properties @@ -220,3 +220,4 @@ entry.1.is.signed.in.jarinputstream.but.is.not.signed.in.jarfile=Eintrag %s ist jar.contains.internal.inconsistencies.result.in.different.contents.via.jarfile.and.jarinputstream=Diese JAR-Datei enthält interne Inkonsistenzen, die zu anderem Inhalt beim Lesen über JarFile als beim Lesen über JarInputStream führen können: signature.verification.failed.on.entry.1.when.reading.via.jarinputstream=Signaturverifizierung war für Eintrag %s beim Lesen über JarInputStream nicht erfolgreich signature.verification.failed.on.entry.1.when.reading.via.jarfile=Signaturverifizierung war für Eintrag %s beim Lesen über JarFile nicht erfolgreich +jks.storetype.warning=%1$s verwendet veraltete kryptografische Algorithmen und wird in einer zukünftigen Version entfernt. Migrieren Sie zu PKCS12 mit:\nkeytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12 diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_ja.properties b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_ja.properties index 97ab6a918cb..f2a5ce39be3 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_ja.properties +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_ja.properties @@ -220,3 +220,4 @@ entry.1.is.signed.in.jarinputstream.but.is.not.signed.in.jarfile=エントリ%s jar.contains.internal.inconsistencies.result.in.different.contents.via.jarfile.and.jarinputstream=このJARファイルには内部的な不整合があるため、JarFileとJarInputStreamから読み取る場合にコンテンツが異なる可能性があります: signature.verification.failed.on.entry.1.when.reading.via.jarinputstream=JarInputStreamを介して読み取るときに署名検証がエントリ%sで失敗しました signature.verification.failed.on.entry.1.when.reading.via.jarfile=JarFileを介して読み取るときに署名検証がエントリ%sで失敗しました +jks.storetype.warning=%1$sは古い暗号化アルゴリズムを使用しているため、将来のリリースで削除されます。次を使用してPKCS12に移行します:\nkeytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12 diff --git a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_zh_CN.properties b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_zh_CN.properties index 378cc3ba9fc..f780bd1f1c3 100644 --- a/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_zh_CN.properties +++ b/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/resources/jarsigner_zh_CN.properties @@ -220,3 +220,4 @@ entry.1.is.signed.in.jarinputstream.but.is.not.signed.in.jarfile=条目 %s 已 jar.contains.internal.inconsistencies.result.in.different.contents.via.jarfile.and.jarinputstream=此 JAR 文件包含内部不一致,通过 JarFile 和 JarInputStream 读取时可能会导致内容不同: signature.verification.failed.on.entry.1.when.reading.via.jarinputstream=通过 JarInputStream 读取时,条目 %s 的签名验证失败 signature.verification.failed.on.entry.1.when.reading.via.jarfile=通过 JarFile 读取时,条目 %s 的签名验证失败 +jks.storetype.warning=%1$s 使用的加密算法已过时,将在未来发行版中删除。请使用以下命令迁移到 PKCS12:\nkeytool -importkeystore -srckeystore %2$s -destkeystore %2$s -deststoretype pkcs12 diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_de.properties b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_de.properties index 2a5786e10b4..292ec9c963d 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_de.properties +++ b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_de.properties @@ -80,6 +80,8 @@ error.validator.info.opens.notequal=module-info.class in einem versionierten Ver error.validator.info.provides.notequal=module-info.class in einem versionierten Verzeichnis enthält unterschiedliche "provides" error.validator.info.version.notequal={0}: module-info.class in einem versionierten Verzeichnis enthält unterschiedlichen "version"-Wert error.validator.info.manclass.notequal={0}: module-info.class in einem versionierten Verzeichnis enthält unterschiedlichen "main-class"-Wert +error.validator.metainf.wrong.position=Eintrag META-INF/ an Position 0 erwartet, aber an Position {0} gefunden +error.validator.manifest.wrong.position=Eintrag META-INF/MANIFEST.MF an Position 0 oder 1 erwartet, aber an Position {0} gefunden warn.validator.identical.entry=Warnung: Eintrag {0} enthält eine Klasse, die mit\neinem bereits in der JAR-Datei enthaltenen Eintrag identisch ist warn.validator.resources.with.same.name=Warnung: Eintrag {0}, mehrere Ressourcen mit demselben Namen warn.validator.concealed.public.class=Warnung: Eintrag {0} ist eine öffentliche Klasse\nin einem verdeckten Package. Wenn Sie diese JAR-Datei in den Classpath einfügen, kommt es\nzu nicht kompatiblen öffentlichen Schnittstellen diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ja.properties b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ja.properties index c7d7c14613a..0d0f91ad791 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ja.properties +++ b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_ja.properties @@ -80,6 +80,8 @@ error.validator.info.opens.notequal=バージョニング・ディレクトリ error.validator.info.provides.notequal=バージョニングされたディレクトリのmodule-info.classに異なる"provides"が含まれています error.validator.info.version.notequal={0}: バージョニングされたディレクトリのmodule-info.classに異なる"version"が含まれています error.validator.info.manclass.notequal={0}: バージョニングされたディレクトリのmodule-info.classに異なる"main-class"が含まれています +error.validator.metainf.wrong.position=エントリMETA-INF/は0の位置にある必要がありますが、見つかりました: {0} +error.validator.manifest.wrong.position=エントリMETA-INF/MANIFEST.MFは0または1の位置にある必要がありますが、位置: {0}で見つかりました warn.validator.identical.entry=警告 : エントリ{0}には、jarにすでに存在する\nエントリと同じクラスが含まれます warn.validator.resources.with.same.name=警告 : エントリ{0}、同じ名前を持つ複数のリソース warn.validator.concealed.public.class=警告 : エントリ{0}は、隠しパッケージ内のpublicクラスです。\nクラスパスにこのjarを配置すると、互換性のない\npublicインタフェースが生成されます diff --git a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_CN.properties b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_CN.properties index 1979f3e2386..41833d28bfc 100644 --- a/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_CN.properties +++ b/src/jdk.jartool/share/classes/sun/tools/jar/resources/jar_zh_CN.properties @@ -80,6 +80,8 @@ error.validator.info.opens.notequal=版本化目录中的 module-info.class 包 error.validator.info.provides.notequal=版本化目录中的 module-info.class 包含不同的 "provides" error.validator.info.version.notequal={0}: 版本化目录中的 module-info.class 包含不同的 "version" error.validator.info.manclass.notequal={0}: 版本化目录中的 module-info.class 包含不同的 "main-class" +error.validator.metainf.wrong.position=条目 META-INF/ 应位于位置 0 处,但发现:{0} +error.validator.manifest.wrong.position=条目 META-INF/MANIFEST.MF 应位于位置 0 或 1 处,但发现该条目位于位置 {0} 处 warn.validator.identical.entry=警告: 条目 {0} 包含与 jar 中的\n现有条目相同的类 warn.validator.resources.with.same.name=警告: 条目 {0}, 多个资源具有相同名称 warn.validator.concealed.public.class=警告: 条目 {0} 是已隐藏程序包中的\n公共类, 将此 jar 放置在类路径中\n将导致公共接口不兼容 diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_de.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_de.properties index 4cbb4b97774..a380b29d553 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_de.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_de.properties @@ -190,6 +190,10 @@ doclet.Window_Help_title=API-Hilfe doclet.references={0} Referenzen doclet.Window_Search_title=Suchen doclet.search.main_heading=Suchen +doclet.theme.select_theme=Theme auswählen +doclet.theme.light=Hell +doclet.theme.dark=Dunkel +doclet.theme.system=Systemeinstellung # label for link/button element to show the information below doclet.search.show_more=Zusätzliche Ressourcen @@ -539,3 +543,5 @@ doclet.NoFrames_specified=Die Option --no-frames wird nicht mehr benötigt und w # L10N: do not localize the option name -footer doclet.footer_specified=Die Option -footer wird nicht mehr unterstützt und wird ignoriert.\nSie wird möglicherweise in einem zukünftigen Release entfernt. + +doclet.selectModule=Wählen Sie das Modul aus, in dem gesucht werden soll. diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_ja.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_ja.properties index 2151b3f4a2e..69cdc862b4c 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_ja.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_ja.properties @@ -190,6 +190,10 @@ doclet.Window_Help_title=APIヘルプ doclet.references={0}の参照 doclet.Window_Search_title=検索 doclet.search.main_heading=検索 +doclet.theme.select_theme=テーマを選択 +doclet.theme.light=明るい +doclet.theme.dark=暗い +doclet.theme.system=システム設定 # label for link/button element to show the information below doclet.search.show_more=その他のリソース @@ -539,3 +543,5 @@ doclet.NoFrames_specified=--no-framesオプションは必須ではなくなり # L10N: do not localize the option name -footer doclet.footer_specified=-footerオプションはサポートされなくなったため、無視されます。\n将来のリリースで削除される可能性があります。 + +doclet.selectModule=検索するモジュールを選択します。 diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_zh_CN.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_zh_CN.properties index 66620d158bb..b3a0a3a1197 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_zh_CN.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard_zh_CN.properties @@ -190,6 +190,10 @@ doclet.Window_Help_title=API 帮助 doclet.references={0} 个引用 doclet.Window_Search_title=搜索 doclet.search.main_heading=搜索 +doclet.theme.select_theme=选择主题 +doclet.theme.light=浅色 +doclet.theme.dark=深色 +doclet.theme.system=系统设置 # label for link/button element to show the information below doclet.search.show_more=其他资源 @@ -539,3 +543,5 @@ doclet.NoFrames_specified=--no-frames 选项不再是必需的,可能\n会在 # L10N: do not localize the option name -footer doclet.footer_specified=-footer 选项不再受支持并将被忽略。\n可能会在未来发行版中删除此选项。 + +doclet.selectModule=选择要在其中搜索的模块。 diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_de.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_de.properties index 0ee34071c93..a6dbf050bf3 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_de.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_de.properties @@ -65,6 +65,7 @@ doclet.JavaScript_in_comment=JavaScript in Dokumentationskommentar gefunden.\nVe doclet.JavaScript_in_option=Option {0} enthält JavaScript.\nVerwenden Sie --allow-script-in-comments, um die Verwendung von JavaScript zuzulassen. doclet.Link_icon=Linksymbol doclet.Link_to_section=Link zu diesem Abschnitt +doclet.Toggle_member_listing=Zwischen kurzer und detaillierter Listenansicht umschalten doclet.Packages=Packages doclet.All_Packages=Alle Packages doclet.Modules=Module @@ -114,7 +115,7 @@ doclet.inheritDocWithinInappropriateTag=@inheritDoc kann in diesem Tag nicht ver doclet.inheritDocNoDoc=überschriebene Methoden dokumentieren Ausnahmetyp {0} nicht doclet.throwsInheritDocUnsupported=@inheritDoc wird für Parameter vom Typ Ausnahme, die nicht von einer Methode deklariert werden, nicht unterstützt. Dokumentieren Sie solche Ausnahmetypen direkt. doclet.noInheritedDoc=@inheritDoc wurde verwendet, aber mit {0} wird keine Methode außer Kraft gesetzt oder implementiert. -doclet.tag_misuse=Tag {0} kann nicht in {1}-Dokumentation verwendet werden. Es kann nur in folgenden Dokumentationstypen verwendet werden: {2}. +doclet.tag_misuse=Tag {0} kann nicht in Dokumentation {1} verwendet werden. Es kann nur in folgenden Dokumentationstypen verwendet werden: {2}. doclet.Package_Summary=Packageübersicht doclet.Requires_Summary=Erfordernisse doclet.Indirect_Requires_Summary=Indirekte Erfordernisse @@ -226,7 +227,7 @@ doclet.search=Suchen doclet.search_placeholder=In Dokumentation suchen ("/" eingeben) doclet.search_in_documentation=In Dokumentation suchen doclet.search_reset=Zurücksetzen -doclet.Member=Mitglied +doclet.Member=Member doclet.Field=Feld doclet.Property=Eigenschaft doclet.Constructor=Konstruktor @@ -240,11 +241,14 @@ doclet.Description=Beschreibung doclet.ConstantField=Konstantenfeld doclet.Value=Wert doclet.table_of_contents=Inhaltsverzeichnis +doclet.Sort_lexicographically=Member-Details lexikographisch sortieren +doclet.Sort_by_source_order=Member-Details nach Quellreihenfolge sortieren doclet.hide_sidebar=Randleiste ausblenden doclet.show_sidebar=Randleiste einblenden doclet.filter_label=Inhalt filtern ("." eingeben) doclet.filter_table_of_contents=Inhaltsverzeichnis filtern doclet.filter_reset=Zurücksetzen +doclet.sort_table_of_contents=Member-Details in lexikographischer Reihenfolge sortieren doclet.linkMismatch_PackagedLinkedtoModule=Der Code, der dokumentiert wird, verwendet Packages im unbenannten Modul, aber die in {0} definierten Packages befinden sich in benannten Modulen. doclet.linkMismatch_ModuleLinkedtoPackage=Der Code, der dokumentiert wird, verwendet Module, aber die in {0} definierten Packages befinden sich im unbenannten Modul. doclet.urlRedirected=URL {0} wurde umgeleitet an {1} - Aktualisieren Sie die Befehlszeilenoptionen, um diese Warnung zu unterdrücken. diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties index 2b10f4e6e9a..1970203da38 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_ja.properties @@ -65,6 +65,7 @@ doclet.JavaScript_in_comment=ドキュメント・コメントにJavaScriptが doclet.JavaScript_in_option=オプション{0}にJavaScriptが含まれています。\n--allow-script-in-commentsを使用して、JavaScriptの使用を許可してください。 doclet.Link_icon=リンク・アイコン doclet.Link_to_section=このセクションにリンク +doclet.Toggle_member_listing=短いリスト・ビューと詳細リスト・ビューの切替え doclet.Packages=パッケージ doclet.All_Packages=すべてのパッケージ doclet.Modules=モジュール @@ -240,11 +241,14 @@ doclet.Description=説明 doclet.ConstantField=定数フィールド doclet.Value=値 doclet.table_of_contents=目次 +doclet.Sort_lexicographically=メンバー詳細を辞書順にソート +doclet.Sort_by_source_order=メンバー詳細をソース順序にソート doclet.hide_sidebar=サイドバーの非表示 doclet.show_sidebar=サイドバーの表示 doclet.filter_label=コンテンツのフィルタ(.と入力) doclet.filter_table_of_contents=目次のフィルタ doclet.filter_reset=リセット +doclet.sort_table_of_contents=メンバー詳細を辞書順にソート doclet.linkMismatch_PackagedLinkedtoModule=ドキュメント化しようとしているコードでは名前のないモジュールのパッケージが使用されていますが、{0}で定義されているパッケージは名前のあるモジュールのものです。 doclet.linkMismatch_ModuleLinkedtoPackage=ドキュメント化しようとしているコードではモジュールが使用されていますが、{0}で定義されているパッケージは名前のないモジュールのものです。 doclet.urlRedirected=URL {0}は{1}にリダイレクトされました -- コマンドライン・オプションを更新してこの警告を表示しないようにしてください。 diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties index f2c8762b283..62e51c2c1c4 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/resources/doclets_zh_CN.properties @@ -65,6 +65,7 @@ doclet.JavaScript_in_comment=文档注释中发现 JavaScript。\n使用 --allow doclet.JavaScript_in_option=选项 {0} 包含 JavaScript。\n使用 --allow-script-in-comments 可允许使用 JavaScript。 doclet.Link_icon=链接图标 doclet.Link_to_section=链接到此节 +doclet.Toggle_member_listing=在简短列表视图和详细列表视图之间切换 doclet.Packages=程序包 doclet.All_Packages=所有程序包 doclet.Modules=模块 @@ -240,11 +241,14 @@ doclet.Description=说明 doclet.ConstantField=常量字段 doclet.Value=值 doclet.table_of_contents=目录 +doclet.Sort_lexicographically=按字典顺序对成员详细信息进行排序 +doclet.Sort_by_source_order=按源顺序对成员详细信息进行排序 doclet.hide_sidebar=隐藏子工具栏 doclet.show_sidebar=显示子工具栏 doclet.filter_label=筛选内容(键入 .) doclet.filter_table_of_contents=筛选目录 doclet.filter_reset=重置 +doclet.sort_table_of_contents=按字典顺序对成员详细信息进行排序 doclet.linkMismatch_PackagedLinkedtoModule=进行文档化的代码使用了未命名模块中的程序包,但在 {0} 中定义的程序包在命名模块中。 doclet.linkMismatch_ModuleLinkedtoPackage=进行文档化的代码使用了模块,但在 {0} 中定义的程序包在未命名模块中。 doclet.urlRedirected=URL {0} 已重定向到 {1} — 更新命令行选项以隐藏此警告。 diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_de.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_de.properties index 7829d2d7e27..57137ffe75d 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_de.properties +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc_de.properties @@ -52,7 +52,7 @@ main.opt.package.desc=Zeigt Package-/geschützte/öffentliche Typen und Mitglied main.opt.private.desc=Zeigt alle Typen und Mitglieder. Zeigt bei benannten Modulen\nalle Packages und alle Moduldetails. main.opt.show.members.arg= -main.opt.show.members.desc=Gibt an, welche Member (Felder, Methoden oder Konstruktoren) dokumentiert\nwerden, wobei der Wert "public", "protected",\n"package" oder "private" lauten kann. Der Standardwert ist "protected"\nund zeigt öffentliche und geschützte Member an. "public" zeigt nur\nöffentliche Member, "package" zeigt öffentliche, geschützte und\nPackage-Member, und "private" zeigt alle Member an. +main.opt.show.members.desc=Gibt an, welche Members (Felder, Methoden oder Konstruktoren) dokumentiert\nwerden, wobei der Wert "public", "protected",\n"package" oder "private" lauten kann. Der Standardwert ist "protected"\nund zeigt öffentliche und geschützte Members an. "public" zeigt nur\nöffentliche Members, "package" zeigt öffentliche, geschützte und\nPackage-Members, und "private" zeigt alle Members an. main.opt.show.types.arg= main.opt.show.types.desc=Gibt an, welche Typen (Klassen, Schnittstellen usw.) dokumentiert\nwerden, wobei der Wert "public", "protected",\n"package" oder "private" lauten kann. Der Standardwert ist "protected"\nund zeigt öffentliche und geschützte Typen, "public" zeigt nur\nöffentliche Typen, "package" zeigt öffentliche, geschützte und\nPackagetypen, und "private" zeigt alle Typen. diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_de.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_de.properties index 9b776745c66..40022a5532b 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_de.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_de.properties @@ -78,7 +78,8 @@ err.runtime.link.patched.module=jlink unterstützt keine Verknüpfung vom Laufze err.no.module.path=Option --module-path muss mit --add-modules ALL-MODULE-PATH angegeben werden err.empty.module.path=Kein Modul im Modulpfad "{0}" mit --add-modules ALL-MODULE-PATH gefunden err.limit.modules=--limit-modules nicht mit --add-modules ALL-MODULE-PATH zulässig -err.jlink.version.mismatch=jlink-Version {0}.{1} stimmt nicht mit Ziel-java.base-Version {2}.{3} überein +err.jlink.version.mismatch=jlink-Build "{0}" stimmt nicht mit dem java.base-Ziel-Build "{1}" überein +err.jlink.version.missing=jlink-Build "{0}" kann die Build-Signatur nicht im Modul java.base finden, das im Modulpfad angegebenen wird. Wahrscheinlich stammt es aus einem früheren Build. err.automatic.module:automatisches Modul kann nicht mit jlink verwendet werden: {0} aus {1} err.unknown.byte.order:unbekannte Bytereihenfolge {0} err.launcher.main.class.empty:Launcher-Hauptklassenname darf nicht leer sein: {0} diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_ja.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_ja.properties index c925f250c41..9519a24c96e 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_ja.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_ja.properties @@ -78,7 +78,8 @@ err.runtime.link.patched.module=--patch-moduleを使用してパッチ済ラン err.no.module.path=--module-pathオプションは--add-modules ALL-MODULE-PATHで指定する必要があります err.empty.module.path=モジュール・パス''{0}''に--add-modules ALL-MODULE-PATHを使用したモジュールが見つかりません err.limit.modules=--limit-modulesは--add-modules ALL-MODULE-PATHとともに指定できません -err.jlink.version.mismatch=jlinkバージョン{0}.{1}がターゲットのjava.baseバージョン{2}.{3}と一致しません +err.jlink.version.mismatch=jlinkビルド''{0}''がターゲットのjava.baseビルド''{1}''と一致しません +err.jlink.version.missing=jlinkビルド''{0}''では、モジュール・パスで指定されたjava.baseにビルド署名が見つかりません(おそらく以前のビルドから)。 err.automatic.module:jlinkでは自動モジュールは使用できません: {1}からの{0} err.unknown.byte.order:不明なバイト順{0} err.launcher.main.class.empty:起動ツールのメイン・クラス名は空にできません: {0} diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_zh_CN.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_zh_CN.properties index b7526c9f57a..81af170ae7f 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_zh_CN.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink_zh_CN.properties @@ -78,7 +78,8 @@ err.runtime.link.patched.module=当使用 --patch-module 在打补丁的运行 err.no.module.path=--module-path 选项必须与 --add-modules ALL-MODULE-PATH 一起指定 err.empty.module.path=在随 --add-modules ALL-MODULE-PATH 提供的模块路径 ''{0}'' 中找不到模块 err.limit.modules=不允许将 --limit-modules 与 --add-modules ALL-MODULE-PATH 一起使用 -err.jlink.version.mismatch=jlink 版本 {0}.{1} 与目标 java.base 版本 {2}.{3} 不匹配 +err.jlink.version.mismatch=jlink 工作版本 ''{0}'' 与目标 java.base 工作版本 ''{1}'' 不匹配 +err.jlink.version.missing=jlink 工作版本 ''{0}'' 在模块路径中指定的 java.base 中找不到工作版本签名,可能来自早期工作版本。 err.automatic.module:自动模块不能用于来自 {1} 的 jlink: {0} err.unknown.byte.order:未知的字节顺序 {0} err.launcher.main.class.empty:启动程序主类名不能为空: {0} diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_de.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_de.properties index 4713eabed85..80d1ba6e05f 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_de.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_de.properties @@ -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 @@ -31,9 +31,9 @@ add-options.usage=\ --add-options Stellt die angegebene release-info.argument=|add:=:=:...|del: -release-info.description=-Option lädt Releaseeigenschaften aus der angegebenen Datei.\nadd: fügt der Datei "release" Eigenschaften hinzu.\nEine beliebige Anzahl von =-Paaren kann übergeben werden.\ndel: löscht die Liste der Schlüssel in der Releasedatei. +release-info.description=Option lädt Releaseeigenschaften aus der angegebenen Datei.\n Die angegebene Datei soll erwartungsgemäß in UTF-8 codiert sein.\nadd: fügt der Datei "release" Eigenschaften hinzu.\nEine beliebige Anzahl von =-Paaren kann übergeben werden.\ndel: löscht die Liste der Schlüssel in der Releasedatei. -release-info.usage=\ --release-info |add:=:=:...|del:\n Option löscht Releaseeigenschaften aus\n der angegebenen Datei.\n add: fügt Eigenschaften der Datei "release" hinzu.\n Eine beliebige Anzahl =-Paare kann übergeben werden.\n del: löscht die Liste der Schlüssel in der Releasedatei. +release-info.usage=\ --release-info |add:=:=:...|del:\n Option lädt Releaseeigenschaften aus\n der angegebenen Datei. Die angegebene Datei soll erwartungsgemäß\n in UTF-8 codiert sein.\n add: fügt der Datei "release" Eigenschaften hinzu.\n Eine beliebige Anzahl =-Paare kann übergeben werden.\n del: löscht die Liste der Schlüssel in der Releasedatei. class-for-name.argument= @@ -41,11 +41,11 @@ class-for-name.description=Klassenoptimierung: Konvertiert Class.forName-Aufrufe class-for-name.usage=\ --class-for-name Klassenoptimierung: Konvertiert Class.forName-Aufrufe in Konstantenladevorgänge. -compress.argument=[:filter=] +compress.argument=[:filter=] compress.description= Zu verwendende Komprimierung für Ressourcen. -compress.usage=\ --compress Zu verwendende Komprimierung für Ressourcen:\n Zulässige Werte:\n zip-[0-9], wobei "zip-0" für keine Komprimierung\n und "zip-9" für die beste Komprimierung steht.\n Standardwert ist "zip-6". +compress.usage=\ --compress Zu verwendende Komprimierung für Ressourcen:\n Zulässige Werte:\n zip-'{0-9}', wobei "zip-0" für keine Komprimierung\n und "zip-9" für die beste Komprimierung steht.\n Standardwert ist "zip-6". compress.warn.argumentdeprecated=Warnung: Das Argument {0} für --compress ist veraltet und wird möglicherweise in einem zukünftigen Release entfernt @@ -170,7 +170,7 @@ plugin.opt.resources-last-sorter=\ --resources-last-sorter Das le plugin.opt.disable-plugin=\ --disable-plugin Deaktiviert das angegebene Plug-in -plugin.opt.compress=\ --compress Zu verwendende Komprimierung für Ressourcen:\n Zulässige Werte:\n zip-[0-9], wobei "zip-0" für keine Komprimierung\n und "zip-9" für die beste Komprimierung steht.\n Standardwert ist "zip-6".\n Veraltete Werte, die in einem zukünftigen Release entfernt werden:\n 0: Keine Komprimierung. Entspricht "zip-0".\n 1: Gemeinsame Verwendung konstanter Zeichenfolgen\n 2: Entspricht "zip-6". +plugin.opt.compress=\ --compress Komprimiert alle Ressourcen im Ausgabeimage:\n Zulässige Werte:\n zip-'{0-9}', wobei "zip-0" für keine Komprimierung\n und "zip-9" für die beste Komprimierung steht.\n Standardwert ist "zip-6."\n Veraltete Werte, die in einem zukünftigen Release entfernt werden:\n 0: Keine Komprimierung. Verwenden Sie stattdessen "zip-0".\n 1: Gemeinsame Verwendung konstanter Zeichenfolgen\n 2: ZIP. Verwenden Sie stattdessen "zip-6". plugin.opt.strip-debug=\ -G, --strip-debug Entfernt Debuginformationen diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_ja.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_ja.properties index 1cf3ba5b0c0..6ed0a486132 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_ja.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_ja.properties @@ -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 @@ -31,9 +31,9 @@ add-options.usage=\ --add-options 指定した文字列を release-info.argument=|add:=:=:...|del: -release-info.description=オプションは指定されたファイルからリリース・プロパティをロードします。\nadd:はリリース・ファイルにプロパティを追加します。\n任意の数の=のペアを渡すことができます。\ndel:はリリース・ファイルのキーのリストを削除します。 +release-info.description=オプションは指定されたファイルからリリース・プロパティをロードします。\n 指定されたファイルはUTF-8でエンコードされる必要があります。\nadd:はリリース・ファイルにプロパティを追加します。\n任意の数の=のペアを渡すことができます。\ndel:はリリース・ファイルのキーのリストを削除します。 -release-info.usage=\ --release-info |add:=:=:...|del:\n オプションは指定されたファイルからリリース・プロパティを\n ロードします。\n add:はリリース・ファイルにプロパティを追加します。\n 任意の数の=ペアを渡すことができます。\n del:はリリース・ファイルのキーのリストを削除します。 +release-info.usage=\ --release-info |add:=:=:...|del:\n オプションは指定されたファイルからリリース・プロパティを\n ロードします。指定されたファイルはUTF-8で\n エンコードされる必要があります。\n add:はリリース・ファイルにプロパティを追加します。\n 任意の数の=ペアを渡すことができます。\n del:はリリース・ファイルのキーのリストを削除します。 class-for-name.argument= @@ -41,11 +41,11 @@ class-for-name.description=クラスの最適化: Class.forName呼出しを定 class-for-name.usage=\ --class-for-name クラスの最適化: Class.forName呼出しを定数のロードに変換します。 -compress.argument=[:filter=] +compress.argument=[:filter=] compress.description= リソースの圧縮に使用する圧縮。 -compress.usage=\ --compress リソースの圧縮に使用する圧縮:\n 使用可能な値は\n zip-[0-9]です。zip-0では圧縮は行われず、\n zip-9では最適な圧縮が行われます。\n デフォルトはzip-6です。 +compress.usage=\ --compress リソースの圧縮に使用する圧縮:\n 使用可能な値は\n zip-'{0-9}'です。zip-0では圧縮は行われず、\n zip-9では最適な圧縮が行われます。\n デフォルトはzip-6です。 compress.warn.argumentdeprecated=警告: --compressの{0}引数は非推奨であり、今後のリリースで削除される可能性があります @@ -170,7 +170,7 @@ plugin.opt.resources-last-sorter=\ --resources-last-sorter 最後 plugin.opt.disable-plugin=\ --disable-plugin 指定したプラグインを無効にします -plugin.opt.compress=\ --compress リソースの圧縮に使用する圧縮:\n 使用可能な値は\n zip-[0-9]です。zip-0では圧縮は行われず、\n zip-9では最適な圧縮が行われます。\n デフォルトはzip-6です。\n 今後のリリースで削除される非推奨の値:\n 0: 圧縮なし。zip-0と同等。\n 1: 定数文字列の共有\n 2: zip-6と同等。 +plugin.opt.compress=\ --compress 出力イメージ内のすべてのリソースを圧縮します:\n 使用可能な値は\n zip-'{0-9}'です。zip-0では圧縮は行われず、\n zip-9では最適な圧縮が行われます。\n デフォルトはzip-6です。\n 今後のリリースで削除される非推奨の値:\n 0: 圧縮なし。かわりにzip-0を使用。\n 1: 定数文字列の共有\n 2: ZIP。かわりにzip-6を使用。 plugin.opt.strip-debug=\ -G, --strip-debug デバッグ情報を削除します diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_zh_CN.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_zh_CN.properties index 819238e7d04..a0480a31fc3 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_zh_CN.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins_zh_CN.properties @@ -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 @@ -31,9 +31,9 @@ add-options.usage=\ --add-options 在生成的映像中调用虚拟 release-info.argument=|add:=:=:...|del: -release-info.description= 选项:从提供的文件加载 release 属性。\nadd:向 'release' 文件中添加属性。\n可以传递任意数量的 = 对。\ndel:删除 release 文件中的关键字列表。 +release-info.description= 选项:从提供的文件加载 release 属性。\n 指定的文件应采用 UTF-8 编码。\nadd:向 'release' 文件中添加属性。\n可以传递任意数量的 = 对。\ndel:删除 release 文件中的关键字列表。 -release-info.usage=\ --release-info |add:=:=:...|del:\n 选项:从提供的文件\n 加载 release 属性。\n add:向 'release' 文件中添加属性。\n 可以传递任意数量的 = 对。\n del:删除 release 文件中的关键字列表。 +release-info.usage=\ --release-info |add:=:=:...|del:\n 选项:从提供的文件\n 加载 release 属性。指定的文件\n 应采用 UTF-8 编码。\n add:向 'release' 文件中添加属性。\n 可以传递任意数量的 = 对。\n del:删除 release 文件中的关键字列表。 class-for-name.argument= @@ -41,11 +41,11 @@ class-for-name.description=类优化:将 Class.forName 调用转换为常量 class-for-name.usage=\ --class-for-name 类优化:将 Class.forName 调用转换为常量负载。 -compress.argument=[:filter=] +compress.argument=[:filter=] compress.description= 要在压缩资源时使用的压缩。 -compress.usage=\ --compress 要在压缩资源时使用的压缩:\n 接受的值为:\n zip-[0-9],其中 zip-0 表示无压缩,\n zip-9 表示最佳压缩。\n 默认值为 zip-6。 +compress.usage=\ --compress 要在压缩资源时使用的压缩:\n 接受的值为:\n zip-'{0-9}',其中 zip-0 表示无压缩,\n zip-9 表示最佳压缩。\n 默认值为 zip-6。 compress.warn.argumentdeprecated=警告:--compress 的 {0} 参数已过时,可能会在未来发行版中删除 @@ -170,7 +170,7 @@ plugin.opt.resources-last-sorter=\ --resources-last-sorter 允许 plugin.opt.disable-plugin=\ --disable-plugin 禁用所提及的插件 -plugin.opt.compress=\ --compress 要在压缩资源时使用的压缩:\n 接受的值为:\n zip-[0-9],其中 zip-0 表示无压缩,\n zip-9 表示最佳压缩。\n 默认值为 zip-6。\n 要在未来发行版中删除的已过时值:\n 0:无压缩。等同于 zip-0。\n 1:常量字符串共享\n 2:等同于 zip-6。 +plugin.opt.compress=\ --compress 在输出映像中压缩所有资源:\n 接受的值包括:\n zip-'{0-9}',其中 zip-0 表示无压缩,\n zip-9 表示最佳压缩。\n 默认值为 zip-6。\n 要在未来发行版中删除的已过时值:\n 0:无压缩。改为使用 zip-0。\n 1:常量字符串共享\n 2:ZIP。改为使用 zip-6。 plugin.opt.strip-debug=\ -G, --strip-debug 去除调试信息 diff --git a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_de.properties b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_de.properties index 2f8fcddff73..345ed36b7be 100644 --- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_de.properties +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_de.properties @@ -23,12 +23,7 @@ # questions. # # -app.bundler.name=Linux-Anwendungsimage -deb.bundler.name=DEB-Bundle -rpm.bundler.name=RPM-Bundle - param.license-type.default=Unbekannt -param.menu-group.default=Unbekannt resource.deb-control-file=DEB-Kontrolldatei resource.deb-preinstall-script=DEB-Preinstall-Skript @@ -59,7 +54,6 @@ message.output-to-location=Package (.deb) gespeichert in: {0}. message.debs-like-licenses=Debian-Packages müssen eine Lizenz angeben. Bei fehlender Lizenz geben einige Linux-Distributionen eine Meldung über eine Beeinträchtigung der Anwendungsqualität aus. message.outputting-bundle-location=RPM für Installationsprogramm wird generiert in: {0}. message.output-bundle-location=Package (.rpm) gespeichert in: {0}. -message.creating-association-with-null-extension=Verknüpfung mit Nullerweiterung wird erstellt. message.ldd-not-available=ldd-Befehl nicht gefunden. Packageabhängigkeiten werden nicht generiert. message.deb-ldd-not-available.advice=Installieren Sie das DEB-Package "libc-bin", um ldd abzurufen. diff --git a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_ja.properties b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_ja.properties index be2cd00b42c..d0bc4f73407 100644 --- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_ja.properties +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_ja.properties @@ -23,12 +23,7 @@ # questions. # # -app.bundler.name=Linuxアプリケーション・イメージ -deb.bundler.name=DEBバンドル -rpm.bundler.name=RPMバンドル - param.license-type.default=不明 -param.menu-group.default=不明 resource.deb-control-file=DEB制御ファイル resource.deb-preinstall-script=DEBインストール前スクリプト @@ -59,7 +54,6 @@ message.output-to-location=パッケージ(.deb)は次に保存されました: message.debs-like-licenses=Debianパッケージではライセンスを指定する必要があります。ライセンスがない場合、一部のLinuxディストリビューションでアプリケーションの品質に問題が発生する場合があります。 message.outputting-bundle-location=インストーラのRPMを次に生成しています: {0} message.output-bundle-location=パッケージ(.rpm)は次に保存されました: {0} -message.creating-association-with-null-extension=null拡張子との関連付けを作成しています。 message.ldd-not-available=lddコマンドが見つかりませんでした。パッケージ依存性は生成されません。 message.deb-ldd-not-available.advice="libc-bin" DEBパッケージをインストールしてlddを取得します。 diff --git a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_zh_CN.properties b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_zh_CN.properties index 5b583062ab6..f3d62675c4d 100644 --- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_zh_CN.properties +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/resources/LinuxResources_zh_CN.properties @@ -23,12 +23,7 @@ # questions. # # -app.bundler.name=Linux 应用程序映像 -deb.bundler.name=DEB 包 -rpm.bundler.name=RPM 包 - param.license-type.default=未知 -param.menu-group.default=未知 resource.deb-control-file=DEB 控制文件 resource.deb-preinstall-script=DEB 安装前脚本 @@ -59,7 +54,6 @@ message.output-to-location=程序包 (.deb) 已保存到: {0}。 message.debs-like-licenses=Debian 程序包应指定许可证。缺少许可证将导致某些 Linux 分发投诉应用程序质量。 message.outputting-bundle-location=正在为安装程序生成 RPM, 位置: {0}。 message.output-bundle-location=程序包 (.rpm) 已保存到: {0}。 -message.creating-association-with-null-extension=正在使用空扩展名创建关联。 message.ldd-not-available=未找到 ldd 命令。将不生成程序包被依赖对象。 message.deb-ldd-not-available.advice=安装 "libc-bin" DEB 程序包以获取 ldd。 diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_de.properties b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_de.properties index 7e36a260c3f..3cc56bb6cdf 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_de.properties +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_de.properties @@ -23,24 +23,19 @@ # questions. # # - -app.bundler.name=Mac-Anwendungsimage -store.bundler.name=Mac App Store-fähiger Bundler -dmg.bundler.name=Mac-DMG-Package -pkg.bundler.name=Mac-PKG-Package - error.invalid-cfbundle-version.advice=Legen Sie einen kompatiblen Wert für "app-version" fest. Gültige Versionsnummern sind ein bis drei durch Punkte getrennte Ganzzahlen. error.explicit-sign-no-cert=Signatur wurde explizit angefordert, doch es wurde kein Signaturzertifikat gefunden error.explicit-sign-no-cert.advice=Geben Sie gültige Werte für mac-signing-key-user-name und mac-signing-keychain an -error.must-sign-app-store=Mac App Store-Apps müssen signiert werden. Die Signierung wurde von der Bundler-Konfiguration deaktiviert -error.must-sign-app-store.advice=Verwenden Sie die Option --mac-sign mit entsprechenden Werten für user-name und keychain -error.certificate.expired=Fehler: Zertifikat abgelaufen {0} +error.certificate.expired=Zertifikat abgelaufen {0} error.cert.not.found=Kein Zertifikat gefunden, das [{0}] mit Schlüsselbund [{1}] entspricht -error.multiple.certs.found=WARNUNG: Mehrere Zertifikate gefunden, die [{0}] mit Schlüsselbund [{1}] entsprechen. Es wird das erste Zertifikat verwendet -error.app-image.mac-sign.required=Fehler: Die Option "--mac-sign" ist mit einem vordefinierten Anwendungsimage und Typ [app-image] erforderlich -error.tool.failed.with.output=Fehler: "{0}" nicht erfolgreich mit folgender Ausgabe: -resource.bundle-config-file=Bundle-Konfigurationsdatei +error.multiple.certs.found=Mehrere Zertifikate mit Namen [{0}] in Schlüsselbund [{1}] gefunden +error.app-image.mac-sign.required=Die Option --mac-sign ist mit einem vordefinierten Anwendungsimage und Typ [app-image] erforderlich +error.tool.failed.with.output="{0}" war mit folgender Ausgabe nicht erfolgreich: +error.invalid-runtime-image-missing-file=Im Laufzeitimage "{0}" fehlt die Datei "{1}" +error.invalid-runtime-image-bin-dir=Laufzeitimage "{0}" darf keinen Ordner "bin" enthalten +error.invalid-runtime-image-bin-dir.advice=Verwenden Sie die jlink-Option --strip-native-commands, wenn das Laufzeitimage mit Option {0} generiert wird resource.app-info-plist=Info.plist der Anwendung +resource.app-runtime-info-plist=Eingebettete Info.plist von Java Runtime resource.runtime-info-plist=Info.plist von Java Runtime resource.entitlements=Mac-Berechtigungen resource.dmg-setup-script=DMG-Setupskript @@ -56,21 +51,15 @@ resource.pkg-background-image=PKG-Hintergrundbild resource.pkg-pdf=Projektdefinitionsdatei resource.launchd-plist-file=launchd-PLIST-Datei - message.bundle-name-too-long-warning={0} ist auf "{1}" gesetzt. Dies ist länger als 16 Zeichen. Kürzen Sie den Wert, um die Mac-Nutzungserfahrung zu verbessern. message.preparing-info-plist=Info.plist wird vorbereitet: {0}. message.icon-not-icns= Das angegebene Symbol "{0}" ist keine ICNS-Datei und wird nicht verwendet. Stattdessen wird das Standardsymbol verwendet. message.version-string-too-many-components="app-version" darf ein bis drei Zahlen aufweisen: 1, 1.2, 1.2.3. message.version-string-first-number-not-zero=Die erste Zahl in app-version darf nicht null oder negativ sein. -message.creating-association-with-null-extension=Verknüpfung mit Nullerweiterung wird erstellt. -message.ignoring.symlink=Warnung: codesign überspringt den Symlink {0}. -message.already.signed=Datei ist bereits signiert: {0}. -message.keychain.error=Fehler: Schlüsselbundliste kann nicht abgerufen werden. -message.building-bundle=Mac App Store-Package für {0} wird erstellt. +message.keychain.error=Schlüsselbundliste kann nicht abgerufen werden. message.invalid-identifier=Ungültige Mac-Bundle-ID [{0}]. message.invalid-identifier.advice=Geben Sie die ID mit "--mac-package-identifier" an. message.building-dmg=DMG-Package für {0} wird erstellt. -message.running-script=Shellskript wird auf Anwendungsimage [{0}] ausgeführt. message.preparing-dmg-setup=DMG-Setup wird vorbereitet: {0}. message.creating-dmg-file=DMG-Datei wird erstellt: {0}. message.dmg-cannot-be-overwritten=DMG-Datei [{0}] ist vorhanden und kann nicht entfernt werden. @@ -84,3 +73,5 @@ message.codesign.failed.reason.app.content="codesign" war nicht erfolgreich, und message.codesign.failed.reason.xcode.tools=Möglicher Grund für "codesign"-Fehler ist fehlender Xcode mit Befehlszeilen-Entwicklertools. Installieren Sie Xcode mit Befehlszeilen-Entwicklertools, und prüfen Sie, ob das Problem dadurch beseitigt wird. warning.unsigned.app.image=Warnung: Nicht signiertes app-image wird zum Erstellen von signiertem {0} verwendet. warning.per.user.app.image.signed=Warnung: Konfiguration der installierten Anwendung pro Benutzer wird nicht unterstützt, da "{0}" im vordefinierten signierten Anwendungsimage fehlt. +warning.non.standard.contents.sub.dir=Warnung: Der Dateiname des Verzeichnisses "{0}", das für die Option --app-content angegeben wurde, ist kein Standardunterverzeichnisname im Verzeichnis "Contents" des Anwendungs-Bundles. Möglicherweise verläuft die Codesignierung und/oder Notarisierung im Ergebnisanwendungs-Bundle nicht erfolgreich. +warning.app.content.is.not.dir=Warnung: Der Wert "{0}" der Option --app-content ist kein Verzeichnis. Möglicherweise verläuft die Codesignierung und/oder Notarisierung im Ergebnisanwendungs-Bundle nicht erfolgreich. diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_ja.properties b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_ja.properties index 4384d6507f9..d3150a34a86 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_ja.properties +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_ja.properties @@ -23,24 +23,19 @@ # questions. # # - -app.bundler.name=Macアプリケーション・イメージ -store.bundler.name=Mac App Storeの準備完了バンドラ -dmg.bundler.name=Mac DMGパッケージ -pkg.bundler.name=Mac PKGパッケージ - error.invalid-cfbundle-version.advice=互換性のある'app-version'値を設定します。有効なバージョンは、ドットで区切られた1から3つの整数です。 error.explicit-sign-no-cert=署名が明示的に要求されましたが、署名証明書が見つかりません error.explicit-sign-no-cert.advice=有効なmac-signing-key-user-nameおよびmac-signing-keychainを指定してください -error.must-sign-app-store=Mac App Storeアプリケーションは署名されている必要がありますが、署名はバンドラ構成によって無効化されています -error.must-sign-app-store.advice=--mac-signオプションを適切なuser-nameおよびkeychain付きで使用してください -error.certificate.expired=エラー: 証明書は{0}に期限が切れました +error.certificate.expired=証明書が期限切れです{0} error.cert.not.found=キーチェーン[{1}]を使用する[{0}]と一致する証明書が見つかりません -error.multiple.certs.found=警告: キーチェーン[{1}]を使用する[{0}]と一致する複数の証明書が見つかりました。最初のものを使用します -error.app-image.mac-sign.required=エラー: --mac-signオプションは、事前定義済アプリケーション・イメージおよびタイプ[app-image]で必要です -error.tool.failed.with.output=エラー: "{0}"は次の出力で失敗しました: -resource.bundle-config-file=バンドル構成ファイル +error.multiple.certs.found=名前[{0}]に一致する複数の証明書がキーチェーン[{1}]で見つかりました +error.app-image.mac-sign.required=--mac-signオプションは、事前定義済アプリケーション・イメージおよびタイプ[app-image]で必要です +error.tool.failed.with.output="{0}"は次の出力で失敗しました: +error.invalid-runtime-image-missing-file=ランタイム・イメージ"{0}"に"{1}"ファイルがありません +error.invalid-runtime-image-bin-dir=ランタイム・イメージ"{0}"に"bin"フォルダを含めることはできません +error.invalid-runtime-image-bin-dir.advice={0}オプションとともに使用されるランタイム・イメージを生成する場合は、--strip-native-commands jlinkオプションを使用します resource.app-info-plist=アプリケーションのInfo.plist +resource.app-runtime-info-plist=埋込みJavaランタイムのInfo.plist resource.runtime-info-plist=JavaランタイムのInfo.plist resource.entitlements=Mac権限 resource.dmg-setup-script=DMG設定スクリプト @@ -56,21 +51,15 @@ resource.pkg-background-image=pkg背景イメージ resource.pkg-pdf=プロジェクト定義ファイル resource.launchd-plist-file=launchd plistファイル - message.bundle-name-too-long-warning={0}が16文字を超える''{1}''に設定されています。Macでの操作性をより良くするために短くすることを検討してください。 message.preparing-info-plist=Info.plistを準備しています: {0}。 message.icon-not-icns= 指定したアイコン"{0}"はICNSファイルではなく、使用されません。デフォルト・アイコンがその位置に使用されます。 message.version-string-too-many-components='app-version'には、1、1.2、1.2.3など1から3の数字を使用できます。 message.version-string-first-number-not-zero=pp-versionの最初の数字は、ゼロまたは負の値にできません。 -message.creating-association-with-null-extension=null拡張子との関連付けを作成しています。 -message.ignoring.symlink=警告: codesignがsymlink {0}をスキップしています -message.already.signed=ファイルはすでに署名されています: {0}。 -message.keychain.error=エラー: キーチェーン・リストを取得できません。 -message.building-bundle={0}のMac App Storeパッケージを作成しています。 +message.keychain.error=キーチェーン・リストを取得できません。 message.invalid-identifier=macバンドル識別子[{0}]が無効です。 message.invalid-identifier.advice="--mac-package-identifier"で識別子を指定してください。 message.building-dmg={0}のDMGパッケージを作成しています -message.running-script=アプリケーション・イメージ[{0}]でシェル・スクリプトを実行しています。 message.preparing-dmg-setup=dmgの設定を準備しています: {0} message.creating-dmg-file=DMGファイルを作成しています: {0} message.dmg-cannot-be-overwritten=Dmgファイルは存在し[{0}]、削除できません。 @@ -84,3 +73,5 @@ message.codesign.failed.reason.app.content="codesign"が失敗したため、追 message.codesign.failed.reason.xcode.tools="codesign"失敗の考えられる理由は、Xcodeとコマンドライン・デベロッパ・ツールの欠落です。Xcodeとコマンドライン・デベロッパ・ツールをインストールして、問題が解決されるかを確認してください。 warning.unsigned.app.image=警告: 署名されていないapp-imageを使用して署名された{0}を作成します。 warning.per.user.app.image.signed=警告: 事前定義済の署名付きアプリケーション・イメージに"{0}"がないため、インストール済アプリケーションのユーザーごとの構成はサポートされません。 +warning.non.standard.contents.sub.dir=警告: --app-contentオプションに指定されたディレクトリ"{0}"のファイル名が、アプリケーション・バンドルの"Contents"ディレクトリ内の標準サブディレクトリ名ではありません。結果アプリケーション・バンドルは、コード署名および/または公証に失敗することがあります。 +warning.app.content.is.not.dir=警告: --app-contentオプションの値"{0}"はディレクトリではありません。結果アプリケーション・バンドルは、コード署名または公証(あるいはその両方)に失敗することがあります。 diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_zh_CN.properties b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_zh_CN.properties index 09c6d77694a..8ca2219b72f 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_zh_CN.properties +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/resources/MacResources_zh_CN.properties @@ -23,24 +23,19 @@ # questions. # # - -app.bundler.name=Mac 应用程序映像 -store.bundler.name=支持 Mac App Store 的打包程序 -dmg.bundler.name=Mac DMG 程序包 -pkg.bundler.name=Mac PKG 程序包 - error.invalid-cfbundle-version.advice=设置兼容的 'app-version' 值。有效版本包含一到三个用点分隔的整数。 error.explicit-sign-no-cert=已明确请求签名,但找不到签名证书 error.explicit-sign-no-cert.advice=指定有效的 mac-signing-key-user-name 和 mac-signing-keychain -error.must-sign-app-store=Mac App Store 应用程序必须签名, 而打包程序配置已禁用签名 -error.must-sign-app-store.advice=将 --mac-sign 选项用于适当的用户名和密钥链 -error.certificate.expired=错误: 证书已失效 {0} +error.certificate.expired=证书已到期 {0} error.cert.not.found=使用密钥链 [{1}] 找不到与 [{0}] 匹配的证书 -error.multiple.certs.found=警告:使用密钥链 [{1}] 找到多个与 [{0}] 匹配的证书,将使用第一个证书 -error.app-image.mac-sign.required=错误:预定义的应用程序映像和类型 [app image] 需要 --mac-sign 选项 -error.tool.failed.with.output=错误:"{0}" 失败,显示以下输出: -resource.bundle-config-file=包配置文件 +error.multiple.certs.found=在密钥链 [{1}] 中找到多个与名称 [{0}] 匹配的证书 +error.app-image.mac-sign.required=预定义的应用程序映像和类型 [app-image] 需要 --mac-sign 选项 +error.tool.failed.with.output="{0}" 失败,显示以下输出: +error.invalid-runtime-image-missing-file=运行时映像 "{0}" 缺少 "{1}" 文件 +error.invalid-runtime-image-bin-dir=运行时映像 "{0}" 不应包含 "bin" 文件夹 +error.invalid-runtime-image-bin-dir.advice=生成与 {0} 选项一起使用的运行时映像时,使用 --strip-native-commands jlink 选项 resource.app-info-plist=应用程序 Info.plist +resource.app-runtime-info-plist=嵌入式 Java 运行时 Info.plist resource.runtime-info-plist=Java 运行时 Info.plist resource.entitlements=Mac 权利 resource.dmg-setup-script=DMG 设置脚本 @@ -56,21 +51,15 @@ resource.pkg-background-image=pkg 背景图像 resource.pkg-pdf=项目定义文件 resource.launchd-plist-file=launchd plist 文件 - message.bundle-name-too-long-warning={0}已设置为 ''{1}'', 其长度超过了 16 个字符。为了获得更好的 Mac 体验, 请考虑将其缩短。 message.preparing-info-plist=正在准备 Info.plist: {0}。 message.icon-not-icns= 指定的图标 "{0}" 不是 ICNS 文件, 不会使用。将使用默认图标代替。 message.version-string-too-many-components='app-version' 可以包含 1 到 3 个数字:1、1.2、1.2.3。 message.version-string-first-number-not-zero=app-version 中的第一个数字不能为零或负数。 -message.creating-association-with-null-extension=正在使用空扩展名创建关联。 -message.ignoring.symlink=警告: codesign 正在跳过符号链接 {0}。 -message.already.signed=文件已签名:{0}。 -message.keychain.error=错误:无法获取密钥链列表。 -message.building-bundle=正在为 {0} 构建 Mac App Store 程序包。 -message.invalid-identifier=无效的 Mac 包标识符 [{0}]。 +message.keychain.error=无法获取密钥链列表。 +message.invalid-identifier=mac 包标识符 [{0}] 无效。 message.invalid-identifier.advice=请使用 "--mac-package-identifier" 指定标识符。 message.building-dmg=正在为 {0} 构建 DMG 程序包。 -message.running-script=正在应用程序映像 [{0}] 上运行 shell 脚本。 message.preparing-dmg-setup=正在准备 dmg 设置: {0}。 message.creating-dmg-file=正在创建 DMG 文件: {0}。 message.dmg-cannot-be-overwritten=Dmg 文件已存在 [{0}] 且无法删除。 @@ -84,3 +73,5 @@ message.codesign.failed.reason.app.content="codesign" 失败,并通过 "--app- message.codesign.failed.reason.xcode.tools="codesign" 失败可能是因为缺少带命令行开发人员工具的 Xcode。请安装带命令行开发人员工具的 Xcode,看看是否可以解决问题。 warning.unsigned.app.image=警告:使用未签名的 app-image 生成已签名的 {0}。 warning.per.user.app.image.signed=警告:由于预定义的已签名应用程序映像中缺少 "{0}",不支持对已安装应用程序的每用户配置提供支持。 +warning.non.standard.contents.sub.dir=警告:为 --app-content 选项指定的目录 "{0}" 的文件名不是应用程序包的 "Contents" 目录中的标准子目录名称。结果应用程序包可能会使代码签名和/或公证失败。 +warning.app.content.is.not.dir=警告:--app-content 选项的值 "{0}" 不是目录。结果应用程序包可能会使代码签名和/或公证失败。 diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_de.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_de.properties index c1cb5bf4283..5b9a5728912 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_de.properties +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_de.properties @@ -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 @@ -24,19 +24,163 @@ # # -MSG_Help=Verwendung: jpackage \n\nBeispielverwendungen:\n--------------\n Generiert ein für das Hostsystem geeignetes Anwendungspackage:\n Für eine modulare Anwendung:\n jpackage -n name -p modulePath -m moduleName/className\n Für eine nicht modulare Anwendung:\n jpackage -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n Aus einem vorab erstellten Anwendungsimage:\n jpackage -n name --app-image appImageDir\n Generiert ein Anwendungsimage:\n Für eine modulare Anwendung:\n jpackage --type app-image -n name -p modulePath \\\n -m moduleName/className\n Für eine nicht modulare Anwendung:\n jpackage --type app-image -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n Um eigene Optionen für jlink anzugeben, führen Sie jlink separat aus:\n jlink --output appRuntimeImage -p modulePath \\\n --add-modules moduleName \\\n --no-header-files [...]\n jpackage --type app-image -n name \\\n -m moduleName/className --runtime-image appRuntimeImage\n Generiert ein Java Runtime-Package:\n jpackage -n name --runtime-image \n{6}\nAllgemeine Optionen:\n @ \n Liest Optionen und/oder Modus aus einer Datei \n Diese Option kann mehrmals verwendet werden.\n --type -t \n Der zu erstellende Packagetyp\n Gültige Werte: {1} \n Bei fehlender Angabe dieser Option wird ein plattformabhängiger\n Standardtyp erstellt.\n --app-version \n Version der Anwendung und/oder des Packages\n --copyright \n Copyright für die Anwendung\n --description \n Beschreibung der Anwendung\n --help -h \n Gibt den Verwendungstext mit einer Liste und Beschreibung jeder gültigen\n Option für die aktuelle Plattform an den Ausgabestream aus und beendet den Vorgang\n --icon \n Pfad des Symbols für das Anwendungspackage\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n --name -n \n Name der Anwendung und/oder des Packages\n --dest -d \n Pfad, in den die generierte Ausgabedatei abgelegt wird\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Standardmäßig wird das aktuelle Arbeitsverzeichnis verwendet.\n --temp \n Pfad eines neuen oder leeren Verzeichnisses zum Erstellen temporärer Dateien\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Falls angegeben, wird das temporäre Verzeichnis beim Abschließen der Aufgabe\n nicht entfernt und muss manuell entfernt werden.\n Bei fehlender Angabe wird ein temporäres Verzeichnis erstellt und\n beim Abschließen der Aufgabe entfernt.\n --vendor \n Anbieter der Anwendung\n --verbose\n Aktiviert Ausgabe im Verbose-Modus\n --version\n Gibt die Produktversion an den Outputstream aus und beendet den Vorgang.\n\nOptionen für das Erstellen des Laufzeitimages:\n --add-modules [,...]\n Eine per Komma (",") getrennte Liste hinzuzufügender Module\n Diese Modulliste wird zusammen mit dem Hauptmodul (sofern angegeben)\n als Argument --add-module an jlink übergeben.\n Bei fehlender Angabe wird entweder nur das Hauptmodul (sofern --module\n angegeben ist) oder das Standardset an Modulen (sofern --main-jar \n angegeben ist) verwendet.\n Diese Option kann mehrmals verwendet werden.\n --module-path -p ...\n \ -Eine per {0} getrennte Pfadliste\n Jeder Pfad ist entweder ein Verzeichnis mit Modulen oder der Pfad zu einer\n JAR-Datei eines Moduls.\n (Jeder Pfad ist absolut oder relativ zum aktuellen Verzeichnis.)\n Diese Option kann mehrmals verwendet werden.\n --jlink-options \n Eine per Leerzeichen getrennte Liste mit an jlink zu übergebenden Optionen \n Bei fehlender Angabe wird standardmäßig "--strip-native-commands \n --strip-debug --no-man-pages --no-header-files" verwendet. \n Diese Option kann mehrmals verwendet werden.\n --runtime-image \n Pfad des vordefinierten Laufzeitimages, das in\n das Anwendungsimage kopiert wird\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Wenn --runtime-image nicht angegeben wird, führt jpackage jlink aus, um\n das Laufzeitimage mit folgenden Optionen zu erstellen:\n --strip-debug, --no-header-files, --no-man-pages und\n --strip-native-commands.\n\nOptionen für das Erstellen des Anwendungsimages:\n --input -i \n Pfad des Eingabeverzeichnisses mit den zu verpackenden Dateien\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Alle Dateien im Eingabeverzeichnis werden verpackt für das\n Anwendungsimage integriert.\n --app-content [,...]\n Eine per Komma getrennte Liste mit Pfaden zu Dateien und/oder Verzeichnissen,\n die zur Anwendungs-Payload hinzugefügt werden sollen.\n Diese Option kann mehrmals verwendet werden.\n\nOptionen für das Erstellen des Anwendungs-Launchers:\n --add-launcher =\n Name des Launchers sowie ein Pfad zu einer Eigenschaftendatei mit\n einer Liste von Schlüssel/Wert-Paaren\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Die Schlüssel "module", "main-jar", "main-class", "description",\n "arguments", "java-options", "app-version", "icon",\n "launcher-as-service",\n "win-console", "win-shortcut", "win-menu",\n "linux-app-category" und "linux-shortcut" können verwendet werden.\n Diese Optionen werden den ursprünglichen Befehlszeilenoptionen hinzugefügt\n (oder überschreiben diese), um einen zusätzlichen, alternativen Launcher zu erstellen.\n Der Hauptanwendungs-Launcher wird aus den Befehlszeilenoptionen\n erstellt. Mit dieser Option können zusätzliche alternative Launcher\n erstellt werden. Außerdem kann diese Option mehrmals verwendet werden,\n um mehrere zusätzliche Launcher zu erstellen. \n --arguments \n Befehlszeilenargumente, die an die Hauptklasse übergeben werden, falls\n keine Befehlszeilenargumente an den Launcher übergeben werden\n Diese Option kann mehrmals verwendet werden.\n --java-options \n Optionen, die an Java Runtime übergeben werden\n Diese Option kann mehrmals verwendet werden.\n --main-class \n Qualifizierter Name der auszuführenden Anwendungshauptklasse\n Diese Option kann nur bei Angabe von --main-jar verwendet werden.\n --main-jar \n Die Haupt-JAR-Datei der Anwendung, die die Hauptklasse enthält\n (angegeben als Pfad relativ zum Eingabepfad)\n Es kann entweder die Option --module oder die Option --main-jar angegeben werden, nicht jedoch\n beides.\n --module -m [/]\n Das Hauptmodul (und optional die Hauptklasse) der Anwendung\n Dieses Modul muss unter dem Modulpfad gespeichert sein.\n Bei Angabe dieser Option wird das Hauptmodul\n \ -im Java Runtime-Image verknüpft. Es kann entweder die Option --module oder die Option --main-jar\n angegeben werden, nicht jedoch beides.\n{2}\nOptionen für das Erstellen des Anwendungspackages:\n --about-url \n URL der Homepage der Anwendung\n --app-image \n {5} (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n --file-associations \n Pfad zu einer Eigenschaftendatei mit einer Liste von Schlüssel/Wert-Paaren\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Mit den Schlüsseln "extension", "mime-type", "icon" und "description"\n kann die Verknüpfung beschrieben werden.\n Diese Option kann mehrmals verwendet werden.\n --install-dir \n {4} --license-file \n Pfad zur Lizenzdatei\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n --resource-dir \n Pfad zum Überschreiben von jpackage-Ressourcen\n Symbole, Vorlagendateien und weitere Ressourcen von jpackage können\n durch Hinzufügen von Ersetzungsressourcen zu diesem Verzeichnis überschrieben werden.\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n --runtime-image \n Pfad des zu installierenden vordefinierten Laufzeitimages\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Option muss beim Erstellen eines Laufzeitpackages angegeben werden.\n --launcher-as-service\n Anforderung zum Erstellen eines Installationsprogramms, das den\n Hauptanwendungs-Launcher als Hintergrundserviceanwendung registriert.\n\nPlattformabhängige Optionen für das Erstellen des Anwendungspackages:\n{3} +help.header=Verwendung: jpackage + +help.short=Verwenden Sie jpackage --help (oder -h), um eine Liste möglicher Optionen aufzurufen + +help.option-group.sample.create-native-package=\ Generieren Sie ein Anwendungspackage, das für das Hostsystem geeignet ist:\n Für eine modulare Anwendung:\n jpackage -n name -p modulePath -m moduleName/className\n Für eine nicht modulare Anwendung:\n jpackage -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n Aus einem vordefinierten Anwendungsimage:\n jpackage -n name --app-image appImageDir + +help.option-group.sample.create-app-image=\ Generieren Sie ein Anwendungspackage:\n Für eine modulare Anwendung:\n jpackage --type app-image -n name -p modulePath \\\n -m moduleName/className\n Für eine nicht modulare Anwendung:\n jpackage --type app-image -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n Um eigene Optionen für jlink anzugeben, führen Sie jlink separat aus:\n jlink --output appRuntimeImage -p modulePath \\\n --add-modules moduleName \\\n --no-header-files [...]\n jpackage --type app-image -n name \\\n -m moduleName/className --runtime-image appRuntimeImage + +help.option-group.sample.create-runtime-installer=\ Generieren Sie ein Java-Laufzeitpackage:\n jpackage -n name --runtime-image + +help.option-group.sample.sign-app-image=\ Vordefiniertes Anwendungsimage signieren:\n jpackage --type app-image --app-image \\\n --mac-sign [...]\n Hinweis: In diesem Modus sind nur die folgenden zusätzlichen Optionen zulässig:\n Das Set der zusätzlichen Mac-Signaturoptionen und --verbose + +help.option-group.sample=Beispielverwendungen +help.option-group.generic=Allgemeine Optionen +help.option-group.runtime-image=Optionen für das Erstellen des Laufzeitimages +help.option-group.app-image=Optionen für das Erstellen des Anwendungsimages +help.option-group.launcher=Optionen für das Erstellen der Anwendungslauncher: +help.option-group.launcher-platform=Plattformabhängige Option für das Erstellen des Anwendungslaunchers +help.option-group.package=Optionen für das Erstellen des Anwendungspackages +help.option-group.package-platform=Plattformabhängige Optionen für das Erstellen des Anwendungspackages + +help.option.argument-file=\ Leseoptionen und/oder -modus aus einer Datei\n Diese Option kann mehrmals verwendet werden. + +help.option.about-url=\ URL der Homepage der Anwendung + +help.option.add-launcher.win=\ Name des Launchers sowie ein Pfad zu einer Eigenschaftendatei mit\n einer Liste von Schlüssel/Wert-Paaren\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Die Schlüssel "arguments", "description", "icon", "java-options",\n "launcher-as-service", "main-class", "main-jar", "module",\n "win-console", "win-menu" und "win-shortcut" können verwendet werden. \n Diese Optionen werden den ursprünglichen\n Befehlszeilenoptionen hinzugefügt (oder überschreiben diese), um einen zusätzlichen, alternativen Launcher zu erstellen.\n Der Hauptanwendungslauncher wird aus den Befehlszeilenoptionen\n erstellt. Mit dieser Option können zusätzliche alternative Launcher\n erstellt werden. Außerdem kann diese Option mehrmals verwendet werden,\n um mehrere zusätzliche Launcher zu erstellen. + +help.option.add-launcher.linux=\ Name des Launchers sowie ein Pfad zu einer Eigenschaftendatei mit\n einer Liste von Schlüssel/Wert-Paaren\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Die Schlüssel "arguments", "description", "icon", "java-options",\n "launcher-as-service", "linux-shortcut", "main-class", "main-jar"\n und "module" können verwendet werden. \n Diese Optionen werden den ursprünglichen Befehlszeilenoptionen hinzugefügt\n (oder überschreiben diese), um einen zusätzlichen, alternativen Launcher zu erstellen. \n Der Hauptanwendungslauncher wird aus den Befehlszeilenoptionen\n erstellt. Mit dieser Option können zusätzliche alternative Launcher\n erstellt werden. Außerdem kann diese Option mehrmals verwendet werden,\n um mehrere zusätzliche Launcher zu erstellen. + +help.option.add-launcher.mac=\ Name des Launchers sowie ein Pfad zu einer Eigenschaftendatei mit\n einer Liste von Schlüssel/Wert-Paaren\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Die Schlüssel "arguments", "description", "icon", "java-options",\n "launcher-as-service", "main-class", "main-jar"\n und "module" können verwendet werden. \n Diese Optionen werden den ursprünglichen Befehlszeilenoptionen hinzugefügt\n (oder überschreiben diese), um einen zusätzlichen, alternativen Launcher zu erstellen. \n Der Hauptanwendungslauncher wird aus den Befehlszeilenoptionen\n erstellt. Mit dieser Option können zusätzliche alternative Launcher\n erstellt werden. Außerdem kann diese Option mehrmals verwendet werden,\n um mehrere zusätzliche Launcher zu erstellen. + +help.option.add-modules=\ Eine per Komma (",") getrennte Liste hinzuzufügender Module\n Diese Modulliste wird zusammen mit dem Hauptmodul (sofern angegeben)\n als Argument --add-module an jlink übergeben. \n Bei fehlender Angabe wird entweder nur das Hauptmodul (sofern --module\n angegeben ist) oder das Standardset an Modulen (sofern --main-jar\n angegeben ist) verwendet. \n Diese Option kann mehrmals verwendet werden. + +help.option.app-content=\ Eine per Komma getrennte Liste mit Pfaden zu Dateien und/oder Verzeichnissen,\n die zur Anwendungs-Payload hinzugefügt werden sollen.\n Diese Option kann mehrmals verwendet werden. + +help.option.app-content.mac=\ Eine per Komma getrennte Liste mit Pfaden zu Dateien und/oder Verzeichnissen,\n die zur Anwendungs-Payload hinzugefügt werden sollen. \n Diese Option kann mehrmals verwendet werden. \n Hinweis: Der Wert muss ein Verzeichnis mit dem Unterverzeichnis "Resources" sein\n Unterverzeichnis (oder ein anderes Verzeichnis, das im Verzeichnis "Contents"\n des Anwendungs-Bundles gültig ist). Andernfalls produziert jpackage möglicherweise ein\n ungültiges Anwendungs-Bundle, bei dem die Codesignatur und/oder Notarisierung nicht erfolgreich\n verläuft. + +help.option.app-image=\ Speicherort des vordefinierten Anwendungsimages, mit dem\n ein installierbares Package erstellt wird\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis) + +help.option.app-image.mac=\ Speicherort des vordefinierten Anwendungsimages, mit dem\n ein installierbares Package erstellt oder das vordefinierte\n Anwendungsimage signiert wird\n (absoluter Pfad bzw. relativ zum aktuellen Verzeichnis) + +help.option.app-version=\ Version der Anwendung und/oder des Packages + +help.option.arguments=\ Befehlszeilenargumente, die an die Hauptklasse übergeben werden, falls\n keine Befehlszeilenargumente an den Launcher übergeben werden\n Diese Option kann mehrmals verwendet werden. + +help.option.copyright=\ Copyright für die Anwendung + +help.option.description=\ Beschreibung der Anwendung + +help.option.dest=\ Pfad, in dem die generierte Ausgabedatei abgelegt wird\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Standardmäßig wird das aktuelle Arbeitsverzeichnis verwendet. + +help.option.file-associations=\ Pfad zu einer Eigenschaftendatei mit einer Liste von Schlüssel/Wert-Paaren\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Mit den Schlüsseln "extension", "mime-type", "icon" und "description"\n kann die Verknüpfung beschrieben werden.\n Diese Option kann mehrmals verwendet werden. + +help.option.help=\ Gibt den Verwendungstext mit einer Liste und Beschreibung jeder gültigen\n Option für die aktuelle Plattform an den Outputstream aus und beendet den Vorgang + +help.option.icon=\ Pfad des Symbols für das Anwendungspackage\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis) + +help.option.input=\ Pfad des Eingabeverzeichnisses mit den zu verpackenden Dateien\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Alle Dateien im Eingabeverzeichnis werden als Package in das\n Anwendungsimage integriert. + +help.option.install-dir=\ Absoluter Pfad des Installationsverzeichnisses der Anwendung + +help.option.install-dir.win=\ Relativer Unterpfad des Installationsverzeichnisses der\n Anwendung, wie "Programme" oder "AppData". + +help.option.installer-runtime-image=\ Pfad des zu installierenden vordefinierten Laufzeitimages\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Option muss beim Erstellen eines Laufzeitpackages angegeben werden. + +help.option.java-options=\ Optionen, die an Java Runtime übergeben werden\n Diese Option kann mehrmals verwendet werden. + +help.option.jlink-options=\ Eine per Leerzeichen getrennte Liste mit an jlink zu übergebenden Optionen\n Bei fehlender Angabe wird standardmäßig "--strip-native-commands\n --strip-debug --no-man-pages --no-header-files" verwendet. \n Diese Option kann mehrmals verwendet werden. + +help.option.launcher-as-service=\ Anforderung zum Erstellen eines Installationsprogramms, das den\n Hauptanwendungslauncher als Hintergrundserviceanwendung registriert. + +help.option.license-file=\ Pfad zur Lizenzdatei\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis) + +help.option.linux-app-category=\ Gruppenwert der RPM-Datei .spec oder\n Abschnittswert der DEB-Kontrolldatei + +help.option.linux-app-release=\ Releasewert der RPM-Datei .spec oder\n Debian-Revisionswert der DEB-Kontrolldatei + +help.option.linux-deb-maintainer=\ Maintainer für DEB-Package + +help.option.linux-menu-group=\ Menügruppe, in der diese Anwendung abgelegt wird + +help.option.linux-package-deps=\ Erforderliche Packages oder Funktionen für die Anwendung + +help.option.linux-package-name=\ Name für das Linux-Package, Standardwert: Anwendungsname + +help.option.linux-rpm-license-type=\ Lizenztyp ("Lizenz: " der RPM-SPEC-Datei) + +help.option.linux-shortcut=\ Erstellt eine Verknüpfung für die Anwendung. + +help.option.mac-app-category=\ Zeichenfolge für das Erstellen von LSApplicationCategoryType in\n Anwendungs-plist. Standardwert: "utilities". + +help.option.mac-app-image-sign-identity=\ Zum Signieren des Anwendungsimages verwendete Identität. Dieser Wert wird direkt\n an die Option --sign des Tools "codesign" übergeben. Diese Option kann nicht\n mit --mac-signing-key-user-name kombiniert werden. + +help.option.mac-app-store=\ Gibt an, dass die jpackage-Ausgabe für den\n Mac App Store vorgesehen ist. + +help.option.mac-dmg-content=\ Nimmt den gesamten referenzierten Inhalt in die DMG-Datei auf.\n Diese Option kann mehrmals verwendet werden. + +help.option.mac-entitlements=\ Pfad zu einer Datei mit Berechtigungen, die beim Signieren von ausführbaren\n Dateien und Librarys im Bundle verwendet werden sollen. + +help.option.mac-installer-sign-identity=\ Zum Signieren des Installationsprogramms "pkg" verwendete Identität. Dieser Wert wird direkt\n an die Option --sign des Tools "productbuild"-übergeben. Diese Option\n kann nicht mit --mac-signing-key-user-name kombiniert werden. + +help.option.mac-package-identifier=\ Eine ID, die die Anwendung für macOS eindeutig identifiziert\n Standardwert ist der Hauptklassenname. \n Es dürfen nur alphanumerische Zeichen (A-Z, a-z, 0-9), Bindestriche (-)\n und Punkte (.) verwendet werden. + +help.option.mac-package-name=\ Name der Anwendung, wie in der Menüleiste angezeigt\n Dieser kann vom Anwendungsnamen abweichen.\n Er darf maximal 15 Zeichen enthalten und muss für die Anzeige\n in der Menüleiste und im Infofenster der Anwendung geeignet sein.\n Standardwert: Anwendungsname. + +help.option.mac-package-signing-prefix=\ Beim Signieren des Anwendungspackages wird dieser Wert\n allen zu signierenden Komponenten ohne vorhandene\n Package-ID als Präfix vorangestellt. + +help.option.mac-sign=\ Anforderung zum Signieren des Packages oder des vordefinierten\n Anwendungsimages. + +help.option.mac-signing-keychain=\ Name des Schlüsselbundes für die Suche nach der Signaturidentität\n Bei fehlender Angabe werden die Standardschlüsselbunde verwendet. + +help.option.mac-signing-key-user-name=\ Team- oder Benutzernamensteil der Apple-Signaturidentitäten. Um direkt zu steuern,\n welche Signaturidentität zum Signieren eines Anwendungsimages oder\n Installationsprogramms verwendet wird, verwenden Sie --mac-app-image-sign-identity und/oder\n --mac-installer-sign-identity. Diese Option kann nicht mit\n --mac-app-image-sign-identity oder --mac-installer-sign-identity kombiniert werden. + +help.option.main-class=\ Qualifizierter Name der auszuführenden Anwendungshauptklasse\n Diese Option kann nur bei Angabe von --main-jar verwendet werden. + +help.option.main-jar=\ Die Haupt-JAR-Datei der Anwendung, die die Hauptklasse enthält\n (angegeben als Pfad relativ zum Eingabepfad)\n Es kann entweder die Option --module oder die Option --main-jar angegeben werden, nicht jedoch\n beides. + +help.option.module=\ Das Hauptmodul (und optional die Hauptklasse) der Anwendung\n Dieses Modul muss unter dem Modulpfad gespeichert sein. \n Bei Angabe dieser Option wird das Hauptmodul\n im Java Runtime-Image verknüpft. Es kann entweder die Option --module oder die Option --main-jar\n angegeben werden, nicht jedoch beides. + +help.option.module-path=\ Eine per Doppelpunkt (:) getrennte Pfadliste\n Jeder Pfad ist entweder ein Verzeichnis mit Modulen oder der Pfad zu einer\n modularen JAR-Datei.\n (Jeder Pfad ist absolut oder relativ zum aktuellen Verzeichnis.)\n Diese Option kann mehrmals verwendet werden. +help.option.module-path.win=\ Eine per Semikolon (;) getrennte Pfadliste\n Jeder Pfad ist entweder ein Verzeichnis mit Modulen oder der Pfad zu einer\n modularen JAR-Datei.\n (Jeder Pfad ist absolut oder relativ zum aktuellen Verzeichnis.)\n Diese Option kann mehrmals verwendet werden. + +help.option.name=\ Name der Anwendung und/oder des Packages + +help.option.resource-dir=\ Pfad zum Überschreiben von jpackage-Ressourcen\n Symbole, Vorlagendateien und weitere Ressourcen von jpackage können\n durch Hinzufügen von Ersetzungsressourcen zu diesem Verzeichnis überschrieben werden.\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis) + +help.option.runtime-image=\ Pfad des vordefinierten Laufzeitimages, das in\n das Anwendungsimage kopiert wird\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Wenn --runtime-image nicht angegeben wird, führt jpackage jlink aus, um\n das Laufzeitimage mit folgenden Optionen zu erstellen:\n --strip-debug, --no-header-files, --no-man-pages und\n --strip-native-commands. + +help.option.temp=\ Pfad eines neuen oder leeren Verzeichnisses zum Erstellen temporärer Dateien\n (absoluter Pfad oder relativ zum aktuellen Verzeichnis)\n Falls angegeben, wird das temporäre Verzeichnis beim Abschließen der Aufgabe\n nicht entfernt und muss manuell entfernt werden. \n Bei fehlender Angabe wird ein temporäres Verzeichnis erstellt und\n beim Abschließen der Aufgabe entfernt. + +help.option.type.win=\ Der zu erstellende Packagetyp\n Gültige Werte sind: {"app-image", "exe", "msi"}\n Bei fehlender Angabe dieser Option wird ein plattformabhängiger\n Standardtyp erstellt. +help.option.type.linux=\ Der zu erstellende Packagetyp\n Gültige Werte sind: {"app-image", "deb", "rpm"}\n Bei fehlender Angabe dieser Option wird ein plattformabhängiger\n Standardtyp erstellt. +help.option.type.mac=\ Der zu erstellende Packagetyp\n Gültige Werte sind: {"app-image", "dmg", "pkg"}\n Bei fehlender Angabe dieser Option wird ein plattformabhängiger\n Standardtyp erstellt. + +help.option.vendor=\ Anbieter der Anwendung + +help.option.verbose=\ Aktiviert Ausgabe im Verbose-Modus + +help.option.version=\ Gibt die Produktversion an den Outputstream aus und beendet den Vorgang. + +help.option.win-console=\ Erstellt einen Konsolenlauncher für die Anwendung. Sollte für\n Anwendungen angegeben werden, die Konsoleninteraktionen erfordern + +help.option.win-dir-chooser=\ Fügt ein Dialogfeld hinzu, in dem der Benutzer das Verzeichnis auswählen kann, in dem\n das Produkt installiert wird. + +help.option.win-help-url=\ URL, unter der der Benutzer weitere Informationen oder technische Unterstützung erhält + +help.option.win-menu=\ Anforderung zum Hinzufügen einer Startmenüverknüpfung für diese Anwendung + +help.option.win-menu-group=\ Startmenügruppe, in der diese Anwendung abgelegt wird + +help.option.win-per-user-install=\ Anforderung zum Ausführen einer Installation pro Benutzer + +help.option.win-shortcut=\ Anforderung zum Hinzufügen einer Desktopverknüpfung für diese Anwendung + +help.option.win-shortcut-prompt=\ Fügt ein Dialogfeld hinzu, in dem der Benutzer auswählen kann, ob Verknüpfungen\n vom Installationsprogramm erstellt werden. + +help.option.win-update-url=\ URL der verfügbaren Anwendungsaktualisierungsinformationen + +help.option.win-upgrade-uuid=\ UUID für Upgrades für dieses Package -MSG_Help_win_launcher=\nPlattformabhängige Option für das Erstellen des Anwendungs-Launchers:\n --win-console\n Erstellt einen Konsolen-Launcher für die Anwendung. Sollte für\n Anwendungen angegeben werden, die Konsoleninteraktionen erfordern\n -MSG_Help_win_install=\ --win-dir-chooser\n Fügt ein Dialogfeld hinzu, in dem der Benutzer das Verzeichnis auswählen kann, in dem\n das Produkt installiert wird.\n --win-help-url \n URL, unter der der Benutzer weitere Informationen oder technische Unterstützung erhält\n --win-menu\n Anforderung zum Hinzufügen einer Startmenüverknüpfung für diese Anwendung\n --win-menu-group \n Startmenügruppe, in der diese Anwendung abgelegt wird\n --win-per-user-install\n Anforderung zum Ausführen einer Installation pro Benutzer\n --win-shortcut\n Anforderung zum Hinzufügen einer Desktopverknüpfung für diese Anwendung\n --win-shortcut-prompt\n Fügt ein Dialogfeld hinzu, in dem der Benutzer auswählen kann, ob Verknüpfungen\n vom Installationsprogramm erstellt werden sollen.\n --win-update-url \n URL verfügbarer Anwendungsupdateinformationen\n --win-upgrade-uuid \n UUID, die mit Upgrades für dieses Package verknüpft ist\n -MSG_Help_win_install_dir=Relativer Unterpfad unter dem Standardinstallationsverzeichnis\n -MSG_Help_mac_install=\ --mac-dmg-content [,...]\n Nimmt den gesamten referenzierten Inhalt in die DMG-Datei auf.\n Diese Option kann mehrmals verwendet werden. \n -MSG_Help_mac_launcher=\ --mac-package-identifier \n Eine ID, die die Anwendung für macOS eindeutig identifiziert\n Standardwert ist der Hauptklassenname.\n Es dürfen nur alphanumerische Zeichen (A-Z, a-z, 0-9), Bindestriche (-)\n und Punkte (.) verwendet werden.\n --mac-package-name \n Name der Anwendung, wie in der Menüleiste angezeigt\n Dieser kann vom Anwendungsnamen abweichen.\n Er darf maximal 15 Zeichen enthalten und muss für die Anzeige\n in der Menüleiste und im Infofenster der Anwendung geeignet sein.\n Standardwert: Anwendungsname.\n --mac-package-signing-prefix \n Beim Signieren des Anwendungspackages wird dieser Wert\n allen zu signierenden Komponenten ohne vorhandene\n Package-ID als Präfix vorangestellt.\n --mac-sign\n Anforderung zum Signieren des Packages oder des vordefinierten\nAnwendungsimages\n --mac-signing-keychain \n Name des Schlüsselbundes für die Suche nach der Signaturidentität\n Bei fehlender Angabe werden die Standardschlüsselbunde verwendet.\n --mac-signing-key-user-name \n Team- oder Benutzernamensteil der Apple-Signaturidentitäten. Um direkt zu steuern,\n welche Signaturidentität zum Signieren eines Anwendungsimages oder\n Installationsprogramms verwendet wird, verwenden Sie --mac-app-image-sign-identity und/oder\n --mac-installer-sign-identity. Diese Option kann nicht mit\n --mac-app-image-sign-identity oder --mac-installer-sign-identity kombiniert werden.\n --mac-app-image-sign-identity \n Zum Signieren des Anwendungsimages verwendete Identität. Dieser Wert wird\n direkt an die Option --sign des Tools "codesign" übergeben. Diese Option kann nicht\n mit --mac-signing-key-user-name kombiniert werden.\n --mac-installer-sign-identity \n Zum Signieren des Installationsprogramms "pkg" verwendete Identität. Dieser Wert wird\n direkt an die Option --sign des Tools "productbuild" übergeben. Diese Option\n kann nicht mit --mac-signing-key-user-name kombiniert werden.\n --mac-app-store\n Gibt an, dass die jpackage-Ausgabe für den\n Mac App Store bestimmt ist.\n --mac-entitlements \n Pfad zu einer Datei mit Berechtigungen, die beim Signieren\n von ausführbaren Dateien und Librarys im Bundle verwendet werden sollen.\n --mac-app-category \n Zeichenfolge für das Erstellen von LSApplicationCategoryType in\n Anwendungs-plist. Standardwert: "utilities".\n -MSG_Help_linux_install=\ --linux-package-name \n Name für das Linux-Package, Standardwert: Anwendungsname\n --linux-deb-maintainer \n Maintainer für .deb-Package\n --linux-menu-group \n Menügruppe, in der diese Anwendung abgelegt wird\n --linux-package-deps \n Erforderliche Packages oder Funktionen für die Anwendung\n --linux-rpm-license-type \n Typ der Lizenz ("License: " der RPM-SPEC-Datei)\n --linux-app-release \n Releasewert der RPM-Datei .spec oder \n Debian-Revisionswert der DEB-Kontrolldatei\n --linux-app-category \n Gruppenwert der RPM-Datei .spec oder \n Abschnittswert der DEB-Kontrolldatei\n --linux-shortcut\n Erstellt einen Shortcut für die Anwendung.\n -MSG_Help_mac_linux_install_dir=Absoluter Pfad des Installationsverzeichnisses der Anwendung\n -MSG_Help_default_install_dir=Absoluter Pfad des Installationsverzeichnisses der Anwendung auf OS X\n oder Linux. Relativer Unterpfad des Installationsverzeichnisses der\n Anwendung wie "Programme" oder "AppData" unter Windows.\n -MSG_Help_no_args=Verwendung: jpackage \nVerwenden Sie jpackage --help (oder -h), um eine Liste möglicher Optionen aufzurufen -MSG_Help_default_app_image=Speicherort des vordefinierten Anwendungsimages, mit dem\n ein installierbares Package erstellt wird\n -MSG_Help_mac_app_image=Speicherort des vordefinierten Anwendungsimages, mit dem\n ein installierbares Package erstellt oder das vordefinierte\n Anwendungsimage signiert wird\n -MSG_Help_mac_sign_sample_usage=\ Vordefiniertes Anwendungsimage signieren:\n jpackage --type app-image --app-image \\\n --mac-sign [...]\n Hinweis: In diesem Modus sind nur die folgenden zusätzlichen Optionen zulässig:\n Das Set der zusätzlichen Mac-Signaturoptionen und --verbose\n diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties index cae6ae216d3..ca606dda9f8 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_ja.properties @@ -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 @@ -24,22 +24,163 @@ # # -MSG_Help=使用方法: jpackage \n\n使用例:\n--------------\n ホスト・システムに適したアプリケーション・パッケージを生成します。\n モジュラ・アプリケーションの場合:\n jpackage -n name -p modulePath -m moduleName/className\n 非モジュラ・アプリケーションの場合:\n jpackage -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n 事前作成されたアプリケーション・イメージから:\n jpackage -n name --app-image appImageDir\n アプリケーション・イメージの生成:\n モジュラ・アプリケーションの場合:\n jpackage --type app-image -n name -p modulePath \\\n -m moduleName/className\n 非モジュラ・アプリケーションの場合:\n jpackage --type app-image -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n jlinkに独自のオプションを指定するには、jlinkを別個に実行します。\n jlink --output appRuntimeImage -p modulePath \\\n --add-modules moduleName \\\n --no-header-files [...]\n jpackage --type app-image -n name \\\n -m moduleName/className --runtime-image appRuntimeImage\n Javaランタイム・パッケージを生成します。\n jpackage -n name --runtime-image \n{6}\n一般的なオプション:\n @ \n ファイルからの読取りオプションおよびモード \n このオプションは複数回使用できます。\n --type -t \n 作成するパッケージのタイプ\n 有効な値: {1} \n このオプションが指定されていない場合、プラットフォーム依存の\n デフォルト・タイプが作成されます\n --app-version \n アプリケーションおよびパッケージのバージョン\n --copyright \n アプリケーションのコピーライト\n --description \n アプリケーションの説明\n --help -h \n 使用方法テキストと現在のプラットフォームの有効なオプションのリストと説明を\n 出力ストリームに出力して、終了します\n --icon \n アプリケーション・パッケージのアイコンのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n \ ---name -n \n アプリケーションおよびパッケージの名前\n --dest -d \n 生成された出力ファイルが配置されるパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n デフォルトは現在の作業ディレクトリです。\n --temp \n 一時ファイルの作成に使用される新規または空のディレクトリのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n 指定した場合、タスク完了時に一時ディレクトリは削除されないため\n 手動で削除する必要があります\n 指定しなかった場合、一時ディレクトリが作成され\n タスク完了時に削除されます。\n --vendor \n アプリケーションのベンダー\n --verbose\n 詳細な出力を有効にします\n --version\n 製品バージョンを出力ストリームに出力して終了します\n\nランタイム・イメージを作成するためのオプション:\n --add-modules [,...]\n 追加するモジュールのカンマ(",")区切りリスト\n このモジュール・リストとメイン・モジュール(指定した場合)\n が--add-module引数としてjlinkに渡されます。\n 指定しなかった場合、メイン・モジュールのみ(--moduleが\n 指定された場合)、またはデフォルトのモジュール・セット(--main-jarが \n 指定された場合)が使用されます。\n このオプションは複数回使用できます。\n --module-path -p ...\n パスの{0}区切りリスト\n 各パスは、モジュールのディレクトリまたは\n モジュラjarへのパスです。\n (各パスは、絶対パスまたは現在のディレクトリからの相対パスです。)\n このオプションは複数回使用できます。\n --jlink-options \n jlinkに渡すオプションのスペース区切りのリスト \n 指定しない場合、"--strip-native-commands \n --strip-debug \ ---no-man-pages --no-header-files"。 \n このオプションは複数回使用できます。\n --runtime-image \n アプリケーション・イメージにコピーされる、事前定義済みのランタイム・イメージ\n のパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n --runtime-imageが指定されていない場合、jpackageはjlinkを実行し、\n 次のオプションを使用してランタイム・イメージを作成します:\n --strip-debug、--no-header-files、--no-man-pagesおよび\n --strip-native-commands。\n\nアプリケーション・イメージを作成するためのオプション:\n --input -i \n パッケージ化するファイルを含む入力ディレクトリへのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n 入力ディレクトリのすべてのファイルは、アプリケーション・イメージに\n パッケージ化されます。\n --app-content [,...]\n ファイルまたはディレクトリ(あるいは両方)のパスのカンマ区切りのリスト\n アプリケーション・ペイロードに追加します。\n このオプションは複数回使用できます。\n\nアプリケーション・ランチャを作成するためのオプション:\n --add-launcher =\n ランチャの名前、およびキー、値のペアのリスト\n を含むプロパティ・ファイルへのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n キー"module"、"main-jar"、"main-class"、"description"、\n "arguments"、"java-options"、"app-version"、"icon"、\n "launcher-as-service"、\n "win-console"、"win-shortcut"、"win-menu"、\n "linux-app-category"および"linux-shortcut"を使用できます。\n これらのオプションを元のコマンドライン・オプションに追加するか、これらのオプションを\n 使用して元のコマンドライン・オプションを上書きして、追加の代替ランチャを作成します。\n \ -メイン・アプリケーション・ランチャはコマンドライン・オプションから作成されます。\n このオプションを使用して追加の代替ランチャを作成でき、\n このオプションを複数回使用して\n 複数の追加のランチャを作成できます。 \n --arguments

\n ランチャにコマンド・ライン引数が指定されていない場合にメイン・クラスに渡す\n コマンド・ライン引数\n このオプションは複数回使用できます。\n --java-options \n Javaランタイムに渡すオプション\n このオプションは複数回使用できます。\n --main-class \n 実行するアプリケーション・メイン・クラスの修飾名\n このオプションを使用できるのは、--main-jarが指定されている場合だけです。\n --main-jar
\n メイン・クラスを含む、アプリケーションのメインJAR\n (入力パスからの相対パスとして指定)\n --moduleまたは--main-jarオプションを指定できますが、両方は\n 指定できません。\n --module -m [/
]\n アプリケーションのメイン・モジュール(およびオプションでメイン・クラス)\n このモジュールは、モジュール・パスに置かれている必要があります。\n このオプションが指定されている場合、メイン・モジュールは\n Javaランタイム・イメージ内でリンクされます。--moduleまたは--main-jar\n オプションを指定できますが、両方は指定できません。\n{2}\nアプリケーション・パッケージを作成するためのオプション:\n --about-url \n アプリケーションのホームページのURL\n --app-image \n {5} (絶対パスまたは現在のディレクトリからの相対パス)\n --file-associations \n キー、値のペアのリストを含むプロパティ・ファイルへのパス\n \ -(絶対パスまたは現在のディレクトリからの相対パス)\n キー"extension"、"mime-type"、"icon"、"description"\n を使用して関連付けを記述できます。\n このオプションは複数回使用できます。\n --install-dir \n {4} --license-file \n ライセンス・ファイルへのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n --resource-dir \n オーバーライドjpackageリソースへのパス\n アイコン、テンプレート・ファイルおよびjpackageのその他のリソースは、\n このディレクトリに置換リソースを追加することでオーバーライドできます。\n (絶対パスまたは現在のディレクトリからの相対パス)\n --runtime-image \n インストールする事前定義済みのランタイム・イメージのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n ランタイム・パッケージの作成時には、オプションが必要です。\n --launcher-as-service\n 次として登録するインストーラの作成をリクエストします: \n バックグラウンド・サービス・タイプ・アプリケーションとしてのメイン・アプリケーション・ランチャ。\n\nアプリケーション・パッケージを作成するためのプラットフォーム依存オプション:\n{3} +help.header=使用方法: jpackage + +help.short=利用可能なオプションのリストについては、jpackage --help (or -h)を使用します + +help.option-group.sample.create-native-package=\ ホスト・システムに適したアプリケーション・パッケージを生成します:\n モジュラ・アプリケーションの場合:\n jpackage -n name -p modulePath -m moduleName/className\n 非モジュラ・アプリケーションの場合:\n jpackage -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n 事前作成されたアプリケーション・イメージから:\n jpackage -n name --app-image appImageDir + +help.option-group.sample.create-app-image=\ アプリケーション・イメージの生成:\n モジュラ・アプリケーションの場合:\n jpackage --type app-image -n name -p modulePath \\\n -m moduleName/className\n 非モジュラ・アプリケーションの場合:\n jpackage --type app-image -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n jlinkに独自のオプションを指定するには、jlinkを別個に実行します:\n jlink --output appRuntimeImage -p modulePath \\\n --add-modules moduleName \\\n --no-header-files [...]\n jpackage --type app-image -n name \\\n -m moduleName/className --runtime-image appRuntimeImage + +help.option-group.sample.create-runtime-installer=\ Javaランタイム・パッケージを生成します:\n jpackage -n name --runtime-image + +help.option-group.sample.sign-app-image=\ 事前定義済みアプリケーション・イメージへの署名:\n jpackage --type app-image --app-image \\\n --mac-sign [...]\n ノート: このモードで許可される唯一の追加オプション:\n 追加のmac署名オプションのセットおよび--verbose + +help.option-group.sample=使用例 +help.option-group.generic=一般的なオプション +help.option-group.runtime-image=ランタイム・イメージを作成するためのオプション +help.option-group.app-image=アプリケーション・イメージを作成するためのオプション +help.option-group.launcher=アプリケーション・ランチャを作成するためのオプション +help.option-group.launcher-platform=アプリケーション・ランチャを作成するためのプラットフォーム依存オプション +help.option-group.package=アプリケーション・パッケージを作成するためのオプション +help.option-group.package-platform=アプリケーション・パッケージを作成するためのプラットフォーム依存オプション + +help.option.argument-file=\ ファイルからの読取りオプションまたはモード(あるいはその両方)\n このオプションは複数回使用できます。 + +help.option.about-url=\ アプリケーションのホームページのURL + +help.option.add-launcher.win=\ ランチャの名前、およびキー、値のペアのリスト\n を含むプロパティ・ファイルへのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n キー"arguments"、"description"、"icon"、"java-options"、\n "launcher-as-service"、"main-class"、"main-jar"、"module"、\n "win-console"、"win-menu"、"win-shortcut"が使用できます。\n これらのオプションを元のコマンドライン・オプションに追加するか、これらのオプションを\n 使用して元のコマンドライン・オプションを上書きして、追加の代替ランチャを作成します。\n メイン・アプリケーション・ランチャはコマンドライン・オプションから作成されます。\n このオプションを使用して追加の代替ランチャを作成でき、\n このオプションを複数回使用して\n 複数の追加のランチャを作成できます。 + +help.option.add-launcher.linux=\ ランチャの名前、およびキー、値のペアのリスト\n を含むプロパティ・ファイルへのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n キー"arguments"、"description"、"icon"、"java-options"、\n "launcher-as-service"、"linux-shortcut"、"main-class"、"main-jar"、\n "module"が使用できます。\n これらのオプションを元のコマンドライン・オプションに追加するか、これらのオプションを\n 使用して元のコマンドライン・オプションを上書きして、追加の代替ランチャを作成します。\n メイン・アプリケーション・ランチャはコマンドライン・オプションから作成されます。\n このオプションを使用して追加の代替ランチャを作成でき、\n このオプションを複数回使用して\n 複数の追加のランチャを作成できます。 + +help.option.add-launcher.mac=\ ランチャの名前、およびキー、値のペアのリスト\n を含むプロパティ・ファイルへのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n キー"arguments"、"description"、"icon"、"java-options"、\n "launcher-as-service"、"main-class"、"main-jar"、"module"\n が使用できます。\n これらのオプションを元のコマンドライン・オプションに追加するか、これらのオプションを\n 使用して元のコマンドライン・オプションを上書きして、追加の代替ランチャを作成します。\n メイン・アプリケーション・ランチャはコマンドライン・オプションから作成されます。\n このオプションを使用して追加の代替ランチャを作成でき、\n このオプションを複数回使用して\n 複数の追加のランチャを作成できます。 + +help.option.add-modules=\ 追加するモジュールのカンマ(",")区切りリスト\n このモジュール・リストとメイン・モジュール(指定した場合)\n が--add-module引数としてjlinkに渡されます。\n 指定しなかった場合、メイン・モジュールのみ(--moduleが\n 指定された場合)、またはデフォルトのモジュール・セット(--main-jarが\n 指定された場合)が使用されます。\n このオプションは複数回使用できます。 + +help.option.app-content=\ アプリケーション・ペイロードに追加するファイルまたはディレクトリ(あるいはその両方)\n のパスのカンマ区切りのリスト。\n このオプションは複数回使用できます。 + +help.option.app-content.mac=\ アプリケーション・ペイロードに追加するファイルまたはディレクトリ(あるいはその両方)\n のパスのカンマ区切りのリスト。\n このオプションは複数回使用できます。\n ノート: 値は"Resources"サブディレクトリ\n (またはアプリケーション・バンドルの"Contents"ディレクトリで有効なその他のディレクトリ)\n を含むディレクトリである必要があります。それ以外の場合は、jpackageによって無効なアプリケーション・バンドルが生成される場合があり、\n コード署名または公証(あるいはその両方)に失敗する\n 場合があります。 + +help.option.app-image=\ インストール可能なパッケージの作成に使用する、事前定義済\n アプリケーション・イメージの場所\n (絶対パスまたは現在のディレクトリからの相対パス) + +help.option.app-image.mac=\ インストール可能なパッケージの作成または事前定義済\n アプリケーション・イメージの署名に使用する、事前定義済\n アプリケーション・イメージの場所\n (絶対パスまたは現在のディレクトリからの相対パス) + +help.option.app-version=\ アプリケーションおよびパッケージのバージョン + +help.option.arguments=\ コマンドライン引数がランチャに指定されていない場合に、\n メイン・クラスに渡されるコマンドライン引数\n このオプションは複数回使用できます。 + +help.option.copyright=\ アプリケーションのコピーライト + +help.option.description=\ アプリケーションの説明 + +help.option.dest=\ 生成された出力ファイルが配置されるパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n 現在の作業ディレクトリにデフォルト設定されています。 + +help.option.file-associations=\ キー、値のペアのリストを含むプロパティ・ファイルへのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n キー"extension"、"mime-type"、"icon"、"description"\n を使用して関連付けを記述できます。\n このオプションは複数回使用できます。 + +help.option.help=\ 使用方法テキストと現在のプラットフォームの有効なオプションのリストと説明を\n 出力ストリームに出力して、終了します + +help.option.icon=\ アプリケーション・パッケージのアイコンのパス\n (絶対パスまたは現在のディレクトリからの相対パス) + +help.option.input=\ パッケージ化するファイルを含む入力ディレクトリのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n 入力ディレクトリのすべてのファイルは、アプリケーション・イメージに\n パッケージ化されます。 + +help.option.install-dir=\ アプリケーションのインストール・ディレクトリの絶対パス + +help.option.install-dir.win=\ "プログラム・ファイル"または"AppData"など、\n アプリケーションのインストール場所の相対サブパス。 + +help.option.installer-runtime-image=\ インストールする事前定義済のランタイム・イメージのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n ランタイム・パッケージの作成時には、オプションが必要です。 + +help.option.java-options=\ Javaランタイムに渡すオプション\n このオプションは複数回使用できます。 + +help.option.jlink-options=\ jlinkに渡すオプションのスペース区切りのリスト\n 指定しない場合、"--strip-native-commands\n --strip-debug --no-man-pages --no-header-files"にデフォルト設定されます。\n このオプションは複数回使用できます。 + +help.option.launcher-as-service=\ バックグラウンド・サービス・タイプ・アプリケーションとしてメイン・\n アプリケーション・ランチャを登録するインストーラの作成をリクエストします。 + +help.option.license-file=\ ライセンス・ファイルへのパス\n (絶対パスまたは現在のディレクトリからの相対パス) + +help.option.linux-app-category=\ RPM .specファイルのグループ値または\n DEB制御ファイルのセクション値 + +help.option.linux-app-release=\ RPM .specファイルのリリース値または\n DEB制御ファイルのDebianリビジョン値 + +help.option.linux-deb-maintainer=\ .debパッケージのメンテナ + +help.option.linux-menu-group=\ このアプリケーションを配置するメニュー・グループ + +help.option.linux-package-deps=\ アプリケーションに必要なパッケージまたは機能 + +help.option.linux-package-name=\ Linuxパッケージの名前。アプリケーション名にデフォルト設定されています + +help.option.linux-rpm-license-type=\ ライセンスのタイプ(RPM .specの"License: ") + +help.option.linux-shortcut=\ アプリケーションのショートカットを作成します。 + +help.option.mac-app-category=\ アプリケーションplistのLSApplicationCategoryTypeの構築に\n 使用する文字列。デフォルト値は"utilities"です。 + +help.option.mac-app-image-sign-identity=\ アプリケーション・イメージの署名に使用するアイデンティティ。この値は直接\n "codesign"ツールの--signオプションに渡されます。このオプションは\n --mac-signing-key-user-nameと組み合せることはできません。 + +help.option.mac-app-store=\ jpackage出力がMac App Store用であること\n を示します。 + +help.option.mac-dmg-content=\ dmgに参照されたコンテンツをすべて含めます。\n このオプションは複数回使用できます。 + +help.option.mac-entitlements=\ バンドルの実行可能ファイルおよびライブラリの署名時に\n 使用する権限を含むファイルのパス。 + +help.option.mac-installer-sign-identity=\ "pkg"インストーラの署名に使用するアイデンティティ。この値は直接\n "productbuild"ツールの--signオプションに渡されます。このオプションは\n --mac-signing-key-user-nameと組み合せることはできません。 + +help.option.mac-package-identifier=\ MacOSのアプリケーションを一意に識別する識別子。\n メイン・クラス名にデフォルト設定されています。\n 英数字(A-Z、a-z、0-9)、ハイフン(-)、\n およびピリオド(.)のみを使用できます。 + +help.option.mac-package-name=\ メニュー・バーに表示されるアプリケーションの名前\n アプリケーション名とは異なります。\n この名前は16文字未満にする必要があり、メニュー・バー\n およびアプリケーション情報ウィンドウに表示するのに適している必要があります。\n アプリケーション名にデフォルト設定されています。 + +help.option.mac-package-signing-prefix=\ アプリケーション・パッケージに署名する際、既存のパッケージIDのない\n 署名が必要なすべてのコンポーネントに、\n この値が接頭辞として付けられます。 + +help.option.mac-sign=\ パッケージまたは事前定義済アプリケーション・イメージに署名するよう\n リクエストします。 + +help.option.mac-signing-keychain=\ 署名アイデンティティを検索するキーチェーンの名前\n 指定しなかった場合、標準のキーチェーンが使用されます。 + +help.option.mac-signing-key-user-name=\ Apple署名アイデンティティのチームまたはユーザー名部分。\n アプリケーション・イメージまたはインストーラの署名に使用する署名アイデンティティの\n 直接制御には、--mac-app-image-sign-identityまたは\n --mac-installer-sign-identity(あるいはその両方)を使用します。このオプションは\n --mac-app-image-sign-identityまたは--mac-installer-sign-identityと組み合せることはできません。 + +help.option.main-class=\ 実行するアプリケーション・メイン・クラスの修飾名\n このオプションを使用できるのは、--main-jarが指定されている場合だけです。 + +help.option.main-jar=\ メイン・クラスを含む、アプリケーションのメインJAR\n (入力パスからの相対パスとして指定)\n --moduleまたは--main-jarオプションを指定できますが、両方は\n 指定できません。 + +help.option.module=\ アプリケーションのメイン・モジュール(およびオプションでメイン・クラス)\n このモジュールは、モジュール・パスに置かれている必要があります。\n このオプションが指定されている場合、メイン・モジュールは\n Javaランタイム・イメージ内でリンクされます。--moduleまたは--main-jar\n オプションを指定できますが、両方は指定できません。 + +help.option.module-path=\ :で区切られたパスのリスト\n 各パスは、モジュールのディレクトリまたは\n モジュラjarへのパスです。\n (各パスは、絶対パスまたは現在のディレクトリからの相対パスです。)\n このオプションは複数回使用できます。 +help.option.module-path.win=\ ;で区切られたパスのリスト\n 各パスは、モジュールのディレクトリまたは\n モジュラjarへのパスです。\n (各パスは、絶対パスまたは現在のディレクトリからの相対パスです。)\n このオプションは複数回使用できます。 + +help.option.name=\ アプリケーションおよびパッケージの名前 + +help.option.resource-dir=\ オーバーライドjpackageリソースへのパス\n アイコン、テンプレート・ファイルおよびjpackageのその他のリソースは、\n このディレクトリに置換リソースを追加することでオーバーライドできます。\n (絶対パスまたは現在のディレクトリからの相対パス) + +help.option.runtime-image=\ アプリケーション・イメージにコピーされる、事前定義済のランタイム・イメージ\n のパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n --runtime-imageが指定されていない場合、jpackageはjlinkを実行し、\n 次のオプションを使用してランタイム・イメージを作成します:\n --strip-debug、--no-header-files、--no-man-pagesおよび\n --strip-native-commands。 + +help.option.temp=\ 一時ファイルの作成に使用される新規または空のディレクトリのパス\n (絶対パスまたは現在のディレクトリからの相対パス)\n 指定した場合、タスク完了時に一時ディレクトリは削除されないため\n 手動で削除する必要があります。\n 指定しなかった場合、一時ディレクトリが作成され\n タスク完了時に削除されます。 + +help.option.type.win=\ 作成するパッケージのタイプ\n 有効な値: {"app-image", "exe", "msi"}\n このオプションを指定しない場合、プラットフォーム依存の\n デフォルト・タイプが作成されます。 +help.option.type.linux=\ 作成するパッケージのタイプ\n 有効な値: {"app-image", "deb", "rpm"}\n このオプションを指定しない場合、プラットフォーム依存の\n デフォルト・タイプが作成されます。 +help.option.type.mac=\ 作成するパッケージのタイプ\n 有効な値: {"app-image", "dmg", "pkg"}\n このオプションを指定しない場合、プラットフォーム依存の\n デフォルト・タイプが作成されます。 + +help.option.vendor=\ アプリケーションのベンダー + +help.option.verbose=\ 詳細な出力を有効にします + +help.option.version=\ 製品バージョンを出力ストリームに出力して終了します + +help.option.win-console=\ アプリケーションのコンソール・ランチャを作成します。コンソール・\n インタラクションが必要なアプリケーションに指定する必要があります + +help.option.win-dir-chooser=\ 製品をインストールするディレクトリをユーザーが\n 選択できるダイアログを追加します。 + +help.option.win-help-url=\ ユーザーが詳細情報または技術サポートを取得できるURL + +help.option.win-menu=\ このアプリケーションのスタート・メニューのショートカットを追加するリクエスト + +help.option.win-menu-group=\ このアプリケーションを配置するスタート・メニュー・グループ + +help.option.win-per-user-install=\ ユーザーごとにインストールを実行するリクエスト + +help.option.win-shortcut=\ このアプリケーションのデスクトップのショートカットを追加するリクエスト + +help.option.win-shortcut-prompt=\ ショートカットをインストーラで作成するかどうかをユーザーが\n 選択できるダイアログを追加します。 + +help.option.win-update-url=\ 使用可能なアプリケーション更新情報のURL + +help.option.win-upgrade-uuid=\ このパッケージのアップグレードに関連付けられているUUID -MSG_Help_win_launcher=\nアプリケーション・ランチャを作成するためのプラットフォーム依存オプション:\n --win-console\n アプリケーションのコンソール・ランチャを作成します。コンソール・\n インタラクションが必要なアプリケーションに指定する必要があります\n -MSG_Help_win_install=\ --win-dir-chooser\n ユーザーが製品をインストールするディレクトリを選択するための\n ダイアログを追加します。\n --win-help-url \n ユーザーが詳細情報または技術的なサポートを取得できるURL\n --win-menu\n このアプリケーションのスタート・メニュー・ショートカットを追加するようにリクエストします\n --win-menu-group \n このアプリケーションを配置するスタート・メニュー・グループ\n --win-per-user-install\n ユーザーごとにインストールを実行するようにリクエストします\n --win-shortcut\n このアプリケーションのデスクトップ・ショートカットを追加するようにリクエストします\n --win-shortcut-prompt\n ショートカットをインストーラで作成するかどうかをユーザーが選択できるようにする\n ダイアログを追加します。\n --win-update-url \n 使用可能なアプリケーションの更新情報のURL\n --win-upgrade-uuid \n このパッケージのアップグレードに関連付けられたUUID\n -MSG_Help_win_install_dir=デフォルトのインストール場所の下の相対サブパス\n -MSG_Help_mac_install=\ --mac-dmg-content [,...]\n dmgに参照されたコンテンツをすべて含めます。\n このオプションは複数回使用できます。 \n -MSG_Help_mac_launcher=\ --mac-package-identifier \n macOSのアプリケーションを一意に識別するID\n メイン・クラス名にデフォルト設定されています。\n 英数字(A-Z、a-z、0-9)、ハイフン(-)およびピリオド(.)文字のみ\n 使用できます。\n --mac-package-name \n メニュー・バーに表示されるアプリケーションの名前\n アプリケーション名とは異なります。\n この名前は16文字未満にする必要があり、メニュー・バーおよびアプリケーション情報ウィンドウに\n 表示するのに適している必要があります。\n アプリケーション名にデフォルト設定されています。\n --mac-package-signing-prefix \n アプリケーション・パッケージに署名する際、\n 既存のパッケージIDのない署名が必要なすべてのコンポーネントに、\n この値が接頭辞として付けられます。\n --mac-sign\n パッケージまたは事前定義済アプリケーション・イメージに署名するよう\n リクエストします。\n --mac-signing-keychain \n 署名アイデンティティを検索するキーチェーンの名前\n 指定しなかった場合、標準のキーチェーンが使用されます。\n --mac-signing-key-user-name \n Apple署名アイデンティティのチームまたはユーザー名部分。\n アプリケーション・イメージまたはインストーラの署名に使用する署名アイデンティティの\n 直接制御には、--mac-app-image-sign-identityまたは\n --mac-installer-sign-identity(あるいは両方)を使用します。このオプションは\n --mac-app-image-sign-identityまたは--mac-installer-sign-identityと組み合せることはできません。\n --mac-app-image-sign-identity \n アプリケーション・イメージの署名に使用するアイデンティティ。この値は直接\n "codesign"ツールの--signオプションに渡されます。このオプションは\n \ ---mac-signing-key-user-nameと組み合せることはできません。\n --mac-installer-sign-identity \n "pkg"インストーラの署名に使用するアイデンティティ。この値は直接\n "productbuild"ツールの--signオプションに渡されます。このオプションは\n --mac-signing-key-user-nameと組み合せることはできません。\n --mac-app-store\n jpackage出力がMac App Store用であること\n を示します。\n --mac-entitlements \n バンドルの実行可能ファイルおよびライブラリの署名時に\n 使用する権限を含むファイルのパス。\n --mac-app-category \n アプリケーションのplistのLSApplicationCategoryTypeを生成する際に使用する文字列。\n デフォルト値は"utilities"です。\n -MSG_Help_linux_install=\ --linux-package-name \n Linuxパッケージの名前。アプリケーション名にデフォルト設定されています\n --linux-deb-maintainer \n .debパッケージのMaintainer\n --linux-menu-group \n このアプリケーションが配置されているメニュー・グループ\n --linux-package-deps \n アプリケーションに必要なパッケージまたは機能\n --linux-rpm-license-type \n ライセンスのタイプ(RPM .specの"License: ")\n --linux-app-release \n RPM .specファイルのリリース値または\n DEBコントロール・ファイルのDebianリビジョン値。\n --linux-app-category \n RPM .specファイルのグループ値または \n DEBコントロール・ファイルのセクション値\n --linux-shortcut\n アプリケーションのショートカットを作成します。\n -MSG_Help_mac_linux_install_dir=アプリケーションのインストール・ディレクトリの絶対パス\n -MSG_Help_default_install_dir=OS XまたはLinux上のアプリケーションのインストール・ディレクトリの絶対パス。\n "プログラム・ファイル"や"AppData"など、Windows上のアプリケーションの\n インストール場所の相対サブパス。\n -MSG_Help_no_args=使用方法: jpackage \n利用可能なオプションのリストについては、jpackage --help (or -h)を使用します -MSG_Help_default_app_image=インストール可能なパッケージの作成に使用する、事前定義済み\n アプリケーション・イメージの場所\n -MSG_Help_mac_app_image=インストール可能なパッケージの作成または事前定義済みアプリケーション・\n イメージへの署名に使用する、事前定義済みアプリケーション・\n イメージの場所\n -MSG_Help_mac_sign_sample_usage=\ 事前定義済みアプリケーション・イメージへの署名:\n jpackage --type app-image --app-image \\\n --mac-sign [...]\n ノート: このモードで許可される唯一の追加オプション:\n 追加のmac署名オプションのセットおよび--verbose\n diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties index 6adf62ef1f8..ac72c67ee2f 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/HelpResources_zh_CN.properties @@ -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 @@ -24,20 +24,163 @@ # # -MSG_Help=用法:jpackage \n\n示例用法:\n--------------\n 生成适合主机系统的应用程序包:\n 对于模块化应用程序:\n jpackage -n name -p modulePath -m moduleName/className\n 对于非模块化应用程序:\n jpackage -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n 从预构建的应用程序映像:\n jpackage -n name --app-image appImageDir\n 生成应用程序映像:\n 对于模块化应用程序:\n jpackage --type app-image -n name -p modulePath \\\n -m moduleName/className\n 对于非模块化应用程序:\n jpackage --type app-image -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n 要为 jlink 提供您自己的选项,请单独运行 jlink:\n jlink --output appRuntimeImage -p modulePath \\\n --add-modules moduleName \\\n --no-header-files [...]\n jpackage --type app-image -n name \\\n -m moduleName/className --runtime-image appRuntimeImage\n 生成 Java 运行时程序包:\n jpackage -n name --runtime-image \n{6}\n一般选项:\n @ \n 从文件读取选项和/或模式 \n 可以多次使用此选项。\n --type -t \n 要创建的程序包的类型\n 有效值为:{1} \n 如果未指定此选项,则将创建与平台相关的\n 默认类型。\n --app-version \n 应用程序和/或程序包的版本\n --copyright \n 应用程序的版权\n --description \n 应用程序的说明\n --help -h \n 将用法文本输出到输出流并退出,用法文本中包含\n 适用于当前平台的每个有效选项的列表和说明\n --icon \n 应用程序包图标的路径\n (绝对路径或相对于当前目录的路径)\n --name -n \n 应用程序和/或程序包的名称\n --dest -d \n 用来放置所生成的输出文件的路径\n (绝对路径或相对于当前目录的路径)\n 默认为当前的工作目录。\n --temp \n 用来创建临时文件的新目录或空白目录的路径\n (绝对路径或相对于当前目录的路径)\n 如果指定,则在任务完成时将不删除临时目录,\n 必须手动删除临时目录。\n 如果未指定,则将创建一个临时目录,\n \ -并在任务完成时删除该临时目录。\n --vendor \n 应用程序的供应商\n --verbose\n 启用详细的输出\n --version\n 将产品版本输出到输出流并退出。\n\n用来创建运行时映像的选项:\n --add-modules <模块名称>[,<模块名称>...]\n 要添加的模块的逗号 (",") 分隔列表\n 此模块列表连同主模块(如果指定)\n 将作为 --add-module 参数传递到 jlink。\n 如果未指定,则仅使用主模块(如果指定了 --module),\n 或者使用默认的模块集(如果指定了 \n --main-jar)。\n 可以多次使用此选项。\n --module-path -p ...\n 路径的 {0} 分隔列表\n 每个路径要么是模块的目录,要么是\n 模块化 jar 的路径。\n (每个路径可以是绝对路径,也可以是相对于当前目录的路径。)\n 可以多次使用此选项。\n --jlink-options \n 要传递给 jlink 的选项列表(用空格分隔) \n 如果未指定,则默认为 "--strip-native-commands \n --strip-debug --no-man-pages --no-header-files"。 \n 可以多次使用此选项。\n --runtime-image \n 将复制到应用程序映像的预定义\n 运行时映像的路径\n (绝对路径或相对于当前目录的路径)\n 如果未指定 --runtime-image,jpackage 将运行 jlink 以\n 使用如下选项创建运行时映像:\n --strip-debug、--no-header-files、--no-man-pages 和 \n --strip-native-commands。\n\n用来创建应用程序映像的选项:\n --input -i \n 包含要打包的文件的输入目录的路径\n (绝对路径或相对于当前目录的路径)\n 输入目录中的所有文件将打包到\n 应用程序映像中。\n --app-content [,...]\n 要添加到应用程序有效负载中的文件和/或\n 目录的逗号分隔路径列表。\n 此选项可以多次使用。\n\n用来创建应用程序启动程序的选项:\n --add-launcher =\n 启动程序的名称和包含关键字-值对列表的\n 属性文件的路径\n (绝对路径或相对于当前目录的路径)\n \ -可以使用关键字 "module"、"main-jar"、"main-class"、"description"、\n "arguments"、"java-options"、"app-version"、"icon"、\n "launcher-as-service"、\n "win-console"、"win-shortcut"、"win-menu"、\n "linux-app-category" 和 "linux-shortcut"。\n 这些选项将添加到原始命令行选项中或者用来覆盖\n 原始命令行选项,以构建额外的替代启动程序。\n 将从命令行选项构建主应用程序启动程序。\n 可以使用此选项构建额外的替代启动程序,\n 可以多次使用此选项来构建\n 多个额外的启动程序。 \n --arguments
\n 在没有为启动程序提供命令行参数时,\n 要传递到主类的命令行参数\n 可以多次使用此选项。\n --java-options \n 要传递到 Java 运行时的选项\n 可以多次使用此选项。\n --main-class \n 要执行的应用程序主类的限定名称\n 只有在指定了 --main-jar 时才能使用此选项。\n --main-jar
\n 应用程序的主 JAR;包含主类\n (指定为相对于输入路径的路径)\n 可以指定 --module 或 --main-jar 选项,但是不能同时指定\n 两者。\n --module -m [/
]\n 应用程序的主模块(以及可选的主类)\n 此模块必须位于模块路径中。\n 如果指定了此选项,则将在 Java 运行时映像中\n 链接主模块。可以指定 --module 或 --main-jar 选项,\n 但是不能同时指定这两个选项。\n{2}\n用来创建应用程序包的选项:\n --about-url \n 应用程序主页的 URL\n --app-image \n {5} (绝对路径或相对于当前目录的路径)\n --file-associations \n 包含关键字-值对列表的属性文件的路径\n (绝对路径或相对于当前目录的路径)\n 可以使用关键字 "extension"、"mime-type"、"icon" 和 "description" \n 来描述此关联。\n 可以多次使用此选项。\n --install-dir \n {4} --license-file \n 许可证文件的路径\n (绝对路径或相对于当前目录的路径)\n --resource-dir \n 覆盖 jpackage 资源的路径\n \ -可以通过向该目录中添加替代资源来覆盖 jpackage 的\n 图标、模板文件和其他资源。\n (绝对路径或相对于当前目录的路径)\n --runtime-image \n 要安装的预定义运行时映像的路径\n (绝对路径或相对于当前目录的路径)\n 在创建运行时程序包时需要使用选项。\n --launcher-as-service\n 请求创建安装程序,以将主\n 应用程序启动程序注册为后台服务类型应用程序。\n\n用来创建应用程序包的与平台相关的选项:\n{3} +help.header=用法:jpackage + +help.short=使用 jpackage --help(或 -h)可获取可能选项的列表 + +help.option-group.sample.create-native-package=\ 生成适用于主机系统的应用程序包:\n 对于模块化应用程序:\n jpackage -n name -p modulePath -m moduleName/className\n 对于非模块化应用程序:\n jpackage -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n 从预构建的应用程序映像:\n jpackage -n name --app-image appImageDir + +help.option-group.sample.create-app-image=\ 生成应用程序映像:\n 对于模块化应用程序:\n jpackage --type app-image -n name -p modulePath \\\n -m moduleName/className\n 对于非模块化应用程序:\n jpackage --type app-image -i inputDir -n name \\\n --main-class className --main-jar myJar.jar\n 要向 jlink 提供您自己的选项,请分别运行 jlink:\n jlink --output appRuntimeImage -p modulePath \\\n --add-modules moduleName \\\n --no-header-files [...]\n jpackage --type app-image -n name \\\n -m moduleName/className --runtime-image appRuntimeImage + +help.option-group.sample.create-runtime-installer=\ 生成 Java 运行时程序包:\n jpackage -n name --runtime-image + +help.option-group.sample.sign-app-image=\ 对预定义应用程序映像进行签名:\n jpackage --type app-image --app-image \\\n --mac-sign [...]\n 注:此模式下允许的其他选项只有:\n 一组其他 mac 签名选项和 --verbose + +help.option-group.sample=示例用法 +help.option-group.generic=一般选项 +help.option-group.runtime-image=用来创建运行时映像的选项 +help.option-group.app-image=用来创建应用程序映像的选项 +help.option-group.launcher=用来创建应用程序启动程序的选项 +help.option-group.launcher-platform=用来创建应用程序启动程序的平台相关选项 +help.option-group.package=用来创建应用程序包的选项 +help.option-group.package-platform=用来创建应用程序包的与平台相关的选项 + +help.option.argument-file=\ 从文件读取选项和/或模式\n 可以多次使用此选项。 + +help.option.about-url=\ 应用程序主页的 URL + +help.option.add-launcher.win=\ 启动程序的名称,以及包含\n 键值对列表的属性文件的路径\n (绝对路径或相对于当前目录的路径)\n 可以使用键 "arguments"、"description"、"icon"、"java-options"、\n "launcher-as-service"、"main-class"、"main-jar"、"module"、\n "win-console"、"win-menu" 和 "win-shortcut"。\n 这些选项添加到或用于覆盖原始\n 命令行选项以构建其他替代启动程序。\n 将从命令行选项构建主应用程序启动程序。\n 可以使用此选项构建其他替代启动程序,\n 并且可以多次使用此选项\n 构建多个其他启动程序。 + +help.option.add-launcher.linux=\ 启动程序的名称,以及包含\n 键值对列表的属性文件的路径\n (绝对路径或相对于当前目录的路径)\n 可以使用键 "arguments"、"description"、"icon"、"java-options"、\n "launcher-as-service"、"linux-shortcut"、"main-class"、"main-jar" \n 和 "module"。\n 这些选项添加到或用于覆盖原始\n 命令行选项以构建其他替代启动程序。\n 将从命令行选项构建主应用程序启动程序。\n 可以使用此选项构建其他替代启动程序,\n 并且可以多次使用此选项\n 构建多个其他启动程序。 + +help.option.add-launcher.mac=\ 启动程序的名称,以及包含\n 键值对列表的属性文件的路径\n (绝对路径或相对于当前目录的路径)\n 可以使用键 "arguments"、"description"、"icon"、"java-options"、\n "launcher-as-service"、"main-class"、"main-jar" 和\n "module"。\n 这些选项添加到或用于覆盖原始\n 命令行选项以构建其他替代启动程序。\n 将从命令行选项构建主应用程序启动程序。\n 可以使用此选项构建其他替代启动程序,\n 并且可以多次使用此选项\n 构建多个其他启动程序。 + +help.option.add-modules=\ 要添加的模块列表(以逗号 (",") 分隔)\n 此模块列表以及主模块(如果指定)\n 将作为 --add-module 参数传递到 jlink。\n 如果未指定,则仅使用主模块\n (如果指定 --module)或默认模块集\n (如果指定 --main-jar)。\n 可以多次使用此选项。 + +help.option.app-content=\ 要添加到应用程序有效负载中的文件\n 和/或目录路径的逗号分隔列表。\n 可以多次使用此选项。 + +help.option.app-content.mac=\ 要添加到应用程序有效负载中的文件\n 和/或目录路径的逗号分隔列表。\n 可以多次使用此选项。\n 注:该值应为具有 "Resources" 子目录的\n 目录(或应用程序包的 "Contents" 目录中\n 有效的任何其他目录)。否则,jpackage \n 可能会生成无效的应用程序包,此应用程序包\n 可能会使代码签名和/或公证失败。 + +help.option.app-image=\ 用来构建可安装程序包的\n 预定义应用程序映像的位置\n (绝对路径或相对于当前目录的路径) + +help.option.app-image.mac=\ 用来构建可安装程序包或对预定义应用程序\n 映像进行签名的预定义应用程序\n 映像的位置\n (绝对路径或相对于当前目录的路径) + +help.option.app-version=\ 应用程序和/或程序包的版本 + +help.option.arguments=\ 在没有为启动程序提供命令行参数时,\n 要传递到主类的命令行参数\n 可以多次使用此选项。 + +help.option.copyright=\ 应用程序的版权 + +help.option.description=\ 应用程序的说明 + +help.option.dest=\ 放置生成的输出文件的路径\n (绝对路径或相对于当前目录的路径)\n 默认为当前工作目录。 + +help.option.file-associations=\ 包含键值对列表的属性文件的路径\n (绝对路径或相对于当前目录的路径)\n 键 "extension"、"mime-type"、"icon" 和 "description"\n 可用于描述关联。\n 可以多次使用此选项。 + +help.option.help=\ 将用法文本输出到输出流并退出,用法文本中包含\n 适用于当前平台的每个有效选项的列表和说明 + +help.option.icon=\ 应用程序包图标的路径\n (绝对路径或相对于当前目录的路径) + +help.option.input=\ 包含要打包的文件的输入目录的路径\n (绝对路径或相对于当前目录的路径)\n 输入目录中的所有文件将打包到\n 应用程序映像中。 + +help.option.install-dir=\ 应用程序安装目录的绝对路径 + +help.option.install-dir.win=\ 应用程序安装位置的相对子路径\n 例如 "Program Files" 或 "AppData"。 + +help.option.installer-runtime-image=\ 要安装的预定义运行时映像的路径\n (绝对路径或相对于当前目录的路径)\n 创建运行时程序包时需要提供选项。 + +help.option.java-options=\ 传递到 Java 运行时的选项\n 可以多次使用此选项。 + +help.option.jlink-options=\ 要传递到 jlink 的选项列表(以空格分隔)\n 如果未指定,则默认为 "--strip-native-commands\n --strip-debug --no-man-pages --no-header-files"。\n 可以多次使用此选项。 + +help.option.launcher-as-service=\ 请求创建安装程序,以将主应用程序\n 启动程序注册为后台服务类型应用程序。 + +help.option.license-file=\ 许可证文件的路径\n (绝对路径或相对于当前目录的路径) + +help.option.linux-app-category=\ RPM .spec 文件的组值或\n DEB 控制文件的节值 + +help.option.linux-app-release=\ RPM .spec 文件的发行版值或\n DEB 控制文件的 Debian 修订版值 + +help.option.linux-deb-maintainer=\ .deb 程序包的维护程序 + +help.option.linux-menu-group=\ 此应用程序所在的菜单组 + +help.option.linux-package-deps=\ 应用程序所需的程序包或功能 + +help.option.linux-package-name=\ Linux 程序包的名称,默认为应用程序名称 + +help.option.linux-rpm-license-type=\ 许可证类型(RPM .spec 的 "License: ") + +help.option.linux-shortcut=\ 为应用程序创建快捷方式。 + +help.option.mac-app-category=\ 用于构造应用程序 plist 中的 LSApplicationCategoryType 的\n 字符串。默认值为 "utilities"。 + +help.option.mac-app-image-sign-identity=\ 用于对应用程序映像进行签名的身份。此值将\n 直接传递到 "codesign" 工具的 --sign 选项。此选项\n 不能与 --mac-signing-key-user-name 结合使用。 + +help.option.mac-app-store=\ 指示 jpackage 输出面向\n Mac App Store。 + +help.option.mac-dmg-content=\ 包括 dmg 中引用的所有内容。\n 可以多次使用此选项。 + +help.option.mac-entitlements=\ 包含对包中的可执行文件和库进行签名时\n 要使用的权利的文件路径。 + +help.option.mac-installer-sign-identity=\ 用于对 "pkg" 安装程序进行签名的身份。此值将\n 直接传递到 "productbuild" 工具的 --sign 选项。此选项\n 不能与 --mac-signing-key-user-name 结合使用。 + +help.option.mac-package-identifier=\ 唯一标识 macOS 应用程序的标识符\n 默认为主类名称。\n 只能使用字母数字 (A-Z,a-z,0-9)、连字符 (-)\n 和句点 (.) 字符。 + +help.option.mac-package-name=\ 应用程序在菜单栏中显示的名称\n 此名称可以与应用程序名称不同。\n 此名称的长度必须少于 16 个字符,并且\n 适合显示在菜单栏和应用程序“信息”窗口中。\n 默认为应用程序名称。 + +help.option.mac-package-signing-prefix=\ 对应用程序包进行签名时,此值将作为\n 前缀添加到需要签名但当前没有程序包\n 标识符的所有组件。 + +help.option.mac-sign=\ 请求对程序包或预定义的应用程序映像\n 进行签名。 + +help.option.mac-signing-keychain=\ 要用来搜索签名身份的密钥链的名称\n 如果未指定,则使用标准密钥链。 + +help.option.mac-signing-key-user-name=\ Apple 签名身份的团队或用户名称部分。为了直接\n 控制用于对应用程序映像或安装程序进行签名的\n 签名身份,请使用 --mac-app-image-sign-identity 和/或\n --mac-installer-sign-identity。此选项不能与\n --mac-app-image-sign-identity 或 --mac-installer-sign-identity 结合使用。 + +help.option.main-class=\ 要执行的应用程序主类的限定名称\n 只有在指定了 --main-jar 时才能使用此选项。 + +help.option.main-jar=\ 应用程序的主 JAR;包含主类\n (指定为相对于输入路径的路径)\n 可以指定 --module 或 --main-jar 选项,\n 但不能同时指定这两个选项。 + +help.option.module=\ 应用程序的主模块(以及可选的主类)\n 此模块必须位于模块路径中。\n 指定了此选项时,将在 Java 运行时映像中\n 链接主模块。可以指定 --module 或 --main-jar \n 选项,但不能同时指定这两个选项。 + +help.option.module-path=\ 以 : 分隔的路径列表\n 每个路径是模块的目录或\n 模块化 jar 的路径。\n (每个路径可以是绝对路径,也可以是相对于当前目录的路径。)\n 可以多次使用此选项。 +help.option.module-path.win=\ 以 ; 分隔的路径列表\n 每个路径是模块的目录或\n 模块化 jar 的路径。\n (每个路径可以是绝对路径,也可以是相对于当前目录的路径。)\n 可以多次使用此选项。 + +help.option.name=\ 应用程序和/或程序包的名称 + +help.option.resource-dir=\ 覆盖 jpackage 资源的路径\n 可以通过向此目录中添加替换资源来覆盖 jpackage 的\n 图标、模板文件和其他资源。\n (绝对路径或相对于当前目录的路径) + +help.option.runtime-image=\ 将复制到应用程序映像中的预定义\n 运行时映像的路径\n (绝对路径或相对于当前目录的路径)\n 如果未指定 --runtime-image,jpackage 将运行 jlink 以\n 使用以下选项创建运行时映像:\n --strip-debug、--no-header-files、--no-man-pages 和\n --strip-native-commands。 + +help.option.temp=\ 用于创建临时文件的新目录或空目录的路径\n (绝对路径或相对于当前目录的路径)\n 如果指定,则在任务完成时将不删除\n 临时目录,必须手动删除临时目录。\n 如果未指定,将创建临时目录并\n 并在任务完成时删除该临时目录。 + +help.option.type.win=\ 要创建的程序包的类型\n 有效值为:{"app-image", "exe", "msi"}\n 如果未指定此选项,则将创建与平台相关的\n 默认类型。 +help.option.type.linux=\ 要创建的程序包的类型\n 有效值为:{"app-image", "deb", "rpm"}\n 如果未指定此选项,则将创建与平台相关的\n 默认类型。 +help.option.type.mac=\ 要创建的程序包的类型\n 有效值为:{"app-image", "dmg", "pkg"}\n 如果未指定此选项,则将创建与平台相关的\n 默认类型。 + +help.option.vendor=\ 应用程序的供应商 + +help.option.verbose=\ 启用详细的输出 + +help.option.version=\ 将产品版本输出到输出流并退出。 + +help.option.win-console=\ 为应用程序创建控制台启动程序,应当为\n 需要控制台交互的应用程序指定 + +help.option.win-dir-chooser=\ 添加一个对话框以允许用户选择\n 产品的安装目录。 + +help.option.win-help-url=\ 用户可以从中获取更多信息或技术支持的 URL + +help.option.win-menu=\ 请求为此应用程序添加“开始”菜单快捷方式 + +help.option.win-menu-group=\ 此应用程序所在的“开始”菜单组 + +help.option.win-per-user-install=\ 请求基于每个用户执行安装 + +help.option.win-shortcut=\ 请求为此应用程序添加桌面快捷方式 + +help.option.win-shortcut-prompt=\ 添加一个对话框以允许用户选择是否将由安装程序\n 创建快捷方式。 + +help.option.win-update-url=\ 可用应用程序更新信息的 URL + +help.option.win-upgrade-uuid=\ 与此程序包的升级关联的 UUID -MSG_Help_win_launcher=\n用来创建应用程序启动程序的与平台相关的选项:\n --win-console\n 为应用程序创建控制台启动程序,应当为\n 需要控制台交互的应用程序指定\n -MSG_Help_win_install=\ --win-dir-chooser\n 添加一个对话框以允许用户选择\n 产品的安装目录。\n --win-help-url \n 用户可以从中获取更多信息或技术支持的 URL\n --win-menu\n 请求为此应用程序添加开始菜单快捷方式\n --win-menu-group \n 此应用程序所在的开始菜单组\n --win-per-user-install\n 请求基于每个用户执行安装\n --win-shortcut\n 请求为此应用程序添加桌面快捷方式\n --win-shortcut-prompt\n 添加一个对话框以允许用户选择是否将由安装程序\n 创建快捷方式。\n --win-update-url \n 可用应用程序更新信息的 URL\n --win-upgrade-uuid \n 与此程序包的升级相关联的 UUID\n -MSG_Help_win_install_dir=默认安装位置下面的相对子路径\n -MSG_Help_mac_install=\ --mac-dmg-content [,...]\n 包括 DMG 中引用的所有内容。\n 此选项可以使用多次。\n -MSG_Help_mac_launcher=\ --mac-package-identifier \n 用来唯一地标识 macOS 应用程序的标识符\n 默认为主类名称。\n 只能使用字母数字 (A-Z,a-z,0-9)、连字符 (-) 和\n 句点 (.) 字符。\n --mac-package-name \n 出现在菜单栏中的应用程序名称\n 这可以与应用程序名称不同。\n 此名称的长度必须小于 16 个字符,适合\n 显示在菜单栏中和应用程序“信息”窗口中。\n 默认为应用程序名称。\n --mac-package-signing-prefix \n 在对应用程序包签名时,会在所有需要签名\n 但当前没有程序包标识符的组件的\n 前面加上此值。\n --mac-sign\n 请求对程序包或预定义的应用程序映像\n 进行签名。\n --mac-signing-keychain \n 要用来搜索签名身份的密钥链的名称\n 如果未指定,则使用标准的密钥链。\n --mac-signing-key-user-name \n Apple 签名身份的团队或用户名称部分。为了直接\n 控制用于对应用程序映像或安装程序进行签名的\n 签名身份,请使用 --mac-app-image-sign-identity 和/或\n --mac-installer-sign-identity。此选项不能与\n --mac-app-image-sign-identity 或 --mac-installer-sign-identity 结合使用。\n --mac-app-image-sign-identity \n 用于对应用程序映像进行签名的身份。此值将直接\n 传递至 "codesign" 工具的 --sign 选项。此选项不能\n 与 --mac-signing-key-user-name 结合使用。\n --mac-installer-sign-identity \n 用于对 "pkg" 安装程序进行签名的身份。此值将直接\n 传递至 "productbuild" 工具的 --sign 选项。此选项不能\n 与 --mac-signing-key-user-name 结合使用。\n --mac-app-store\n 指示 jpackage 输出面向\n Mac App Store。\n --mac-entitlements \n 包含一些权利的文件的路径,在对捆绑包中的可执行文件\n 和库进行签名时会使用这些权利。\n --mac-app-category \n 用于构造应用程序 plist 中 LSApplicationCategoryType 的\n 字符串。默认值为 "utilities"。\n -MSG_Help_linux_install=\ --linux-package-name \n Linux 程序包的名称,默认为应用程序名称\n --linux-deb-maintainer \n .deb 程序包的维护程序\n --linux-menu-group \n 此应用程序所在的菜单组\n --linux-package-deps \n 应用程序所需的程序包或功能\n --linux-rpm-license-type \n 许可证的类型(RPM .spec 的 "License: ")\n --linux-app-release \n RPM .spec 文件的发行版值或 \n DEB 控制文件的 Debian 修订版值\n --linux-app-category \n RPM .spec 文件的组值或 \n DEB 控制文件的节值\n --linux-shortcut\n 为应用程序创建快捷方式。\n -MSG_Help_mac_linux_install_dir=应用程序安装目录的绝对路径\n -MSG_Help_default_install_dir=OS X 或 Linux 上应用程序安装目录的绝对路径。\n Windows 上应用程序安装位置的相对子路径\n (如 "Program Files" 或 "AppData")。\n -MSG_Help_no_args=用法:jpackage \n使用 jpackage --help(或 -h)可获取可能选项的列表 -MSG_Help_default_app_image=用来构建可安装程序包的\n 预定义应用程序映像的位置\n -MSG_Help_mac_app_image=用来构建可安装程序包的\n 或对预定义应用程序映像进行签名的\n 预定义应用程序映像的位置\n -MSG_Help_mac_sign_sample_usage=\ 对预定义应用程序映像进行签名:\n jpackage --type app-image --app-image \\\n --mac-sign [...]\n 注:此模式下允许的其他选项只有:\n 一组其他 mac 签名选项和 --verbose\n diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_de.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_de.properties index 2426b97c7e2..7816f8ee71a 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_de.properties +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_de.properties @@ -24,25 +24,32 @@ # # -jpackage.description=Eigenständige Java-Anwendung verpacken - param.copyright.default=Copyright (C) {0,date,YYYY} -param.description.default=Kein Wert param.vendor.default=Unbekannt +bundle-type.win-app=Windows-Anwendungsimage +bundle-type.win-exe=EXE-Installationsprogrammpackage +bundle-type.win-msi=MSI-Installationsprogrammpackage +bundle-type.mac-app=Mac-Anwendungsimage +bundle-type.mac-dmg=Mac-DMG-Package +bundle-type.mac-pkg=Mac-PKG-Package +bundle-type.linux-app=Linux-Anwendungsimage +bundle-type.linux-deb=DEB-Bundle +bundle-type.linux-rpm=RPM-Bundle + resource.post-app-image-script=Auszuführendes Skript nach dem Auffüllen des Anwendungsimages message.using-default-resource=Standardpackageressource {0} {1} wird verwendet (durch Hinzufügen von {2} zu resource-dir ist eine Anpassung möglich). -message.no-default-resource=Keine Standardpackageressource {0} {1} (durch Hinzufügen von {2} zu resource-dir ist eine Anpassung möglich). +message.no-default-resource=Keine Standardpackageressource {0} (durch Hinzufügen von {1} zu resource-dir ist eine Anpassung möglich). message.using-custom-resource-from-file=Benutzerdefinierte Packageressource {0} wird verwendet (aus Datei {1} geladen). message.using-custom-resource=Benutzerdefinierte Packageressource {0} wird verwendet (aus {1} geladen). message.creating-app-bundle=Anwendungspackage {0} wird in {1} erstellt -message.runtime-image-dir-does-not-exist=Angegebenes Laufzeitimageverzeichnis {0}: {1} ist nicht vorhanden -message.resource-dir-does-not-exist=Angegebenes Ressourcenverzeichnis {0}: {1} ist nicht vorhanden message.debug-working-directory=Arbeitsverzeichnis für Debug beibehalten: {0} message.bundle-created={0}-Package wurde erfolgreich erstellt message.module-version=Version "{0}" aus Modul "{1}" wird als Anwendungsversion verwendet -message.module-class=Klasse "{0}" aus Modul "{1}" wird als Anwendungshauptklasse verwendet + +message.error-header={0} +message.advice-header=Empfehlung zur Behebung: {0} error.version-string-empty=Version darf keine leere Zeichenfolge sein error.version-string-zero-length-component=Version [{0}] enthält eine Komponente mit Nulllänge @@ -50,64 +57,69 @@ error.version-string-invalid-component=Version [{0}] enthält ungültige Kompone error.cannot-create-output-dir=Zielverzeichnis {0} kann nicht erstellt werden error.cannot-write-to-output-dir=Zielverzeichnis {0} ist schreibgeschützt -error.root-exists=Fehler: Anwendungszielverzeichnis {0} ist bereits vorhanden +error.root-exists=Anwendungszielverzeichnis {0} ist bereits vorhanden error.no-main-class-with-main-jar=Es wurde keine Hauptklasse angegeben oder in der JAR-Datei {0} gefunden error.no-main-class-with-main-jar.advice=Geben Sie eine Hauptklasse an, oder stellen Sie sicher, dass die JAR-Datei {0} eine Hauptklasse im Manifest angibt -error.no-main-class=Es wurde keine Hauptklasse angegeben oder in den angegebenen Anwendungsressourcen gefunden -error.no-main-class.advice=Geben Sie eine Anwendungsklasse an, oder stellen Sie sicher, dass die appResources eine JAR-Datei mit einer Anwendungsklasse im Manifest enthalten error.main-jar-does-not-exist=Die konfigurierte Haupt-JAR-Datei ist im Eingabeverzeichnis nicht vorhanden {0} error.main-jar-does-not-exist.advice=Die Haupt-JAR-Datei muss relativ zum Eingabeverzeichnis (nicht als absoluter Pfad) angegeben werden und muss in diesem Verzeichnis vorhanden sein error.no-module-in-path="{0}-Modul im Modulpfad nicht gefunden" -error.not-path-parameter="Ungültiger Wert für Parameter {0}: {1}" error.no-input-parameter="--input-Parameter für nicht modulare Anwendung fehlt" +error.non-option-arguments={0} Argumente, die keine Option sind, in der Befehlszeile gefunden. Argumente, die keine Option sind, sind nicht zulässig +error.undefined-default-bundling-operation=Standard-Bundling-Vorgang ist nicht definiert +error.undefined-default-bundling-operation.advice=Parameter {0} zur Befehlszeile hinzufügen +error.parameter-not-uuid=Der für Parameter {1} angegebene Wert "{0}" ist keine gültige UUID +error.parameter-not-path=Der für Parameter {1} angegebene Wert "{0}" ist kein gültiger Pfad +error.parameter-not-file=Der für Parameter {1} angegebene Wert "{0}" ist keine Datei +error.parameter-not-directory=Der für Parameter {1} angegebene Wert "{0}" ist kein Verzeichnis +error.parameter-not-empty-directory=Der für Parameter {1} angegebene Wert "{0}" ist kein leeres Verzeichnis oder kein vorhandener Pfad +error.parameter-not-url=Der für Parameter {1} angegebene Wert "{0}" ist keine gültige URL +error.parameter-not-launcher-shortcut-dir=Der für Parameter {1} angegebene Wert "{0}" ist kein gültiges Verknüpfungsstartverzeichnis +error.path-parameter-ioexception=I/O-Fehler beim Zugriff auf Pfadwert "{0}" von Parameter {1} +error.parameter-add-launcher-malformed=Der für Parameter {1} angegebene Wert "{0}" stimmt nicht mit dem Muster = überein +error.parameter-add-launcher-not-file=Der Wert des Pfades zu einer Eigenschaftendatei "{0}", der für den zusätzlichen Launcher "{1}" bereitgestellt wird, ist kein gültiger Dateipfad +error.properties-parameter-not-path=Der für Eigenschaft "{1}" in Datei "{2}" angegebene Wert "{0}" ist kein gültiger Pfad +error.properties-parameter-not-file=Der für Eigenschaft "{1}" in Datei "{2}" angegebene Wert "{0}" ist keine Datei +error.properties-parameter-not-launcher-shortcut-dir=Der für Eigenschaft "{1}" in Datei "{2}" angegebene Wert "{0}" ist kein gültiges Verknüpfungsstartverzeichnis + error.no-content-types-for-file-association=Für Dateiverknüpfungsnummer {0} wurden keine MIME-Typen angegeben error.no-content-types-for-file-association.advice=Geben Sie einen MIME-Typ für Dateiverknüpfungsnummer {0} an error.too-many-content-types-for-file-association=Für Dateiverknüpfungsnummer {0} wurde mehr als ein MIME-Typ angegeben error.too-many-content-types-for-file-association.advice=Geben Sie nur einen MIME-Typ für Dateiverknüpfungsnummer {0} an -error.tool-not-found={0} kann nicht gefunden werden. Grund: {1} -error.tool-not-found.advice=Installieren Sie {0} -error.tool-old-version={0} {1} oder eine neuere Version kann nicht gefunden werden -error.tool-old-version.advice=Installieren Sie {0} {1} oder eine neuere Version +error.launcher-duplicate-name=Mehrere Launcher haben denselben Namen "{0}". Launcher müssen eindeutige Namen haben + +error.tool-error=Validieren von "{0}" nicht möglich. Grund: {1} +error.tool-not-executable="{0}" ist nicht ausführbar +error.tool-not-found="{0}" kann nicht gefunden werden +error.tool-not-found.advice=Installieren Sie "{0}" +error.tool-old-version="{0}" {1} oder eine neuere Version kann nicht gefunden werden +error.tool-old-version.advice=Installieren Sie "{0}" {1} oder eine neuere Version + error.jlink.failed=jlink nicht erfolgreich mit: {0} error.blocked.option=jlink-Option [{0}] ist in --jlink-options nicht zulässig error.no.name=Name nicht mit --name angegeben. Es kann auch kein Name aus app-image abgeleitet werden error.no.name.advice=Geben Sie den Namen mit --name an -warning.no.jdk.modules.found=Warnung: Keine JDK-Module gefunden - -error.foreign-app-image=Fehler : Fehlende .jpackage.xml-Datei in app-image-Verzeichnis "{0}" -error.invalid-app-image=Fehler: app-image-Verzeichnis "{0}" wurde von einer anderen jpackage-Version generiert, oder Datei "{1}" ist nicht wohlgeformt +error.missing-app-image-file=Datei "{0}" fehlt im vordefinierten Anwendungsimage "{1}" +error.invalid-app-image-file=Datei "{0}" im vordefinierten Anwendungsimage "{1}" ist beschädigt oder wurde von einer anderen Version von jpackage erstellt +error.malformed-app-image-file=Datei "{0}" im vordefinierten Anwendungsimage "{1}" enthält nicht wohlgeformte XML-Daten +error.reading-app-image-file=Datei "{0}" konnte im vordefinierten Anwendungsimage "{1}" nicht gelesen werden error.invalid-install-dir=Ungültiges Installationsverzeichnis "{0}" -MSG_BundlerFailed=Fehler: Bundler "{1}" ({0}) konnte kein Package generieren -MSG_BundlerConfigException=Bundler {0} aufgrund eines Konfigurationsproblems übersprungen: {1} \nEmpfehlung zur Behebung: {2} -MSG_BundlerConfigExceptionNoAdvice=Bundler {0} aufgrund eines Konfigurationsproblems übersprungen: {1} -MSG_BundlerRuntimeException=Bundler {0} nicht erfolgreich. Grund: {1} +ERR_NoMainClass=Hauptanwendungsklasse fehlt +ERR_UnsupportedOption=Option [{0}] ist auf dieser Plattform ungültig +ERR_InvalidTypeOption=Option [{0}] ist nicht gültig mit Typ [{1}] +ERR_NoInstallerEntryPoint=Option [{0}] ist nicht gültig ohne Einstiegspunktoption --module oder --main-jar +ERR_MutuallyExclusiveOptions=Sich gegenseitig ausschließende Optionen: [{0}] und [{1}] +ERR_InvalidOptionWithAppImageSigning=Option [{0}] ist nicht gültig beim Signieren eines Anwendungsimages -ERR_NoMainClass=Fehler: Hauptanwendungsklasse fehlt -ERR_UnsupportedOption=Fehler: Option [{0}] ist auf dieser Plattform ungültig -ERR_InvalidTypeOption=Fehler: Option [{0}] ist nicht gültig mit Typ [{1}] -ERR_NoInstallerEntryPoint=Fehler: Option [{0}] ist nicht gültig ohne Einstiegspunktoption --module oder --main-jar -ERR_MutuallyExclusiveOptions=Fehler: Optionen [{0}] und [{1}] schließen sich gegenseitig aus -ERR_InvalidOptionWithAppImageSigning=Fehler: Option [{0}] ist nicht gültig beim Signieren eines Anwendungsimages - -ERR_MissingArgument=Fehler: Fehlendes Argument: {0} -ERR_MissingRequiredArgument=Fehler: Für das Argument {0} ist mindestens eines der folgenden Argumente erforderlich: [{1}] -ERR_AppImageNotExist=Fehler: Anwendungsimageverzeichnis "{0}" ist nicht vorhanden -ERR_NoAddLauncherName=Fehler: Für Option --add-launcher müssen ein Name und ein Dateipfad angegeben werden (--add-launcher =) -ERR_NoUniqueName=Fehler: Für --add-launcher = ist ein eindeutiger Name erforderlich -ERR_InvalidAppName=Fehler: Ungültiger Anwendungsname: {0} -ERR_InvalidSLName=Fehler: Ungültiger Name für hinzuzufügenden Launcher: {0} -ERR_IconFileNotExit=Fehler: Die angegebene Symboldatei [{0}] ist nicht vorhanden -ERR_LicenseFileNotExit=Fehler: Die angegebene Lizenzdatei ist nicht vorhanden -ERR_BuildRootInvalid=Fehler: Das temporäre Verzeichnis ({0}) darf nicht vorhanden sein oder muss leer sein -ERR_InvalidOption=Fehler: Ungültige Option: [{0}] -ERR_InvalidInstallerType=Fehler: Ungültiger oder nicht unterstützter Typ: [{0}] -ERR_BothMainJarAndModule=Fehler: Die Optionen --main-jar und --module dürfen nicht beide vorhanden sein -ERR_NoEntryPoint=Fehler: Für das Erstellen des Anwendungsimages muss entweder die Option --main-jar oder die Option --module angegeben werden -ERR_CannotParseOptions=Fehler: Option @filename wird verarbeitet: {0} -ERR_MissingJLinkOptMacAppStore=Fehler: Argument "--mac-app-store" erfordert eine {0}-Option für Argument "--jlink-options" -ERR_MacAppStoreRuntimeBinExists=Fehler: Laufzeitimage "{0}" darf nicht den Ordner "bin" enthalten. Verwenden Sie die jlink-Option "--strip-native-commands" beim Generieren des Laufzeitimages mit dem Argument "--mac-app-store". +ERR_MissingArgument2=Fehlendes Argument: {0} oder {1} +ERR_InvalidAppName=Ungültiger Anwendungsname: {0} +ERR_InvalidSLName=Ungültiger Name für hinzuzufügenden Launcher: {0} +ERR_InvalidOption=Ungültige Option: [{0}] +ERR_InvalidInstallerType=Ungültiger oder nicht unterstützter Typ: [{0}] +ERR_NoEntryPoint=Für das Erstellen des Anwendungsimages muss entweder die Option --main-jar oder die Option --module angegeben werden +ERR_CannotParseOptions=Option @filename wird verarbeitet: {0} +ERR_MissingJLinkOptMacAppStore=Argument "--mac-app-store" erfordert eine {0}-Option für Argument "--jlink-options" diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties index e0faf346973..5db5ead7577 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_ja.properties @@ -24,25 +24,32 @@ # # -jpackage.description=自己完結型Javaアプリケーションをパッケージ化します - param.copyright.default=Copyright (C) {0,date,YYYY} -param.description.default=なし param.vendor.default=不明 +bundle-type.win-app=Windowsアプリケーション・イメージ +bundle-type.win-exe=EXEインストーラ・パッケージ +bundle-type.win-msi=MSIインストーラ・パッケージ +bundle-type.mac-app=Macアプリケーション・イメージ +bundle-type.mac-dmg=Mac DMGパッケージ +bundle-type.mac-pkg=Mac PKGパッケージ +bundle-type.linux-app=Linuxアプリケーション・イメージ +bundle-type.linux-deb=DEBバンドル +bundle-type.linux-rpm=RPMバンドル + resource.post-app-image-script=アプリケーション・イメージを移入した後に実行するスクリプト message.using-default-resource=デフォルトのパッケージ・リソース{0} {1}の使用({2}をresource-dirに追加してカスタマイズ)。 -message.no-default-resource=デフォルトのパッケージ・リソース{0} {1}なし({2}をresource-dirに追加してカスタマイズ)。 +message.no-default-resource=デフォルトのパッケージ・リソース{0}なし({1}をresource-dirに追加してカスタマイズ)。 message.using-custom-resource-from-file=カスタム・パッケージ・リソース{0}の使用(ファイル{1}からロード済) message.using-custom-resource=カスタム・パッケージ・リソース{0}の使用({1}からロード済) message.creating-app-bundle=アプリケーション・パッケージを作成しています: {1}内の{0} -message.runtime-image-dir-does-not-exist=指定されたランタイム・イメージ・ディレクトリ{0}: {1}は存在しません -message.resource-dir-does-not-exist=指定されたリソース・ディレクトリ{0}: {1}は存在しません message.debug-working-directory=デバッグの作業ディレクトリが保持されました: {0} message.bundle-created={0}パッケージの作成に成功しました message.module-version=モジュール"{1}"のバージョン"{0}"をアプリケーション・バージョンとして使用 -message.module-class=モジュール"{1}"のクラス"{0}"をアプリケーション・メイン・クラスとして使用 + +message.error-header={0} +message.advice-header=修正のアドバイス: {0} error.version-string-empty=バージョンを空の文字列にすることはできません error.version-string-zero-length-component=バージョン[{0}]に長さゼロのコンポーネントが含まれます @@ -50,64 +57,69 @@ error.version-string-invalid-component=バージョン[{0}]に無効なコンポ error.cannot-create-output-dir=宛先ディレクトリ{0}を作成できません。 error.cannot-write-to-output-dir=宛先ディレクトリ{0}は書込み不可です -error.root-exists=エラー: アプリケーションの宛先ディレクトリ{0}はすでに存在します +error.root-exists=アプリケーションの宛先ディレクトリ{0}はすでに存在します error.no-main-class-with-main-jar=メイン・クラスが指定されていなかったか、jar {0}に見つかりませんでした error.no-main-class-with-main-jar.advice=メイン・クラスを指定するか、jar {0}がマニフェストで指定していることを確認してください -error.no-main-class=メイン・クラスが指定されていなかったか、指定されたアプリケーション・リソースに見つかりませんでした -error.no-main-class.advice=アプリケーション・クラスを指定するか、マニフェストでappResourcesにアプリケーション・クラスを含むjarがあることを確認してください error.main-jar-does-not-exist=入力ディレクトリで、構成されたメインjarが{0}に存在しません error.main-jar-does-not-exist.advice=入力ディレクトリに対して相対的に(絶対パスではない)メインjarを指定する必要があり、そのディレクトリ内に存在する必要があります error.no-module-in-path="モジュール・パスに{0}モジュールが見つかりませんでした" -error.not-path-parameter="{0}パラメータの無効な値: {1}" error.no-input-parameter="非モジュラ・アプリケーションに--inputパラメータがありません" +error.non-option-arguments=コマンドラインで{0}個の非オプション引数が見つかりました。非オプション引数は使用できません +error.undefined-default-bundling-operation=デフォルトのバンドル操作は未定義です +error.undefined-default-bundling-operation.advice=コマンドラインに{0}パラメータを追加します +error.parameter-not-uuid=パラメータ{1}に指定された値"{0}"は有効なUUIDではありません +error.parameter-not-path=パラメータ{1}に指定された値"{0}"は有効なパスではありません +error.parameter-not-file=パラメータ{1}に指定された値"{0}"はファイルではありません +error.parameter-not-directory=パラメータ{1}に指定された値"{0}"はディレクトリではありません +error.parameter-not-empty-directory=パラメータ{1}に指定された値"{0}"が空のディレクトリでないか、存在しないパスです +error.parameter-not-url=パラメータ{1}に指定された値"{0}"は有効なURLではありません +error.parameter-not-launcher-shortcut-dir=パラメータ{1}に指定された値"{0}"は、有効なショートカット起動ディレクトリではありません +error.path-parameter-ioexception=パラメータ{1}のパス値"{0}"へのアクセス中にI/Oエラーが発生しました +error.parameter-add-launcher-malformed=パラメータ{1}に指定された値"{0}"がパターン=と一致しません +error.parameter-add-launcher-not-file=追加のランチャ"{1}"に指定されたプロパティ・ファイル"{0}"へのパスの値は有効なファイル・パスではありません +error.properties-parameter-not-path="{2}"ファイルのプロパティ"{1}"に指定された値"{0}"は有効なパスではありません +error.properties-parameter-not-file="{2}"ファイルのプロパティ"{1}"に指定された値"{0}"はファイルではありません +error.properties-parameter-not-launcher-shortcut-dir="{2}"ファイルのプロパティ"{1}"に指定された値"{0}"は、有効なショートカット起動ディレクトリではありません + error.no-content-types-for-file-association=ファイル・アソシエーション番号{0}にMIMEタイプが指定されませんでした error.no-content-types-for-file-association.advice=ファイル・アソシエーション番号{0}にMIMEタイプを指定してください error.too-many-content-types-for-file-association=ファイル・アソシエーション番号{0}に複数のMIMEタイプが指定されました error.too-many-content-types-for-file-association.advice=ファイル・アソシエーション番号{0}にMIMEタイプを1つのみ指定してください -error.tool-not-found={0}が見つかりません。理由: {1} -error.tool-not-found.advice={0}をインストールしてください -error.tool-old-version={0} {1}以降が見つかりません -error.tool-old-version.advice={0} {1}以降をインストールしてください +error.launcher-duplicate-name=複数のランチャに同じ名前"{0}"が付いています。ランチャには一意の名前が必要です + +error.tool-error="{0}"を検証できません。理由: {1} +error.tool-not-executable="{0}"は実行可能ではありません +error.tool-not-found="{0}"が見つかりません +error.tool-not-found.advice="{0}"をインストールしてください +error.tool-old-version="{0}" {1}以降が見つかりません +error.tool-old-version.advice="{0}" {1}以降をインストールしてください + error.jlink.failed=jlinkが次で失敗しました: {0} error.blocked.option=jlinkオプション[{0}]は--jlink-optionsでは許可されません error.no.name=名前が--nameで指定されておらず、app-imageから推論できません error.no.name.advice=--nameで名前を指定します -warning.no.jdk.modules.found=警告: JDKモジュールが見つかりません - -error.foreign-app-image=エラー: app-imageディレクトリ"{0}"に.jpackage.xmlファイルがありません -error.invalid-app-image=エラー: app-imageディレクトリ"{0}"は、別のjpackageバージョンまたは不正な"{1}"ファイルで生成されました +error.missing-app-image-file=事前定義済アプリケーション・イメージ"{1}"に"{0}"ファイルがありません +error.invalid-app-image-file=事前定義済アプリケーション・イメージ"{1}"の"{0}"ファイルが破損しているか、別のバージョンのjpackageによって作成されました +error.malformed-app-image-file=事前定義済アプリケーション・イメージ"{1}"の"{0}"ファイルに不正なXMLデータが含まれています +error.reading-app-image-file=事前定義済アプリケーション・イメージ"{1}"の"{0}"ファイルの読取りに失敗しました error.invalid-install-dir=無効なインストール・ディレクトリ"{0}" -MSG_BundlerFailed=エラー: バンドラ"{1}" ({0})がパッケージの生成に失敗しました -MSG_BundlerConfigException=構成の問題のため、バンドラ{0}がスキップされました: {1} \n次の修正を行ってください: {2} -MSG_BundlerConfigExceptionNoAdvice=構成の問題のため、バンドラ{0}がスキップされました: {1} -MSG_BundlerRuntimeException={1}のため、バンドラ{0}が失敗しました +ERR_NoMainClass=メイン・アプリケーション・クラスがありません +ERR_UnsupportedOption=オプション[{0}]は、このプラットフォームでは無効です +ERR_InvalidTypeOption=オプション[{0}]は、タイプ[{1}]では無効です +ERR_NoInstallerEntryPoint=オプション[{0}]は、--moduleまたは--main-jarエントリ・ポイント・オプションなしでは無効です +ERR_MutuallyExclusiveOptions=相互排他的なオプション[{0}]と[{1}] +ERR_InvalidOptionWithAppImageSigning=アプリケーション・イメージへの署名時にオプション[{0}]が有効ではありません -ERR_NoMainClass=エラー: メイン・アプリケーション・クラスがありません -ERR_UnsupportedOption=エラー: オプション[{0}]は、このプラットフォームでは無効です -ERR_InvalidTypeOption=エラー: オプション[{0}]は、タイプ[{1}]では無効です -ERR_NoInstallerEntryPoint=エラー: オプション[{0}]は、--moduleまたは--main-jarエントリ・ポイント・オプションなしでは無効です -ERR_MutuallyExclusiveOptions=エラー: 相互排他的なオプション[{0}]と[{1}] -ERR_InvalidOptionWithAppImageSigning=エラー: アプリケーション・イメージへの署名時にオプション[{0}]が有効ではありません - -ERR_MissingArgument=エラー: 引数がありません: {0} -ERR_MissingRequiredArgument=エラー: {0}引数には少なくとも1つの[{1}]引数が必要です -ERR_AppImageNotExist=エラー: アプリケーション・イメージ・ディレクトリ"{0}"は存在しません -ERR_NoAddLauncherName=エラー: --add-launcherオプションには名前およびファイル・パスが必要です(--add-launcher =) -ERR_NoUniqueName=エラー: --add-launcher =には一意の名前が必要です -ERR_InvalidAppName=エラー: 無効なアプリケーション名: {0} -ERR_InvalidSLName=エラー: 無効な追加ランチャ名: {0} -ERR_IconFileNotExit=エラー: 指定されたアイコン・ファイル[{0}]は存在しません -ERR_LicenseFileNotExit=エラー: 指定されたライセンス・ファイルは存在しません -ERR_BuildRootInvalid=エラー: 一時({0})は存在しないか、空のディレクトリである必要があります -ERR_InvalidOption=エラー: 無効なオプション: [{0}] -ERR_InvalidInstallerType=エラー: 無効またはサポートされていないタイプ: [{0}] -ERR_BothMainJarAndModule=エラー: --main-jarオプションと--moduleオプションの両方を指定することはできません -ERR_NoEntryPoint=エラー: アプリケーション・イメージの作成には--main-jarまたは--moduleオプションが必要です -ERR_CannotParseOptions=エラー: @filenameオプションの処理: {0} -ERR_MissingJLinkOptMacAppStore=エラー: --mac-app-store引数では、--jlink-options引数に{0}オプションが必要です -ERR_MacAppStoreRuntimeBinExists=エラー: ランタイム・イメージ"{0}"に"bin"フォルダを含めることはできません。--mac-app-store引数で使用されるランタイム・イメージを生成する際に、--strip-native-commands jlinkオプションを使用します。 +ERR_MissingArgument2=引数がありません: {0}または{1} +ERR_InvalidAppName=無効なアプリケーション名: {0} +ERR_InvalidSLName=無効な追加ランチャ名: {0} +ERR_InvalidOption=無効なオプション: [{0}] +ERR_InvalidInstallerType=無効またはサポートされていないタイプ: [{0}] +ERR_NoEntryPoint=アプリケーション・イメージの作成には--main-jarまたは--moduleオプションが必要です +ERR_CannotParseOptions=@filenameオプションの処理: {0} +ERR_MissingJLinkOptMacAppStore=--mac-app-store引数では、--jlink-options引数に{0}オプションが必要です diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties index 0236ef34077..23540af7db2 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/resources/MainResources_zh_CN.properties @@ -24,25 +24,32 @@ # # -jpackage.description=打包自包含 Java 应用程序 - param.copyright.default=版权所有 (C) {0,date,YYYY} -param.description.default=无 param.vendor.default=未知 +bundle-type.win-app=Windows 应用程序映像 +bundle-type.win-exe=EXE 安装程序包 +bundle-type.win-msi=MSI 安装程序包 +bundle-type.mac-app=Mac 应用程序映像 +bundle-type.mac-dmg=Mac DMG 程序包 +bundle-type.mac-pkg=Mac PKG 程序包 +bundle-type.linux-app=Linux 应用程序映像 +bundle-type.linux-deb=DEB 包 +bundle-type.linux-rpm=RPM 包 + resource.post-app-image-script=要在填充应用程序映像之后运行的脚本 message.using-default-resource=使用默认程序包资源 {0} {1}(将 {2} 添加到 resource-dir 中以进行定制)。 -message.no-default-resource=无默认程序包资源 {0} {1}(将 {2} 添加到 resource-dir 中以进行定制)。 +message.no-default-resource=无默认程序包资源 {0}(将 {1} 添加到 resource-dir 中以进行定制)。 message.using-custom-resource-from-file=使用定制程序包资源 {0} (从文件 {1} 加载)。 message.using-custom-resource=使用定制程序包资源 {0} (从 {1} 加载)。 message.creating-app-bundle=正在 {1} 中创建应用程序包 {0} -message.runtime-image-dir-does-not-exist=指定的运行时映像目录 {0}:{1} 不存在 -message.resource-dir-does-not-exist=指定的资源目录 {0}:{1} 不存在 message.debug-working-directory=用于调试的已保留工作目录: {0} message.bundle-created=已成功地构建 {0} 程序包 message.module-version=正在将模块 "{1}" 中的版本 "{0}" 用作应用程序版本 -message.module-class=正在将模块 "{1}" 中的类 "{0}" 用作应用程序主类 + +message.error-header={0} +message.advice-header=修复建议:{0} error.version-string-empty=版本不能为空字符串 error.version-string-zero-length-component=版本 [{0}] 包含长度为零的组件 @@ -50,64 +57,69 @@ error.version-string-invalid-component=版本 [{0}] 包含无效组件 [{1}] error.cannot-create-output-dir=无法创建目标目录 {0} error.cannot-write-to-output-dir=目标目录 {0} 不可写 -error.root-exists=错误:应用程序目标目录 {0} 已存在 +error.root-exists=应用程序目标目录 {0} 已存在 error.no-main-class-with-main-jar=未指定主类,在 jar {0} 中也未找到主类 error.no-main-class-with-main-jar.advice=请指定主类或确保 jar {0} 在清单中指定一个主类。 -error.no-main-class=未指定主类,在提供的应用程序资源中也未找到主类 -error.no-main-class.advice=请指定应用程序类,或者确保 appResources 中有一个 jar 在清单中包含应用程序类。 error.main-jar-does-not-exist=配置的主 jar 在输入目录中不存在 {0} error.main-jar-does-not-exist.advice=必须使用相对于输入目录的路径(不使用绝对路径)指定主 jar ,并且该目录中存在主 jar error.no-module-in-path="无法在模块路径中找到 {0} 模块" -error.not-path-parameter="{0} 参数的值无效:{1}" error.no-input-parameter="非模块化应用程序缺少 --input 参数" +error.non-option-arguments=在命令行上发现 {0} 个非选项参数。不允许使用非选项参数 +error.undefined-default-bundling-operation=未定义默认绑定操作 +error.undefined-default-bundling-operation.advice=将 {0} 参数添加到命令行 +error.parameter-not-uuid=为参数 {1} 提供的值 "{0}" 不是有效的 UUID +error.parameter-not-path=为参数 {1} 提供的值 "{0}" 不是有效路径 +error.parameter-not-file=为参数 {1} 提供的值 "{0}" 不是文件 +error.parameter-not-directory=为参数 {1} 提供的值 "{0}" 不是目录 +error.parameter-not-empty-directory=为参数 {1} 提供的值 "{0}" 不是空目录或是不存在的路径 +error.parameter-not-url=为参数 {1} 提供的值 "{0}" 不是有效的 URL +error.parameter-not-launcher-shortcut-dir=为参数 {1} 提供的值 "{0}" 不是有效的快捷方式启动目录 +error.path-parameter-ioexception=访问参数 {1} 的路径值 "{0}" 时出现 I/O 错误 +error.parameter-add-launcher-malformed=为参数 {1} 提供的值 "{0}" 与模式 = 不匹配 +error.parameter-add-launcher-not-file=为其他启动程序 "{1}" 提供的属性文件 "{0}" 的路径值不是有效的文件路径 +error.properties-parameter-not-path=为 "{2}" 文件中的属性 "{1}" 提供的值 "{0}" 不是有效路径 +error.properties-parameter-not-file=为 "{2}" 文件中的属性 "{1}" 提供的值 "{0}" 不是文件 +error.properties-parameter-not-launcher-shortcut-dir=为 "{2}" 文件中的属性 "{1}" 提供的值 "{0}" 不是有效的快捷方式启动目录 + error.no-content-types-for-file-association=没有为文件关联号{0}指定 MIME 类型 error.no-content-types-for-file-association.advice=为文件关联号 {0} 指定 MIME 类型 error.too-many-content-types-for-file-association=为文件关联号{0}指定了多个 MIME 类型 error.too-many-content-types-for-file-association.advice=仅为文件关联号 {0} 指定一个 MIME 类型 -error.tool-not-found=找不到 {0}。原因:{1} -error.tool-not-found.advice=请安装 {0} -error.tool-old-version=找不到 {0} {1}或更新版本 -error.tool-old-version.advice=请安装 {0} {1}或更新版本 +error.launcher-duplicate-name=多个启动程序具有相同的名称 "{0}"。启动程序应具有唯一名称 + +error.tool-error=无法验证 "{0}"。原因:{1} +error.tool-not-executable="{0}" 不可执行 +error.tool-not-found=找不到 "{0}" +error.tool-not-found.advice=请安装 "{0}" +error.tool-old-version=找不到 "{0}" {1} 或更新版本 +error.tool-old-version.advice=请安装 "{0}" {1} 或更新版本 + error.jlink.failed=jlink 失败,出现 {0} error.blocked.option=不允许在 --jlink-options 中使用 jlink 选项 [{0}] error.no.name=未使用 --name 指定名称,无法从 app-image 推断名称 error.no.name.advice=使用 --name 指定名称 -warning.no.jdk.modules.found=警告: 未找到 JDK 模块 - -error.foreign-app-image=错误:app-image 目录 "{0}" 中缺少 .jpackage.xml 文件 -error.invalid-app-image=错误:另一个 jpackage 版本或格式错误的 "{1}" 文件生成了 app-image 目录 "{0}" +error.missing-app-image-file=预定义的应用程序映像 "{1}" 中缺少 "{0}" 文件 +error.invalid-app-image-file=预定义的应用程序映像 "{1}" 中的 "{0}" 文件已损坏或由其他版本的 jpackage 创建 +error.malformed-app-image-file=预定义的应用程序映像 "{1}" 中的 "{0}" 文件包含格式错误的 XML 数据 +error.reading-app-image-file=无法在预定义的应用程序映像 "{1}" 中读取 "{0}" 文件 error.invalid-install-dir=安装目录 "{0}" 无效 -MSG_BundlerFailed=错误:打包程序 "{1}" ({0}) 无法生成程序包 -MSG_BundlerConfigException=由于配置问题, 跳过了打包程序{0}: {1} \n修复建议: {2} -MSG_BundlerConfigExceptionNoAdvice=由于配置问题, 跳过了打包程序{0}: {1} -MSG_BundlerRuntimeException=由于{1}, 打包程序{0}失败 +ERR_NoMainClass=缺少主应用程序类 +ERR_UnsupportedOption=选项 [{0}] 在此平台上无效 +ERR_InvalidTypeOption=选项 [{0}] 对于类型 [{1}] 无效 +ERR_NoInstallerEntryPoint=在没有 --module 或 --main-jar 入口点选项时,选项 [{0}] 无效 +ERR_MutuallyExclusiveOptions=选项 [{0}] 和 [{1}] 相互排斥 +ERR_InvalidOptionWithAppImageSigning=对应用程序映像进行签名时,选项 [{0}] 无效 -ERR_NoMainClass=错误:缺少主应用程序类 -ERR_UnsupportedOption=错误:选项 [{0}] 在此平台上无效 -ERR_InvalidTypeOption=错误:选项 [{0}] 对于类型 [{1}] 无效 -ERR_NoInstallerEntryPoint=错误:在没有 --module 或 --main-jar 入口点选项时,选项 [{0}] 无效 -ERR_MutuallyExclusiveOptions=错误:选项 [{0}] 和 [{1}] 相互排斥 -ERR_InvalidOptionWithAppImageSigning=错误:对应用程序映像签名时,选项 [{0}] 无效 - -ERR_MissingArgument=错误: 缺少参数: {0} -ERR_MissingRequiredArgument=错误:{0} 参数至少需要 [{1}] 参数之一 -ERR_AppImageNotExist=错误:应用程序映像目录 "{0}" 不存在 -ERR_NoAddLauncherName=错误:--add-launcher 选项需要一个名称和一个文件路径 (--add-launcher =) -ERR_NoUniqueName=错误:--add-launcher = 需要一个唯一的名称 -ERR_InvalidAppName=错误:应用程序名称 {0} 无效 -ERR_InvalidSLName=错误:添加启动程序名称 {0} 无效 -ERR_IconFileNotExit=错误:指定的图标文件 [{0}] 不存在 -ERR_LicenseFileNotExit=错误:指定的许可证文件不存在 -ERR_BuildRootInvalid=错误:临时目录 ({0}) 必须是不存在的目录或空白目录 -ERR_InvalidOption=错误:选项 [{0}] 无效 -ERR_InvalidInstallerType=错误:类型 [{0}] 无效或不受支持 -ERR_BothMainJarAndModule=错误:不能同时包含 --main-jar 和 --module 选项 -ERR_NoEntryPoint=错误:创建应用程序映像需要 --main-jar 或 --module 选项 -ERR_CannotParseOptions=错误:正在处理 @filename 选项:{0} -ERR_MissingJLinkOptMacAppStore=错误:对于 --jlink-options 参数,--mac-app-store 参数需要 {0} 选项 -ERR_MacAppStoreRuntimeBinExists=错误:运行时映像 "{0}" 不应包含 "bin" 文件夹。生成与 --mac-app-store 参数一起使用的运行时映像时,使用 --strip-native-commands jlink 选项。 +ERR_MissingArgument2=缺少参数:{0} 或 {1} +ERR_InvalidAppName=应用程序名称 {0} 无效 +ERR_InvalidSLName=添加启动程序名称 {0} 无效 +ERR_InvalidOption=选项 [{0}] 无效 +ERR_InvalidInstallerType=类型 [{0}] 无效或不受支持 +ERR_NoEntryPoint=创建应用程序映像需要 --main-jar 或 --module 选项 +ERR_CannotParseOptions=正在处理 @filename 选项:{0} +ERR_MissingJLinkOptMacAppStore=对于 --jlink-options 参数,--mac-app-store 参数需要 {0} 选项 diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_de.properties b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_de.properties index 3e6f8e30d6a..baaba64b398 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_de.properties +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_de.properties @@ -23,15 +23,9 @@ # questions. # # - -app.bundler.name=Windows-Anwendungsimage -exe.bundler.name=EXE-Installationsprogrammpackage -msi.bundler.name=MSI-Installationsprogrammpackage - param.menu-group.default=Unbekannt resource.executable-properties-template=Vorlage für das Erstellen der ausführbaren Eigenschaftendatei -resource.setup-icon=Symbol für Dialogfeld "Setup" resource.post-msi-script=Auszuführendes Skript nach dem Erstellen der MSI-Datei für das EXE-Installationsprogramm resource.wxl-file=WiX-Lokalisierungsdatei resource.main-wix-file=Haupt-WiX-Projektdatei @@ -65,12 +59,10 @@ message.potential.windows.defender.issue=Warnung: Windows Defender verhindert ev message.outputting-to-location=EXE für Installationsprogramm wird generiert in: {0}. message.output-location=Installationsprogramm (.exe) gespeichert in: {0} message.tool-version=[{0}]-Version [{1}] erkannt. -message.creating-association-with-null-extension=Verknüpfung mit Nullerweiterung wird erstellt. message.wrong-tool-version=[{0}]-Version {1} wurde erkannt. Erforderlich ist jedoch Version {2}. message.use-wix36-features=WiX {0} erkannt. Erweiterte Bereinigungsaktion wird aktiviert. message.product-code=MSI-ProductCode: {0}. message.upgrade-code=MSI-UpgradeCode: {0}. message.preparing-msi-config=MSI-Konfiguration wird vorbereitet: {0}. message.generating-msi=MSI wird generiert: {0}. -message.invalid.install.dir=Warnung: Ungültiges Installationsverzeichnis {0}. Installationsverzeichnis muss ein relativer Unterpfad unter dem Standardinstallationsverzeichnis wie "Programme" sein. Der Anwendungsname "{1}" wird als Standardwert verwendet. diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties index 07604dc9980..119c7532b1f 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties @@ -23,15 +23,9 @@ # questions. # # - -app.bundler.name=Windowsアプリケーション・イメージ -exe.bundler.name=EXEインストーラ・パッケージ -msi.bundler.name=MSIインストーラ・パッケージ - param.menu-group.default=不明 resource.executable-properties-template=実行可能なプロパティ・ファイル作成用のテンプレート -resource.setup-icon=設定ダイアログ・アイコン resource.post-msi-script=exeインストーラのmsiファイルが作成された後に実行するスクリプト resource.wxl-file=WiXローカリゼーション・ファイル resource.main-wix-file=メインWiXプロジェクト・ファイル @@ -65,12 +59,10 @@ message.potential.windows.defender.issue=警告: Windows Defenderが原因でjpa message.outputting-to-location=インストーラのEXEを次に生成しています: {0} message.output-location=インストーラ(.exe)は次に保存されました: {0} message.tool-version=[{0}]バージョン[{1}]が検出されました。 -message.creating-association-with-null-extension=null拡張子との関連付けを作成しています。 message.wrong-tool-version=[{0}]バージョン{1}が検出されましたが、バージョン{2}が必要です。 message.use-wix36-features=WiX {0}が検出されました。拡張クリーンアップ・アクションを有効化しています。 message.product-code=MSI ProductCode: {0}。 message.upgrade-code=MSI UpgradeCode: {0}。 message.preparing-msi-config=MSI構成を準備しています: {0} message.generating-msi=MSIを生成しています: {0}。 -message.invalid.install.dir=警告: インストール・ディレクトリ{0}が無効です。インストール・ディレクトリはデフォルトのインストール場所("プログラム・ファイル"など)の下の相対サブパスである必要があります。アプリケーション名"{1}"にデフォルト設定されています。 diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties index 7eae69fba2f..66d8a9d8b96 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties @@ -23,15 +23,9 @@ # questions. # # - -app.bundler.name=Windows 应用程序映像 -exe.bundler.name=EXE 安装程序包 -msi.bundler.name=MSI 安装程序包 - param.menu-group.default=未知 resource.executable-properties-template=用于创建可执行属性文件的模板 -resource.setup-icon=设置对话框图标 resource.post-msi-script=在为 exe 安装程序创建 msi 文件之后要运行的脚本 resource.wxl-file=WiX 本地化文件 resource.main-wix-file=主 WiX 项目文件 @@ -65,12 +59,10 @@ message.potential.windows.defender.issue=警告:Windows Defender 可能会阻 message.outputting-to-location=正在为安装程序生成 EXE, 位置: {0}。 message.output-location=安装程序 (.exe) 已保存到: {0} message.tool-version=检测到 [{0}] 版本 [{1}]。 -message.creating-association-with-null-extension=正在使用空扩展名创建关联。 message.wrong-tool-version=检测到 [{0}] 版本 {1}, 但需要版本 {2}。 message.use-wix36-features=检测到 WiX {0}。正在启用高级清除操作。 message.product-code=MSI ProductCode:{0}。 message.upgrade-code=MSI UpgradeCode:{0}。 message.preparing-msi-config=正在准备 MSI 配置: {0}。 message.generating-msi=正在生成 MSI: {0}。 -message.invalid.install.dir=警告:安装目录 {0} 无效。安装目录应当是默认安装位置(如 "Program Files")下面的相对子路径。默认为应用程序名称 "{1}"。 From 2241218ef64ed6cb51f962f3ab6db1a766f1744f Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Tue, 16 Dec 2025 21:25:41 +0000 Subject: [PATCH 028/390] 8373631: Improve classes in the "jdk.jpackage.internal.util.function" package Reviewed-by: almatvee --- .../jdk/jpackage/internal/MacFromOptions.java | 12 +- .../jdk/jpackage/internal/TempKeychain.java | 4 +- .../jdk/jpackage/internal/AppImageFile.java | 2 +- .../jpackage/internal/PackagingPipeline.java | 2 +- .../jdk/jpackage/internal/cli/Main.java | 2 +- .../internal/cli/OptionsProcessor.java | 2 +- .../jdk/jpackage/internal/util/FileUtils.java | 5 +- .../jdk/jpackage/internal/util/Result.java | 61 +- .../jdk/jpackage/internal/util/XmlUtils.java | 6 +- .../internal/util/function/ExceptionBox.java | 64 +- .../util/function/ThrowingBiConsumer.java | 12 +- .../util/function/ThrowingBiFunction.java | 12 +- .../util/function/ThrowingConsumer.java | 12 +- .../util/function/ThrowingFunction.java | 12 +- .../util/function/ThrowingRunnable.java | 12 +- .../util/function/ThrowingSupplier.java | 12 +- .../util/function/ThrowingUnaryOperator.java | 12 +- .../internal/WinSystemEnvironment.java | 2 +- .../jdk/jpackage/test/AnnotationsTest.java | 6 +- .../jdk/jpackage/test/PackageTestTest.java | 6 +- .../jdk/jpackage/test/TKitTest.java | 11 +- .../jdk/jpackage/test/AdditionalLauncher.java | 4 +- .../jdk/jpackage/test/JPackageCommand.java | 22 +- .../jpackage/test/JPackageStringBundle.java | 6 +- .../jdk/jpackage/test/LauncherVerifier.java | 2 +- .../jdk/jpackage/test/LinuxHelper.java | 2 +- .../helpers/jdk/jpackage/test/MacHelper.java | 2 +- .../helpers/jdk/jpackage/test/MacSign.java | 19 +- .../jdk/jpackage/test/MacSignVerify.java | 4 +- .../helpers/jdk/jpackage/test/Main.java | 9 +- .../helpers/jdk/jpackage/test/MethodCall.java | 4 +- .../jdk/jpackage/test/ObjectMapper.java | 8 +- .../jdk/jpackage/test/PackageTest.java | 26 +- .../helpers/jdk/jpackage/test/TKit.java | 39 +- .../jdk/jpackage/test/TestBuilder.java | 16 +- .../jdk/jpackage/test/TestInstance.java | 18 +- .../test/WinExecutableIconVerifier.java | 6 +- .../jdk/jpackage/test/WindowsHelper.java | 4 +- .../internal/PackagingPipelineTest.java | 4 +- .../cli/OptionsValidationFailTest.java | 2 +- .../jpackage/internal/util/ResultTest.java | 602 ++++++++++++++++++ .../util/function/ExceptionBoxTest.java | 246 +++++++ .../util/function/FunctionalTest.java | 189 ++++++ .../tools/jdk/jpackage/test/JUnitAdapter.java | 6 +- .../tools/jpackage/linux/AppAboutUrlTest.java | 4 +- .../jpackage/macosx/CustomInfoPListTest.java | 12 +- .../jpackage/macosx/EntitlementsTest.java | 2 +- .../tools/jpackage/share/AppContentTest.java | 3 +- test/jdk/tools/jpackage/share/AsyncTest.java | 27 +- test/jdk/tools/jpackage/share/BasicTest.java | 4 +- test/jdk/tools/jpackage/share/IconTest.java | 4 +- .../tools/jpackage/share/InOutPathTest.java | 23 +- .../tools/jpackage/share/PerUserCfgTest.java | 4 +- .../jpackage/share/RuntimePackageTest.java | 4 +- .../jdk/tools/jpackage/share/ServiceTest.java | 4 +- 55 files changed, 1339 insertions(+), 261 deletions(-) create mode 100644 test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/ResultTest.java create mode 100644 test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/function/ExceptionBoxTest.java create mode 100644 test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/function/FunctionalTest.java diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacFromOptions.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacFromOptions.java index 074014dede0..b1094331740 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacFromOptions.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacFromOptions.java @@ -49,7 +49,7 @@ import static jdk.jpackage.internal.cli.StandardOption.PREDEFINED_RUNTIME_IMAGE; import static jdk.jpackage.internal.model.MacPackage.RUNTIME_BUNDLE_LAYOUT; import static jdk.jpackage.internal.model.StandardPackageType.MAC_DMG; import static jdk.jpackage.internal.model.StandardPackageType.MAC_PKG; -import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; +import static jdk.jpackage.internal.util.function.ExceptionBox.toUnchecked; import java.nio.file.Path; import java.util.Objects; @@ -106,7 +106,7 @@ final class MacFromOptions { final boolean sign = MAC_SIGN.findIn(options).orElse(false); final boolean appStore = MAC_APP_STORE.findIn(options).orElse(false); - final var appResult = Result.create(() -> createMacApplicationInternal(options)); + final var appResult = Result.of(() -> createMacApplicationInternal(options)); final Optional pkgBuilder; if (appResult.hasValue()) { @@ -146,18 +146,18 @@ final class MacFromOptions { final var expiredAppCertException = appResult.firstError().orElseThrow(); - final var pkgSignConfigResult = Result.create(signingIdentityBuilder::create); + final var pkgSignConfigResult = Result.of(signingIdentityBuilder::create); try { rethrowIfNotExpiredCertificateException(pkgSignConfigResult); // The certificate for the package signing config is also expired! } catch (RuntimeException ex) { // Some error occurred trying to configure the signing config for the package. // Ignore it, bail out with the first error. - rethrowUnchecked(expiredAppCertException); + throw toUnchecked(expiredAppCertException); } Log.error(pkgSignConfigResult.firstError().orElseThrow().getMessage()); - rethrowUnchecked(expiredAppCertException); + throw toUnchecked(expiredAppCertException); } } @@ -303,7 +303,7 @@ final class MacFromOptions { } } - rethrowUnchecked(ex); + throw toUnchecked(ex); } private static SigningIdentityBuilder createSigningIdentityBuilder(Options options) { diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/TempKeychain.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/TempKeychain.java index 97709678c67..b38faecd96f 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/TempKeychain.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/TempKeychain.java @@ -35,7 +35,7 @@ import jdk.jpackage.internal.util.function.ThrowingConsumer; final class TempKeychain implements Closeable { - static void withKeychains(ThrowingConsumer> keychainConsumer, List keychains) throws Throwable { + static void withKeychains(ThrowingConsumer, ? extends Exception> keychainConsumer, List keychains) throws Exception { keychains.forEach(Objects::requireNonNull); if (keychains.isEmpty() || OSVersion.current().compareTo(new OSVersion(10, 12)) < 0) { keychainConsumer.accept(keychains); @@ -47,7 +47,7 @@ final class TempKeychain implements Closeable { } } - static void withKeychain(ThrowingConsumer keychainConsumer, Keychain keychain) throws Throwable { + static void withKeychain(ThrowingConsumer keychainConsumer, Keychain keychain) throws Exception { Objects.requireNonNull(keychainConsumer); withKeychains(keychains -> { keychainConsumer.accept(keychains.getFirst()); diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java index b6b4322302e..5f473b554be 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java @@ -198,7 +198,7 @@ final class AppImageFile { } catch (XPathExpressionException ex) { // This should never happen as XPath expressions should be correct - throw ExceptionBox.rethrowUnchecked(ex); + throw ExceptionBox.toUnchecked(ex); } catch (SAXException ex) { // Malformed input XML throw new JPackageException(I18N.format("error.malformed-app-image-file", relativeAppImageFilePath, appImageDir), ex); diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PackagingPipeline.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PackagingPipeline.java index a2750fee260..2ee35b658ea 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PackagingPipeline.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PackagingPipeline.java @@ -508,7 +508,7 @@ final class PackagingPipeline { try { builder.create().call(); } catch (Exception ex) { - throw ExceptionBox.rethrowUnchecked(ex); + throw ExceptionBox.toUnchecked(ex); } } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/Main.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/Main.java index af51bc9fd98..57f627b1548 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/Main.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/Main.java @@ -110,7 +110,7 @@ public final class Main { Log.fatalError(I18N.format("ERR_CannotParseOptions", ex.getMessage())); return 1; } catch (IOException ex) { - throw ExceptionBox.rethrowUnchecked(ex); + throw ExceptionBox.toUnchecked(ex); } final var bundlingEnv = ServiceLoader.load(CliBundlingEnvironment.class, diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/OptionsProcessor.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/OptionsProcessor.java index 1bc5c36989f..54003b714a2 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/OptionsProcessor.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/cli/OptionsProcessor.java @@ -87,7 +87,7 @@ final class OptionsProcessor { final var untypedOptions = optionsBuilder.create(); // Create command line structure analyzer. - final var analyzerResult = Result.create(() -> new OptionsAnalyzer(untypedOptions, bundlingEnv)); + final var analyzerResult = Result.of(() -> new OptionsAnalyzer(untypedOptions, bundlingEnv)); if (analyzerResult.hasErrors()) { // Failed to derive the bundling operation from the command line. allErrors.addAll(analyzerResult.mapErrors().errors()); diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/FileUtils.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/FileUtils.java index 49c395642f4..2f7f2682a71 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/FileUtils.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/FileUtils.java @@ -37,7 +37,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; import jdk.internal.util.OperatingSystem; -import jdk.jpackage.internal.util.function.ExceptionBox; import jdk.jpackage.internal.util.function.ThrowingConsumer; public final class FileUtils { @@ -170,15 +169,13 @@ public final class FileUtils { } } - private void runActionOnPath(ThrowingConsumer action, Path path) { + private void runActionOnPath(ThrowingConsumer action, Path path) { try { action.accept(path); } catch (IOException ex) { if (this.ex == null) { this.ex = ex; } - } catch (Throwable t) { - throw ExceptionBox.rethrowUnchecked(t); } } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/Result.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/Result.java index 8a61acafe77..46e99f134df 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/Result.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/Result.java @@ -24,33 +24,28 @@ */ package jdk.jpackage.internal.util; -import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; - import java.util.Collection; import java.util.List; +import java.util.Objects; import java.util.Optional; import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; -import java.util.function.UnaryOperator; import java.util.stream.StreamSupport; +import jdk.jpackage.internal.util.function.ExceptionBox; +import jdk.jpackage.internal.util.function.ThrowingSupplier; public record Result(Optional value, Collection errors) { public Result { if (value.isEmpty() == errors.isEmpty()) { - throw new IllegalArgumentException(); + throw new IllegalArgumentException("'value' and 'errors' cannot both be non-empty or both be empty"); } - - if (value.isEmpty() && errors.isEmpty()) { - throw new IllegalArgumentException("Error collection must be non-empty"); - } - } public T orElseThrow() { firstError().ifPresent(ex -> { - rethrowUnchecked(ex); + throw ExceptionBox.toUnchecked(ex); }); return value.orElseThrow(); } @@ -64,7 +59,16 @@ public record Result(Optional value, Collection error } public Result map(Function conv) { - return new Result<>(value.map(conv), errors); + if (hasValue()) { + var mapped = value.map(conv); + if (mapped.isEmpty()) { + throw new NullPointerException(); + } else { + return new Result<>(mapped, errors); + } + } else { + return mapErrors(); + } } public Result flatMap(Function> conv) { @@ -73,12 +77,12 @@ public record Result(Optional value, Collection error }); } - public Result mapErrors(UnaryOperator> errorsMapper) { - return new Result<>(value, errorsMapper.apply(errors)); - } - + @SuppressWarnings("unchecked") public Result mapErrors() { - return new Result<>(Optional.empty(), errors); + if (hasValue()) { + throw new IllegalStateException("Can not map errors from a result without errors"); + } + return (Result)this; } public Result peekErrors(Consumer> consumer) { @@ -97,12 +101,31 @@ public record Result(Optional value, Collection error return errors.stream().findFirst(); } - public static Result create(Supplier supplier) { + public static Result of(Supplier supplier) { + return of(supplier::get, RuntimeException.class); + } + + public static Result of( + ThrowingSupplier supplier, Class supplierExceptionType) { + + Objects.requireNonNull(supplier); + Objects.requireNonNull(supplierExceptionType); + + T value; try { - return ofValue(supplier.get()); + value = supplier.get(); } catch (Exception ex) { - return ofError(ex); + if (supplierExceptionType.isInstance(ex)) { + return ofError(ex); + } else if (ex instanceof RuntimeException rex) { + throw rex; + } else { + // Unreachable because the `supplier` can throw exceptions of type or supertype `E` or runtime exceptions. + throw ExceptionBox.reachedUnreachable(); + } } + + return ofValue(value); } public static Result ofValue(T value) { diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java index c8761259254..f62ffee9260 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java @@ -24,7 +24,7 @@ */ package jdk.jpackage.internal.util; -import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; +import static jdk.jpackage.internal.util.function.ExceptionBox.toUnchecked; import java.io.IOException; import java.io.Writer; @@ -80,7 +80,7 @@ public final class XmlUtils { xml.flush(); xml.close(); } catch (XMLStreamException ex) { - throw rethrowUnchecked(ex); + throw toUnchecked(ex); } } @@ -101,7 +101,7 @@ public final class XmlUtils { xml.flush(); xml.close(); } catch (XMLStreamException ex) { - throw rethrowUnchecked(ex); + throw toUnchecked(ex); } } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ExceptionBox.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ExceptionBox.java index 8428d5d1e7f..40503469873 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ExceptionBox.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ExceptionBox.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 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 @@ -30,23 +30,55 @@ public class ExceptionBox extends RuntimeException { private static final long serialVersionUID = 1L; - public static RuntimeException rethrowUnchecked(Throwable throwable) { - if (throwable instanceof RuntimeException err) { - throw err; + public static RuntimeException toUnchecked(Exception ex) { + switch (ex) { + case RuntimeException rex -> { + return rex; + } + case InvocationTargetException itex -> { + var t = itex.getCause(); + if (t instanceof Exception cause) { + return toUnchecked(cause); + } else { + throw (Error)t; + } + } + case InterruptedException _ -> { + Thread.currentThread().interrupt(); + return new ExceptionBox(ex); + } + default -> { + return new ExceptionBox(ex); + } } - - if (throwable instanceof Error err) { - throw err; - } - - if (throwable instanceof InvocationTargetException err) { - throw rethrowUnchecked(err.getCause()); - } - - throw new ExceptionBox(throwable); } - private ExceptionBox(Throwable throwable) { - super(throwable); + public static Exception unbox(Throwable t) { + switch (t) { + case ExceptionBox ex -> { + return unbox(ex.getCause()); + } + case InvocationTargetException ex -> { + return unbox(ex.getCause()); + } + case Exception ex -> { + return ex; + } + case Error err -> { + throw err; + } + default -> { + // Unreachable + throw reachedUnreachable(); + } + } + } + + public static Error reachedUnreachable() { + return new AssertionError("Reached unreachable!"); + } + + private ExceptionBox(Exception ex) { + super(ex); } } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiConsumer.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiConsumer.java index 3ed0fd67d84..374eaf803d9 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiConsumer.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiConsumer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 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 @@ -27,17 +27,17 @@ package jdk.jpackage.internal.util.function; import java.util.function.BiConsumer; @FunctionalInterface -public interface ThrowingBiConsumer { +public interface ThrowingBiConsumer { - void accept(T t, U u) throws Throwable; + void accept(T t, U u) throws E; public static BiConsumer toBiConsumer( - ThrowingBiConsumer v) { + ThrowingBiConsumer v) { return (t, u) -> { try { v.accept(t, u); - } catch (Throwable ex) { - throw ExceptionBox.rethrowUnchecked(ex); + } catch (Exception ex) { + throw ExceptionBox.toUnchecked(ex); } }; } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiFunction.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiFunction.java index 8c2df773eb5..13b0b53c887 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiFunction.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiFunction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 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 @@ -27,17 +27,17 @@ package jdk.jpackage.internal.util.function; import java.util.function.BiFunction; @FunctionalInterface -public interface ThrowingBiFunction { +public interface ThrowingBiFunction { - R apply(T t, U u) throws Throwable; + R apply(T t, U u) throws E; public static BiFunction toBiFunction( - ThrowingBiFunction v) { + ThrowingBiFunction v) { return (t, u) -> { try { return v.apply(t, u); - } catch (Throwable ex) { - throw ExceptionBox.rethrowUnchecked(ex); + } catch (Exception ex) { + throw ExceptionBox.toUnchecked(ex); } }; } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingConsumer.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingConsumer.java index ef1b0a61df7..38342a361c0 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingConsumer.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingConsumer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 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 @@ -27,16 +27,16 @@ package jdk.jpackage.internal.util.function; import java.util.function.Consumer; @FunctionalInterface -public interface ThrowingConsumer { +public interface ThrowingConsumer { - void accept(T t) throws Throwable; + void accept(T t) throws E; - public static Consumer toConsumer(ThrowingConsumer v) { + public static Consumer toConsumer(ThrowingConsumer v) { return o -> { try { v.accept(o); - } catch (Throwable ex) { - throw ExceptionBox.rethrowUnchecked(ex); + } catch (Exception ex) { + throw ExceptionBox.toUnchecked(ex); } }; } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingFunction.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingFunction.java index 2b5eae43842..5bbfb254858 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingFunction.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingFunction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 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 @@ -27,16 +27,16 @@ package jdk.jpackage.internal.util.function; import java.util.function.Function; @FunctionalInterface -public interface ThrowingFunction { +public interface ThrowingFunction { - R apply(T t) throws Throwable; + R apply(T t) throws E; - public static Function toFunction(ThrowingFunction v) { + public static Function toFunction(ThrowingFunction v) { return t -> { try { return v.apply(t); - } catch (Throwable ex) { - throw ExceptionBox.rethrowUnchecked(ex); + } catch (Exception ex) { + throw ExceptionBox.toUnchecked(ex); } }; } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingRunnable.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingRunnable.java index 7c75c4d9753..f3ce5affbbf 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingRunnable.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingRunnable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 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 @@ -25,16 +25,16 @@ package jdk.jpackage.internal.util.function; @FunctionalInterface -public interface ThrowingRunnable { +public interface ThrowingRunnable { - void run() throws Throwable; + void run() throws E; - public static Runnable toRunnable(ThrowingRunnable v) { + public static Runnable toRunnable(ThrowingRunnable v) { return () -> { try { v.run(); - } catch (Throwable ex) { - throw ExceptionBox.rethrowUnchecked(ex); + } catch (Exception ex) { + throw ExceptionBox.toUnchecked(ex); } }; } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingSupplier.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingSupplier.java index c69c4729190..4f194a0f4d2 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingSupplier.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingSupplier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 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 @@ -27,16 +27,16 @@ package jdk.jpackage.internal.util.function; import java.util.function.Supplier; @FunctionalInterface -public interface ThrowingSupplier { +public interface ThrowingSupplier { - T get() throws Throwable; + T get() throws E; - public static Supplier toSupplier(ThrowingSupplier v) { + public static Supplier toSupplier(ThrowingSupplier v) { return () -> { try { return v.get(); - } catch (Throwable ex) { - throw ExceptionBox.rethrowUnchecked(ex); + } catch (Exception ex) { + throw ExceptionBox.toUnchecked(ex); } }; } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingUnaryOperator.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingUnaryOperator.java index 7a2a0fd67cf..3d757bbec48 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingUnaryOperator.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingUnaryOperator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 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 @@ -27,17 +27,17 @@ package jdk.jpackage.internal.util.function; import java.util.function.UnaryOperator; @FunctionalInterface -public interface ThrowingUnaryOperator { +public interface ThrowingUnaryOperator { - T apply(T t) throws Throwable; + T apply(T t) throws E; public static UnaryOperator toUnaryOperator( - ThrowingUnaryOperator v) { + ThrowingUnaryOperator v) { return t -> { try { return v.apply(t); - } catch (Throwable ex) { - throw ExceptionBox.rethrowUnchecked(ex); + } catch (Exception ex) { + throw ExceptionBox.toUnchecked(ex); } }; } diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinSystemEnvironment.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinSystemEnvironment.java index ab0cc37b9fe..c0bea444e00 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinSystemEnvironment.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinSystemEnvironment.java @@ -34,6 +34,6 @@ record WinSystemEnvironment(WixToolset wixToolset) implements SystemEnvironment } static Result create() { - return Result.create(WixTool::createToolset).map(WinSystemEnvironment::new); + return Result.of(WixTool::createToolset).map(WinSystemEnvironment::new); } } diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java index f88d1f81a34..42dd8eda19b 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java @@ -353,12 +353,12 @@ public class AnnotationsTest extends JUnitAdapter { try { log = captureJPackageTestLog(() -> Main.main(TestBuilder.build().workDirRoot(workDir), args)); assertRecordedTestDescs(expectedTestDescs); - } catch (Throwable t) { - t.printStackTrace(System.err); + } catch (Exception ex) { + ex.printStackTrace(System.err); System.exit(1); // Redundant, but needed to suppress "The local variable log may not have been initialized" error. - throw new RuntimeException(t); + throw new RuntimeException(ex); } final var actualTestCount = Integer.parseInt(log.stream().dropWhile(line -> { diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/PackageTestTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/PackageTestTest.java index 4723f4dadbd..16909d0eb40 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/PackageTestTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/PackageTestTest.java @@ -168,7 +168,7 @@ public class PackageTestTest extends JUnitAdapter { protected final int expectedTicks; } - private static class CountingConsumer extends TickCounter implements ThrowingConsumer { + private static class CountingConsumer extends TickCounter implements ThrowingConsumer { @Override public void accept(JPackageCommand cmd) { @@ -188,7 +188,7 @@ public class PackageTestTest extends JUnitAdapter { private final String label; } - private static class CountingRunnable extends TickCounter implements ThrowingRunnable { + private static class CountingRunnable extends TickCounter implements ThrowingRunnable { @Override public void run() { @@ -208,7 +208,7 @@ public class PackageTestTest extends JUnitAdapter { private final String label; } - private static class CountingBundleVerifier extends TickCounter implements ThrowingBiConsumer { + private static class CountingBundleVerifier extends TickCounter implements ThrowingBiConsumer { @Override public void accept(JPackageCommand cmd, Executor.Result result) { diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/TKitTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/TKitTest.java index 590f23b002d..00172791ad8 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/TKitTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/TKitTest.java @@ -25,6 +25,7 @@ package jdk.jpackage.test; import static jdk.jpackage.internal.util.function.ThrowingRunnable.toRunnable; import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; +import java.io.IOException; import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Path; @@ -212,13 +213,13 @@ public class TKitTest extends JUnitAdapter { @Test @ParameterSupplier("testCreateTempPath") - public void testCreateTempFile(CreateTempTestSpec testSpec) throws Throwable { + public void testCreateTempFile(CreateTempTestSpec testSpec) throws IOException { testSpec.test(TKit::createTempFile, TKit::assertFileExists); } @Test @ParameterSupplier("testCreateTempPath") - public void testCreateTempDirectory(CreateTempTestSpec testSpec) throws Throwable { + public void testCreateTempDirectory(CreateTempTestSpec testSpec) throws IOException { testSpec.test(TKit::createTempDirectory, TKit::assertDirectoryEmpty); } @@ -232,7 +233,7 @@ public class TKitTest extends JUnitAdapter { } } - void test(ThrowingFunction createTempPath, Consumer assertTempPathExists) throws Throwable { + void test(ThrowingFunction createTempPath, Consumer assertTempPathExists) throws IOException { for (var existingFile : existingFiles) { existingFile = TKit.workDir().resolve(existingFile); @@ -333,14 +334,14 @@ public class TKitTest extends JUnitAdapter { }).toList(); } - private static void runAssertWithExpectedLogOutput(ThrowingRunnable action, + private static void runAssertWithExpectedLogOutput(ThrowingRunnable action, boolean expectFail, String... expectLogStrings) { runWithExpectedLogOutput(() -> { TKit.assertAssert(!expectFail, toRunnable(action)); }, expectLogStrings); } - private static void runWithExpectedLogOutput(ThrowingRunnable action, + private static void runWithExpectedLogOutput(ThrowingRunnable action, String... expectLogStrings) { final var output = JUnitAdapter.captureJPackageTestLog(action); if (output.size() == 1 && expectLogStrings.length == 1) { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java index 95373fa0d61..8ce3f4d2948 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java @@ -152,7 +152,7 @@ public final class AdditionalLauncher { } public AdditionalLauncher setPersistenceHandler( - ThrowingBiConsumer>> handler) { + ThrowingBiConsumer>, ? extends Exception> handler) { if (handler != null) { createFileHandler = ThrowingBiConsumer.toBiConsumer(handler); } else { @@ -182,7 +182,7 @@ public final class AdditionalLauncher { Optional.ofNullable(defaultArguments), Optional.ofNullable(icon), rawProperties); } - private ThrowingConsumer createVerifierAsConsumer() { + private ThrowingConsumer createVerifierAsConsumer() { return cmd -> { createVerifier().verify(cmd, verifyActions.stream().sorted(Comparator.comparing(Action::ordinal)).toArray(Action[]::new)); }; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index 197e835ed8d..f80f1e61cd3 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -291,7 +291,7 @@ public class JPackageCommand extends CommandArguments { public JPackageCommand setFakeRuntime() { verifyMutable(); - ThrowingConsumer createBulkFile = path -> { + ThrowingConsumer createBulkFile = path -> { Files.createDirectories(path.getParent()); try (FileOutputStream out = new FileOutputStream(path.toFile())) { byte[] bytes = new byte[4 * 1024]; @@ -328,12 +328,12 @@ public class JPackageCommand extends CommandArguments { .removeArgumentWithValue("--input"); } - JPackageCommand addPrerequisiteAction(ThrowingConsumer action) { + JPackageCommand addPrerequisiteAction(ThrowingConsumer action) { prerequisiteActions.add(action); return this; } - JPackageCommand addVerifyAction(ThrowingConsumer action) { + JPackageCommand addVerifyAction(ThrowingConsumer action) { return addVerifyAction(action, ActionRole.DEFAULT); } @@ -343,12 +343,12 @@ public class JPackageCommand extends CommandArguments { ; } - JPackageCommand addVerifyAction(ThrowingConsumer action, ActionRole actionRole) { + JPackageCommand addVerifyAction(ThrowingConsumer action, ActionRole actionRole) { verifyActions.add(action, actionRole); return this; } - Stream> getVerifyActionsWithRole(ActionRole actionRole) { + Stream> getVerifyActionsWithRole(ActionRole actionRole) { return verifyActions.actionsWithRole(actionRole); } @@ -1648,16 +1648,16 @@ public class JPackageCommand extends CommandArguments { actions.addAll(other.actions); } - void add(ThrowingConsumer action) { + void add(ThrowingConsumer action) { add(action, ActionRole.DEFAULT); } - void add(ThrowingConsumer action, ActionRole role) { + void add(ThrowingConsumer action, ActionRole role) { verifyMutable(); actions.add(new Action(action, role)); } - Stream> actionsWithRole(ActionRole role) { + Stream> actionsWithRole(ActionRole role) { Objects.requireNonNull(role); return actions.stream().filter(action -> { return Objects.equals(action.role(), role); @@ -1666,7 +1666,7 @@ public class JPackageCommand extends CommandArguments { private static final class Action implements Consumer { - Action(ThrowingConsumer impl, ActionRole role) { + Action(ThrowingConsumer impl, ActionRole role) { this.impl = Objects.requireNonNull(impl); this.role = Objects.requireNonNull(role); } @@ -1675,7 +1675,7 @@ public class JPackageCommand extends CommandArguments { return role; } - ThrowingConsumer impl() { + ThrowingConsumer impl() { return impl; } @@ -1688,7 +1688,7 @@ public class JPackageCommand extends CommandArguments { } private final ActionRole role; - private final ThrowingConsumer impl; + private final ThrowingConsumer impl; private boolean executed; } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java index cdf2855faef..9425b84472c 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java @@ -26,7 +26,7 @@ package jdk.jpackage.test; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.MessageFormat; -import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; +import static jdk.jpackage.internal.util.function.ExceptionBox.toUnchecked; public enum JPackageStringBundle { @@ -40,7 +40,7 @@ public enum JPackageStringBundle { i18nClass_getString = i18nClass.getDeclaredMethod("getString", String.class); i18nClass_getString.setAccessible(true); } catch (ClassNotFoundException|NoSuchMethodException ex) { - throw rethrowUnchecked(ex); + throw toUnchecked(ex); } } @@ -51,7 +51,7 @@ public enum JPackageStringBundle { try { return (String)i18nClass_getString.invoke(i18nClass, key); } catch (IllegalAccessException|InvocationTargetException ex) { - throw rethrowUnchecked(ex); + throw toUnchecked(ex); } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.java index 89468ef7f86..15d96311d98 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherVerifier.java @@ -102,7 +102,7 @@ public final class LauncherVerifier { EXECUTE_LAUNCHER(LauncherVerifier::executeLauncher), ; - Action(ThrowingBiConsumer action) { + Action(ThrowingBiConsumer action) { this.action = ThrowingBiConsumer.toBiConsumer(action); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java index e795f7c9760..3b02a3f6a69 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java @@ -645,7 +645,7 @@ public final class LinuxHelper { } private static void withTestFileAssociationsFile(FileAssociations fa, - ThrowingConsumer consumer) { + ThrowingConsumer consumer) { boolean iterated[] = new boolean[] { false }; PackageTest.withFileAssociationsTestRuns(fa, (testRun, testFiles) -> { if (!iterated[0]) { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java index caeb0a206fc..678d25e4007 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java @@ -78,7 +78,7 @@ import org.xml.sax.SAXException; public final class MacHelper { public static void withExplodedDmg(JPackageCommand cmd, - ThrowingConsumer consumer) { + ThrowingConsumer consumer) { cmd.verifyIsOfType(PackageType.MAC_DMG); // Explode DMG assuming this can require interaction, thus use `yes`. diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSign.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSign.java index 7d2bb908edb..15249c51887 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSign.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSign.java @@ -42,6 +42,7 @@ import java.nio.file.Path; import java.nio.file.StandardCopyOption; import java.nio.file.StandardOpenOption; import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateExpiredException; import java.security.cert.CertificateFactory; import java.security.cert.CertificateNotYetValidException; @@ -526,7 +527,7 @@ public final class MacSign { private record CertificateStats(List allResolvedCertificateRequests, List knownCertificateRequests, - Map unmappedCertificates) { + Map unmappedCertificates) { static CertificateStats get(KeychainWithCertsSpec spec) { return CACHE.computeIfAbsent(spec, CertificateStats::create); @@ -560,7 +561,7 @@ public final class MacSign { private static CertificateStats create(KeychainWithCertsSpec spec) { final var allCertificates = spec.keychain().findCertificates(); final List allResolvedCertificateRequests = new ArrayList<>(); - final Map unmappedCertificates = new HashMap<>(); + final Map unmappedCertificates = new HashMap<>(); withTempDirectory(workDir -> { for (final var cert : allCertificates) { @@ -568,13 +569,7 @@ public final class MacSign { try { resolvedCertificateRequest = new ResolvedCertificateRequest(cert); } catch (RuntimeException ex) { - final Throwable t; - if (ex instanceof ExceptionBox) { - t = ex.getCause(); - } else { - t = ex; - } - unmappedCertificates.put(cert, t); + unmappedCertificates.put(cert, ExceptionBox.unbox(ex)); continue; } @@ -635,13 +630,13 @@ public final class MacSign { SHA1(20, () -> MessageDigest.getInstance("SHA-1")), SHA256(32, () -> MessageDigest.getInstance("SHA-256")); - DigestAlgorithm(int hashLength, ThrowingSupplier createDigest) { + DigestAlgorithm(int hashLength, ThrowingSupplier createDigest) { this.hashLength = hashLength; this.createDigest = createDigest; } final int hashLength; - final ThrowingSupplier createDigest; + final ThrowingSupplier createDigest; } public record CertificateHash(byte[] value, DigestAlgorithm alg) { @@ -1223,7 +1218,7 @@ public final class MacSign { }).map(KeychainWithCertsSpec::keychain); } - private static void withTempDirectory(ThrowingConsumer callback) { + private static void withTempDirectory(ThrowingConsumer callback) { try { final var dir = Files.createTempDirectory("jdk.jpackage.test"); try { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSignVerify.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSignVerify.java index 123fba56b71..1f37829791e 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSignVerify.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacSignVerify.java @@ -262,8 +262,8 @@ public final class MacSignVerify { signIdentities.add(new SignIdentity(name, fingerprint)); } while (lineIt.hasNext()); return signIdentities; - } catch (Throwable t) { - t.printStackTrace(); + } catch (Exception ex) { + ex.printStackTrace(); reportUnexpectedCommandOutcome(exec.getPrintableCommandLine(), result); return null; // Unreachable } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java index fa8fe166f5a..fee5b65c897 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java @@ -37,15 +37,16 @@ import java.util.List; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Stream; +import jdk.jpackage.internal.util.function.ExceptionBox; public final class Main { - public static void main(String... args) throws Throwable { + public static void main(String... args) throws Exception { main(TestBuilder.build(), args); } - public static void main(TestBuilder.Builder builder, String... args) throws Throwable { + public static void main(TestBuilder.Builder builder, String... args) throws Exception { boolean listTests = false; List tests = new ArrayList<>(); try (TestBuilder testBuilder = builder.testConsumer(tests::add).create()) { @@ -86,8 +87,8 @@ public final class Main { try { testBuilder.processCmdLineArg(arg); success = true; - } catch (Throwable throwable) { - TKit.unbox(throwable); + } catch (Exception ex) { + throw ExceptionBox.unbox(ex); } finally { if (!success) { TKit.log(String.format("Error processing parameter=[%s]", arg)); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java index 73d0a7fe495..b27531d0572 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java @@ -40,7 +40,7 @@ import java.util.stream.Stream; import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.test.TestInstance.TestDesc; -class MethodCall implements ThrowingConsumer { +class MethodCall implements ThrowingConsumer { MethodCall(Object[] instanceCtorArgs, Method method, Object ... args) { Objects.requireNonNull(instanceCtorArgs); @@ -107,7 +107,7 @@ class MethodCall implements ThrowingConsumer { } @Override - public void accept(Object thiz) throws Throwable { + public void accept(Object thiz) throws Exception { method.invoke(thiz, methodArgs); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ObjectMapper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ObjectMapper.java index f35e255951e..126d0e07f00 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ObjectMapper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ObjectMapper.java @@ -24,7 +24,7 @@ package jdk.jpackage.test; import static java.util.stream.Collectors.groupingBy; import static java.util.stream.Collectors.toSet; -import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; +import static jdk.jpackage.internal.util.function.ExceptionBox.toUnchecked; import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer; import static jdk.jpackage.internal.util.function.ThrowingRunnable.toRunnable; import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; @@ -283,7 +283,7 @@ public final class ObjectMapper { try { return m.invoke(obj); } catch (IllegalAccessException ex) { - throw rethrowUnchecked(ex); + throw toUnchecked(ex); } catch (InvocationTargetException ex) { return map(ex.getTargetException()); } @@ -724,7 +724,7 @@ public final class ObjectMapper { } xml.writeEndElement(); } catch (Exception ex) { - rethrowUnchecked(ex); + throw toUnchecked(ex); } } @@ -740,7 +740,7 @@ public final class ObjectMapper { } xml.writeEndElement(); } catch (Exception ex) { - rethrowUnchecked(ex); + throw toUnchecked(ex); } } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java index 5b3815510ce..2e4f11d056f 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java @@ -22,7 +22,7 @@ */ package jdk.jpackage.test; -import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; +import static jdk.jpackage.internal.util.function.ExceptionBox.toUnchecked; import static jdk.jpackage.internal.util.function.ThrowingBiConsumer.toBiConsumer; import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer; import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; @@ -143,7 +143,7 @@ public final class PackageTest extends RunnablePackageTest { return this; } - private PackageTest addInitializer(ThrowingConsumer v, String id) { + private PackageTest addInitializer(ThrowingConsumer v, String id) { Objects.requireNonNull(v); if (id != null) { if (namedInitializers.contains(id)) { @@ -156,11 +156,11 @@ public final class PackageTest extends RunnablePackageTest { return this; } - private PackageTest addRunOnceInitializer(ThrowingRunnable v, String id) { + private PackageTest addRunOnceInitializer(ThrowingRunnable v, String id) { Objects.requireNonNull(v); - return addInitializer(new ThrowingConsumer() { + return addInitializer(new ThrowingConsumer() { @Override - public void accept(JPackageCommand unused) throws Throwable { + public void accept(JPackageCommand unused) throws Exception { if (!executed) { executed = true; v.run(); @@ -171,21 +171,21 @@ public final class PackageTest extends RunnablePackageTest { }, id); } - public PackageTest addInitializer(ThrowingConsumer v) { + public PackageTest addInitializer(ThrowingConsumer v) { return addInitializer(v, null); } - public PackageTest addRunOnceInitializer(ThrowingRunnable v) { + public PackageTest addRunOnceInitializer(ThrowingRunnable v) { return addRunOnceInitializer(v, null); } - public PackageTest addBundleVerifier(ThrowingBiConsumer v) { + public PackageTest addBundleVerifier(ThrowingBiConsumer v) { Objects.requireNonNull(v); currentTypes.forEach(type -> handlers.get(type).addBundleVerifier(toBiConsumer(v))); return this; } - public PackageTest addBundleVerifier(ThrowingConsumer v) { + public PackageTest addBundleVerifier(ThrowingConsumer v) { Objects.requireNonNull(v); return addBundleVerifier((cmd, unused) -> toConsumer(v).accept(cmd)); } @@ -222,13 +222,13 @@ public final class PackageTest extends RunnablePackageTest { return this; } - public PackageTest addInstallVerifier(ThrowingConsumer v) { + public PackageTest addInstallVerifier(ThrowingConsumer v) { currentTypes.forEach(type -> handlers.get(type).addInstallVerifier( toConsumer(v))); return this; } - public PackageTest addUninstallVerifier(ThrowingConsumer v) { + public PackageTest addUninstallVerifier(ThrowingConsumer v) { currentTypes.forEach(type -> handlers.get(type).addUninstallVerifier( toConsumer(v))); return this; @@ -259,7 +259,7 @@ public final class PackageTest extends RunnablePackageTest { } static void withFileAssociationsTestRuns(FileAssociations fa, - ThrowingBiConsumer> consumer) { + ThrowingBiConsumer, ? extends Exception> consumer) { Objects.requireNonNull(consumer); for (var testRun : fa.getTestRuns()) { TKit.withTempDirectory("fa-test-files", tempDir -> { @@ -860,7 +860,7 @@ public final class PackageTest extends RunnablePackageTest { "Check the package has %d top installation directories", expectedRootCount)); } catch (IOException ex) { - rethrowUnchecked(ex); + throw toUnchecked(ex); } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java index 0afdf31ec68..90c73f97106 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java @@ -33,7 +33,6 @@ import java.io.Closeable; import java.io.IOException; import java.io.PrintStream; import java.io.UncheckedIOException; -import java.lang.reflect.InvocationTargetException; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.LinkOption; @@ -110,7 +109,7 @@ public final class TKit { throw throwUnknownPlatformError(); }).get(); - static void withExtraLogStream(ThrowingRunnable action) { + static void withExtraLogStream(ThrowingRunnable action) { if (state().extraLogStream != null) { ThrowingRunnable.toRunnable(action).run(); } else { @@ -120,19 +119,19 @@ public final class TKit { } } - static void withExtraLogStream(ThrowingRunnable action, PrintStream logStream) { + static void withExtraLogStream(ThrowingRunnable action, PrintStream logStream) { withNewState(action, stateBuilder -> { stateBuilder.extraLogStream(logStream); }); } - public static void withMainLogStream(ThrowingRunnable action, PrintStream logStream) { + public static void withMainLogStream(ThrowingRunnable action, PrintStream logStream) { withNewState(action, stateBuilder -> { stateBuilder.mainLogStream(logStream); }); } - public static void withStackTraceStream(ThrowingRunnable action, PrintStream logStream) { + public static void withStackTraceStream(ThrowingRunnable action, PrintStream logStream) { withNewState(action, stateBuilder -> { stateBuilder.stackTraceStream(logStream); }); @@ -146,7 +145,7 @@ public final class TKit { STATE.set(Objects.requireNonNull(v)); } - private static void withNewState(ThrowingRunnable action, Consumer stateBuilderMutator) { + private static void withNewState(ThrowingRunnable action, Consumer stateBuilderMutator) { Objects.requireNonNull(action); Objects.requireNonNull(stateBuilderMutator); @@ -198,7 +197,7 @@ public final class TKit { }); } - static T runAdhocTest(ThrowingSupplier action) { + static T runAdhocTest(ThrowingSupplier action) { final List box = new ArrayList<>(); runAdhocTest(() -> { box.add(action.get()); @@ -206,7 +205,7 @@ public final class TKit { return box.getFirst(); } - static void runAdhocTest(ThrowingRunnable action) { + static void runAdhocTest(ThrowingRunnable action) { Objects.requireNonNull(action); final Path workDir = toSupplier(() -> Files.createTempDirectory("jdk.jpackage-test")).get(); @@ -227,28 +226,20 @@ public final class TKit { runTests(List.of(test), Set.of(RunTestMode.FAIL_FAST)); } - static Runnable ignoreExceptions(ThrowingRunnable action) { + static Runnable ignoreExceptions(ThrowingRunnable action) { return () -> { try { try { action.run(); - } catch (Throwable ex) { - unbox(ex); + } catch (Exception ex) { + throw ExceptionBox.unbox(ex); } - } catch (Throwable throwable) { - printStackTrace(throwable); + } catch (Exception | AssertionError t) { + printStackTrace(t); } }; } - static void unbox(Throwable throwable) throws Throwable { - try { - throw throwable; - } catch (ExceptionBox | InvocationTargetException ex) { - unbox(ex.getCause()); - } - } - public static Path workDir() { return currentTest().workDir(); } @@ -440,7 +431,7 @@ public final class TKit { return createTempPath(role, Files::createFile); } - private static Path createTempPath(Path templatePath, ThrowingUnaryOperator createPath) { + private static Path createTempPath(Path templatePath, ThrowingUnaryOperator createPath) { if (templatePath.isAbsolute()) { throw new IllegalArgumentException(); } @@ -458,13 +449,11 @@ public final class TKit { return createPath.apply(path); } catch (IOException ex) { throw new UncheckedIOException(ex); - } catch (Throwable t) { - throw ExceptionBox.rethrowUnchecked(t); } } public static Path withTempDirectory(String role, - ThrowingConsumer action) { + ThrowingConsumer action) { final Path tempDir = ThrowingSupplier.toSupplier( () -> createTempDirectory(role)).get(); boolean keepIt = true; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java index 4009fe2f687..5f4547c701e 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java @@ -128,7 +128,7 @@ final class TestBuilder implements AutoCloseable { clear(); } - void processCmdLineArg(String arg) throws Throwable { + void processCmdLineArg(String arg) throws Exception { int separatorIdx = arg.indexOf('='); final String argName; final String argValue; @@ -140,7 +140,7 @@ final class TestBuilder implements AutoCloseable { argValue = null; } try { - ThrowingConsumer argProcessor = argProcessors.get(argName); + var argProcessor = argProcessors.get(argName); if (argProcessor == null) { throw new ParseException("Unrecognized"); } @@ -205,8 +205,8 @@ final class TestBuilder implements AutoCloseable { } private void createTestInstance(MethodCall testBody) { - final List> curBeforeActions; - final List> curAfterActions; + final List> curBeforeActions; + final List> curAfterActions; Method testMethod = testBody.getMethod(); if (Stream.of(BeforeEach.class, AfterEach.class).anyMatch( @@ -326,7 +326,7 @@ final class TestBuilder implements AutoCloseable { } // Wraps Method.invoke() into ThrowingRunnable.run() - private ThrowingConsumer wrap(Method method) { + private ThrowingConsumer wrap(Method method) { return (test) -> { Class methodClass = method.getDeclaringClass(); String methodName = String.join(".", methodClass.getName(), @@ -375,13 +375,13 @@ final class TestBuilder implements AutoCloseable { } private final TestMethodSupplier testMethodSupplier; - private final Map> argProcessors; + private final Map> argProcessors; private final Consumer testConsumer; private final Path workDirRoot; private final ClassLoader testClassLoader; private List testGroup; - private List> beforeActions; - private List> afterActions; + private List> beforeActions; + private List> afterActions; private Set excludedTests; private Set includedTests; private String spaceSubstitute; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java index 4445a194ee7..3c622200249 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java @@ -46,7 +46,7 @@ import jdk.jpackage.internal.util.function.ThrowingFunction; import jdk.jpackage.internal.util.function.ThrowingRunnable; import jdk.jpackage.internal.util.function.ThrowingSupplier; -final class TestInstance implements ThrowingRunnable { +final class TestInstance implements ThrowingRunnable { static final class TestDesc { private TestDesc(Class clazz, String functionName, String functionArgs, String instanceArgs) { @@ -149,7 +149,7 @@ final class TestInstance implements ThrowingRunnable { private final String instanceArgs; } - TestInstance(ThrowingRunnable testBody, Path workDirRoot) { + TestInstance(ThrowingRunnable testBody, Path workDirRoot) { assertCount = 0; this.testConstructor = (unused) -> null; this.testBody = (unused) -> testBody.run(); @@ -160,8 +160,8 @@ final class TestInstance implements ThrowingRunnable { this.workDir = workDirRoot.resolve(createWorkDirPath(testDesc)); } - TestInstance(MethodCall testBody, List> beforeActions, - List> afterActions, boolean dryRun, Path workDirRoot) { + TestInstance(MethodCall testBody, List> beforeActions, + List> afterActions, boolean dryRun, Path workDirRoot) { assertCount = 0; this.testConstructor = v -> ((MethodCall)v).newInstance(); this.testBody = testBody; @@ -226,7 +226,7 @@ final class TestInstance implements ThrowingRunnable { } @Override - public void run() throws Throwable { + public void run() throws Exception { final String fullName = fullName(); TKit.log(String.format("[ RUN ] %s", fullName)); try { @@ -333,10 +333,10 @@ final class TestInstance implements ThrowingRunnable { private Status status; private RuntimeException skippedTestException; private final TestDesc testDesc; - private final ThrowingFunction, Object> testConstructor; - private final ThrowingConsumer testBody; - private final List> beforeActions; - private final List> afterActions; + private final ThrowingFunction, Object, ? extends Exception> testConstructor; + private final ThrowingConsumer testBody; + private final List> beforeActions; + private final List> afterActions; private final boolean dryRun; private final Path workDir; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WinExecutableIconVerifier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WinExecutableIconVerifier.java index 5110259e6f3..f4468fa9ab0 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WinExecutableIconVerifier.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WinExecutableIconVerifier.java @@ -22,7 +22,7 @@ */ package jdk.jpackage.test; -import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; +import static jdk.jpackage.internal.util.function.ExceptionBox.toUnchecked; import java.awt.image.BufferedImage; import java.io.IOException; @@ -195,7 +195,7 @@ public final class WinExecutableIconVerifier { iconSwap.setAccessible(true); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException ex) { - throw rethrowUnchecked(ex); + throw toUnchecked(ex); } } @@ -268,7 +268,7 @@ public final class WinExecutableIconVerifier { } } } catch (IllegalAccessException | InvocationTargetException ex) { - throw rethrowUnchecked(ex); + throw toUnchecked(ex); } } finally { executable.toFile().setWritable(false, true); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java index 5e97b0d2dde..72b5dbc578b 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java @@ -22,7 +22,7 @@ */ package jdk.jpackage.test; -import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; +import static jdk.jpackage.internal.util.function.ExceptionBox.toUnchecked; import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; import java.io.IOException; @@ -634,7 +634,7 @@ public class WindowsHelper { getShortPathWrapper.setAccessible(true); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException ex) { - throw rethrowUnchecked(ex); + throw toUnchecked(ex); } } diff --git a/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/PackagingPipelineTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/PackagingPipelineTest.java index 8168b876d2f..721e0802d16 100644 --- a/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/PackagingPipelineTest.java +++ b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/PackagingPipelineTest.java @@ -23,7 +23,7 @@ package jdk.jpackage.internal; -import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; +import static jdk.jpackage.internal.util.function.ExceptionBox.toUnchecked; import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer; import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -412,7 +412,7 @@ public class PackagingPipelineTest { final var expectedException = new Exception("foo"); final var ex = testExceptionRethrow(expectedException, ExceptionBox.class, () -> { - rethrowUnchecked(expectedException); + throw toUnchecked(expectedException); }); assertSame(expectedException, ex.getCause()); } diff --git a/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/cli/OptionsValidationFailTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/cli/OptionsValidationFailTest.java index a46cb20815f..ee261dfe8a8 100644 --- a/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/cli/OptionsValidationFailTest.java +++ b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/cli/OptionsValidationFailTest.java @@ -160,7 +160,7 @@ public class OptionsValidationFailTest { } @TestFactory - Stream getTestCasesFromErrorTest() throws Throwable { + Stream getTestCasesFromErrorTest() throws Exception { final var jpackageTestsUnnamedModule = JUnitAdapter.class.getModule(); final var testClassloader = new InMemoryClassLoader(Stream.of( diff --git a/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/ResultTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/ResultTest.java new file mode 100644 index 00000000000..ca8f7aad102 --- /dev/null +++ b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/ResultTest.java @@ -0,0 +1,602 @@ +/* + * Copyright (c) 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.jpackage.internal.util; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Function; +import jdk.jpackage.internal.util.function.ExceptionBox; +import jdk.jpackage.internal.util.function.ThrowingSupplier; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; + +public class ResultTest { + + @Test + public void test_ctor_with_value() { + var result = new Result(Optional.of("foo"), List.of()); + + assertTrue(result.hasValue()); + assertFalse(result.hasErrors()); + assertEquals(Optional.of("foo"), result.value()); + assertEquals(List.of(), result.errors()); + assertEquals(Optional.empty(), result.firstError()); + } + + @Test + public void test_ctor_with_errors() { + var ex = new Exception("Kaput!"); + var result = new Result(Optional.empty(), List.of(ex)); + + assertFalse(result.hasValue()); + assertTrue(result.hasErrors()); + assertEquals(Optional.empty(), result.value()); + assertEquals(List.of(ex), result.errors()); + assertEquals(Optional.of(ex), result.firstError()); + } + + @Test + public void test_ctor_invalid_npe() { + assertThrowsExactly(NullPointerException.class, () -> { + new Result(Optional.of("foo"), null); + }); + + assertThrowsExactly(NullPointerException.class, () -> { + new Result(null, List.of(new Exception())); + }); + + assertThrowsExactly(NullPointerException.class, () -> { + new Result(null, null); + }); + } + + @Test + public void test_ctor_invalid_both_empty() { + var ex = assertThrowsExactly(IllegalArgumentException.class, () -> { + new Result(Optional.empty(), List.of()); + }); + assertEquals("'value' and 'errors' cannot both be non-empty or both be empty", ex.getMessage()); + } + + @Test + public void test_ctor_invalid_both_non_empty() { + var ex = assertThrowsExactly(IllegalArgumentException.class, () -> { + new Result(Optional.of("foo"), List.of(new Exception())); + }); + assertEquals("'value' and 'errors' cannot both be non-empty or both be empty", ex.getMessage()); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_ofValue(boolean valid) { + if (valid) { + assertTrue(Result.ofValue("foo").hasValue()); + } else { + assertThrowsExactly(NullPointerException.class, () -> { + Result.ofValue(null); + }); + } + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_ofError(boolean valid) { + if (valid) { + var err = new Exception("foo"); + var result = Result.ofError(err); + assertEquals(List.of(err), result.errors()); + } else { + assertThrowsExactly(NullPointerException.class, () -> { + Result.ofError(null); + }); + } + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_ofErrors(boolean valid) { + if (valid) { + var errors = List.of(new Exception("foo"), new IllegalArgumentException("bar")); + var result = Result.ofErrors(errors); + assertSame(errors, result.errors()); + } else { + assertThrowsExactly(NullPointerException.class, () -> { + Result.ofErrors(null); + }); + + assertThrowsExactly(NullPointerException.class, () -> { + var errors = new ArrayList(); + errors.add(new Exception()); + errors.add(null); + Result.ofErrors(errors); + }); + } + } + + @Test + public void test_of() { + assertEquals("foo", Result.of(() -> { + return "foo"; + }).orElseThrow()); + } + + @Test + public void test_of_null_value() { + assertThrowsExactly(NullPointerException.class, () -> { + Result.of(() -> { + return null; + }); + }); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_of_throws(boolean declaredExceptionType) { + + Exception cause; + if (declaredExceptionType) { + cause = new IOException("foo"); + } else { + cause = new UnsupportedOperationException("bar"); + } + + ThrowingSupplier supplier = () -> { + if (declaredExceptionType) { + throw (IOException)cause; + } else { + throw (UnsupportedOperationException)cause; + } + }; + + if (declaredExceptionType) { + var result = Result.of(supplier, IOException.class); + assertSame(cause, result.firstError().orElseThrow()); + assertEquals(1, result.errors().size()); + } else { + var ex = assertThrowsExactly(cause.getClass(), () -> { + Result.of(supplier, IOException.class); + }); + assertSame(cause, ex); + } + } + + @Test + public void test_orElseThrow_hasValue() { + assertEquals("foo", Result.ofValue("foo").orElseThrow()); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_orElseThrow(boolean uncheckedException) { + Exception ex; + Class expectedType; + if (uncheckedException) { + ex = new RuntimeException("Kaput!"); + expectedType = ex.getClass(); + } else { + ex = new Exception("Kaput!"); + expectedType = ExceptionBox.class; + } + + var actual = assertThrowsExactly(expectedType, Result.ofError(ex)::orElseThrow); + + if (uncheckedException) { + assertSame(ex, actual); + } else { + assertSame(ex, actual.getCause()); + } + } + + @ParameterizedTest + @MethodSource + public void test_map_and_flatMap(MapTestSpec spec) { + spec.run(); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_peekValue(boolean hasValue) { + var pickedValue = Slot.createEmpty(); + + Consumer consumer = v -> { + assertNotNull(v); + assertTrue(pickedValue.find().isEmpty()); + pickedValue.set(v); + }; + + Result result; + if (hasValue) { + result = Result.ofValue("foo"); + } else { + result = Result.ofError(new Exception("foo")); + } + result.peekValue(consumer); + + if (hasValue) { + assertEquals("foo", pickedValue.get()); + } else { + assertTrue(pickedValue.find().isEmpty()); + } + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_peekErrors(boolean hasValue) { + var pickedErrors = Slot.>createEmpty(); + + Consumer> consumer = v -> { + assertNotNull(v); + assertTrue(pickedErrors.find().isEmpty()); + pickedErrors.set(v); + }; + + Result result; + if (hasValue) { + result = Result.ofValue("foo"); + } else { + result = Result.ofErrors(List.of(new Exception("foo"), new IOException("bar"))); + } + result.peekErrors(consumer); + + if (hasValue) { + assertTrue(pickedErrors.find().isEmpty()); + } else { + assertSame(result.errors(), pickedErrors.get()); + } + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_mapErrors(boolean hasValue) { + Result result; + if (hasValue) { + result = Result.ofValue("foo"); + } else { + result = Result.ofErrors(List.of(new Exception("foo"), new IOException("bar"))); + } + + if (hasValue) { + var ex = assertThrowsExactly(IllegalStateException.class, result::mapErrors); + assertEquals("Can not map errors from a result without errors", ex.getMessage()); + } else { + assertSame(result, result.mapErrors()); + } + } + + @Test + public void test_allHaveValues_empty() { + assertTrue(Result.allHaveValues()); + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_allHaveValues(boolean expected) { + if (expected) { + assertTrue(Result.allHaveValues(Result.ofValue("foo"), Result.ofValue(37))); + } else { + assertFalse(Result.allHaveValues(Result.ofValue("foo"), Result.ofError(new Exception()))); + } + } + + enum MapFunctionType { + MAP, + FLAT_MAP, + ; + } + + enum MapFunctionOutcome { + RETURN_NON_NULL, + RETURN_NULL, + THROW, + FLAT_MAP_NEW_ERRORS(MapFunctionType.FLAT_MAP), + ; + + MapFunctionOutcome(MapFunctionType... supportedTypes) { + this.supportedTypes = Set.of(supportedTypes); + } + + MapFunctionOutcome() { + this(MapFunctionType.values()); + } + + private final Set supportedTypes; + } + + record MapTestSpec(boolean hasValue, MapFunctionOutcome outcome, MapFunctionType type) { + MapTestSpec { + Objects.requireNonNull(outcome); + Objects.requireNonNull(type); + } + + @Override + public String toString() { + var tokens = new ArrayList(); + tokens.add(outcome.name()); + if (type == MapFunctionType.FLAT_MAP) { + tokens.add("flatMap"); + } + if (!hasValue) { + tokens.add("no-value"); + } + return String.join(", ", tokens); + } + + void run() { + var builder = MapTest.build(); + if (hasValue) { + builder.initialValue(100); + } + + Function plainMapper; + switch (outcome) { + case RETURN_NON_NULL -> { + if (hasValue) { + builder.expectValue("200"); + } + plainMapper = v -> { + return String.valueOf(v * 2); + }; + } + case RETURN_NULL -> { + builder.expectExceptionOfType(NullPointerException.class); + plainMapper = _ -> { + return null; + }; + } + case THROW -> { + var cause = new UnsupportedOperationException("Unsupported"); + builder.expectException(cause); + plainMapper = _ -> { + throw cause; + }; + } + case FLAT_MAP_NEW_ERRORS -> { + if (hasValue) { + // Just a stub to make `builder.create()` pass. + builder.expectValue(""); + } + var mappedResult = Result.ofError(new UnsupportedOperationException("Whoopsy-daisy")); + var test = builder.create().copyWithMappedValue(mappedResult); + test.flatMap(v -> { + return mappedResult; + }); + return; + } + default -> { + throw ExceptionBox.reachedUnreachable(); + } + } + + var test = builder.create(); + + switch (type) { + case MAP -> { + test.map(plainMapper); + } + case FLAT_MAP -> { + test.flatMap(v -> { + return Optional.ofNullable(plainMapper.apply(v)).map(Result::ofValue).orElse(null); + }); + } + } + } + } + + private static List test_map_and_flatMap() { + var data = new ArrayList(); + for (var type : MapFunctionType.values()) { + for (var outcome : MapFunctionOutcome.values()) { + if (outcome.supportedTypes.contains(type)) { + for (var hasValue : List.of(true, false)) { + data.add(new MapTestSpec(hasValue, outcome, type)); + } + } + } + } + return data; + } + + private static final class Counter implements Function { + + Counter(Function impl) { + this.impl = Objects.requireNonNull(impl); + } + + @Override + public U apply(T v) { + counter++; + return impl.apply(v); + } + + int count() { + return counter; + } + + private int counter; + private final Function impl; + } + + private record MapTest( + Result initialValue, + Optional> mappedValue, + Optional expectedException, + Optional> expectedExceptionType) { + + MapTest { + Objects.requireNonNull(initialValue); + Objects.requireNonNull(mappedValue); + Objects.requireNonNull(expectedException); + Objects.requireNonNull(expectedExceptionType); + + if (expectedExceptionType.isPresent() && mappedValue.isPresent()) { + // Bad configuration: the mapping operation is expected to throw, + // but it also expects it to return a value. + throw new IllegalArgumentException(); + } + + if (expectedExceptionType.isEmpty() && mappedValue.isEmpty()) { + // Bad configuration: the mapping operation is expected to return normally (not to throw), + // but it also doesn't expect a mapped value. + throw new IllegalArgumentException(); + } + + if (initialValue.hasErrors() && mappedValue.map(Result::hasValue).orElse(false)) { + // Bad configuration: the initial value has errors but they expect a mapped value without errors. + throw new IllegalArgumentException(); + } + + expectedException.map(Object::getClass).ifPresent(expectedExpectedExceptionType -> { + var configuredExpectedExceptionType = expectedExceptionType.orElseThrow(); + if (!configuredExpectedExceptionType.equals(expectedExpectedExceptionType)) { + throw new IllegalArgumentException(String.format( + "expectedException=%s; expectedExceptionType=%s", + expectedExpectedExceptionType, configuredExpectedExceptionType)); + } + }); + } + + MapTest copyWithMappedValue(Result v) { + return new MapTest<>(initialValue, Optional.of(v), expectedException, expectedExceptionType); + } + + static Builder build() { + return new Builder<>(); + } + + void map(Function mapper) { + map(new Counter<>(mapper), initialValue::map); + } + + void flatMap(Function> mapper) { + map(new Counter<>(mapper), initialValue::flatMap); + } + + private void map(Counter countingMapper, Function, Result> mapper) { + + if (initialValue.hasErrors()) { + Result mapped = mapper.apply(countingMapper); + assertTrue(mapped.hasErrors()); + assertEquals(initialValue.errors(), mapped.errors()); + } else { + expectedExceptionType.ifPresentOrElse(theExpectedExceptionType -> { + var ex = assertThrowsExactly(theExpectedExceptionType, () -> { + initialValue.map(countingMapper); + }); + + expectedException.ifPresent(theExpectedException -> { + assertSame(theExpectedException, ex); + }); + }, () -> { + Result mapped = mapper.apply(countingMapper); + assertEquals(mappedValue.orElseThrow(), mapped); + }); + } + + if (initialValue.hasValue()) { + assertEquals(1, countingMapper.count()); + } else { + assertEquals(0, countingMapper.count()); + } + } + + static final class Builder { + + MapTest create() { + + var theInitialValue = Optional.ofNullable(initialValue).orElseGet(() -> { + return Result.ofError(new Exception("Kaput!")); + }); + + return new MapTest<>( + theInitialValue, + Optional.ofNullable(expectedValue).map(Result::ofValue).or(() -> { + if (expectedExceptionType == null) { + return Optional.of(theInitialValue.mapErrors()); + } else { + return Optional.empty(); + } + }), + Optional.ofNullable(expectedException), + Optional.ofNullable(expectedExceptionType)); + } + + Builder initialValue(Result v) { + initialValue = v; + return this; + } + + Builder initialValue(T v) { + return initialValue(Result.ofValue(v)); + } + + Builder expectException(Exception v) { + expectedException = v; + if (expectedException != null) { + expectedExceptionType = expectedException.getClass(); + expectValue(null); + } else { + expectedExceptionType = null; + } + return this; + } + + Builder expectExceptionOfType(Class v) { + expectedException = null; + expectedExceptionType = v; + if (v != null) { + expectValue(null); + } + return this; + } + + Builder expectValue(U v) { + expectedValue = v; + if (v != null) { + expectException(null); + } + return this; + } + + private Result initialValue; + private U expectedValue; + private Exception expectedException; + private Class expectedExceptionType; + } + } +} diff --git a/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/function/ExceptionBoxTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/function/ExceptionBoxTest.java new file mode 100644 index 00000000000..c3ef239b02d --- /dev/null +++ b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/function/ExceptionBoxTest.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 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.jpackage.internal.util.function; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicReference; +import java.util.function.UnaryOperator; +import jdk.jpackage.internal.util.Slot; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; + +public class ExceptionBoxTest { + + @Test + public void test_unbox_RuntimeException() { + var ex = new RuntimeException(); + assertSame(ex, ExceptionBox.unbox(ex)); + } + + @Test + public void test_unbox_Exception() { + var ex = new Exception(); + assertSame(ex, ExceptionBox.unbox(ex)); + } + + @Test + public void test_unbox_InvocationTargetException() { + var ex = new Exception(); + assertSame(ex, ExceptionBox.unbox(new InvocationTargetException(ex))); + } + + @Test + public void test_unbox_ExceptionBox() { + var ex = new Exception("foo"); + // There is no way to directly instantiate ExceptionBox, use a workaround. + var box = assertThrowsExactly(ExceptionBox.class, () -> { + throw ExceptionBox.toUnchecked(ex); + }); + assertSame(ex, ExceptionBox.unbox(box)); + } + + @Test + public void test_unbox_Error() { + var err = new Error("On Fire!"); + var thrown = assertThrowsExactly(Error.class, () -> { + ExceptionBox.unbox(err); + }); + assertSame(err, thrown); + } + + @Test + public void test_reachedUnreachable() { + var err = ExceptionBox.reachedUnreachable(); + assertEquals("Reached unreachable!", err.getMessage()); + } + + @Test + public void test_toUnchecked_RuntimeException() { + assertToUnchecked(new RuntimeException(), true); + } + + @Test + public void test_toUnchecked_Exception() { + assertToUnchecked(new Exception(), false); + } + + @Test + public void test_toUnchecked_ExceptionBox() { + // There is no way to directly instantiate ExceptionBox, use a workaround. + var box = assertThrowsExactly(ExceptionBox.class, () -> { + throw ExceptionBox.toUnchecked(new Exception("foo")); + }); + assertToUnchecked(box, true); + } + + @Test + public void test_toUnchecked_InterruptedException() throws InterruptedException { + + var workerThreadReadyToWait = Slot.createEmpty(); + + var workerThreadInterruptedExceptionCaught = Slot.createEmpty(); + + var workerThreadException = new AtomicReference(); + + var thread = Thread.ofVirtual().uncaughtExceptionHandler((Thread _, Throwable e) -> { + trace("unexpected exception: %s", e); + workerThreadException.set(e); + }).start(() -> { + try { + var lock = new Object(); + synchronized (lock) { + synchronized (workerThreadReadyToWait) { + workerThreadReadyToWait.set(true); + workerThreadReadyToWait.notify(); + } + trace("wait"); + lock.wait(); + } + } catch (InterruptedException iex) { + trace("interrupted state cleared"); + synchronized (workerThreadInterruptedExceptionCaught) { + workerThreadInterruptedExceptionCaught.set(true); + trace("notify about to interrupt itself"); + workerThreadInterruptedExceptionCaught.notify(); + } + trace("before toUnchecked()"); + var box = assertThrowsExactly(ExceptionBox.class, () -> { + throw ExceptionBox.toUnchecked(iex); + }); + assertSame(iex, box.getCause()); + } + }); + + // Wait until the worker thread gets to the point + // when interrupting it will cause InterruptedException. + synchronized (workerThreadReadyToWait) { + while (workerThreadReadyToWait.find().isEmpty()) { + workerThreadReadyToWait.wait(); + } + } + + trace("interrupt %s", thread); + thread.interrupt(); + + // Wait until the worker thread catches an InterruptedException. + synchronized (workerThreadInterruptedExceptionCaught) { + while (workerThreadInterruptedExceptionCaught.find().isEmpty()) { + trace("wait for %s to catch InterruptedException", thread); + workerThreadInterruptedExceptionCaught.wait(); + } + } + + // Block waiting when ExceptionBox.toUnchecked() + // called in the worker thread will interrupt the worker thread. + while (!thread.isInterrupted()) { + trace("wait %s is interrupted", thread); + Thread.sleep(100); + } + + trace("join interrupted %s", thread); + thread.join(); + + assertNull(workerThreadException.get()); + } + + @ParameterizedTest + @EnumSource(InvocationTargetExceptionType.class) + public void test_rethrowUnchecked_InvocationTargetException(InvocationTargetExceptionType type) + throws NoSuchMethodException, SecurityException, IllegalAccessException { + + var m = ExceptionBoxTest.class.getMethod(type.methodName); + + try { + m.invoke(null); + } catch (InvocationTargetException ex) { + var cause = assertThrows(type.expectedThrownType, () -> { + throw ExceptionBox.toUnchecked(ex); + }); + assertSame(ex.getCause(), type.expectedThrowableGetter.apply(cause)); + } + } + + public enum InvocationTargetExceptionType { + CHECKED("throwIOException", t -> { + return t.getCause(); + }, ExceptionBox.class), + UNCHECKED("throwNPE", x -> x, RuntimeException.class), + ERROR("throwError", x -> x, Error.class), + ; + + InvocationTargetExceptionType( + String methodName, + UnaryOperator expectedThrowableGetter, + Class expectedThrownType) { + this.methodName = Objects.requireNonNull(methodName); + this.expectedThrownType = Objects.requireNonNull(expectedThrownType); + this.expectedThrowableGetter = Objects.requireNonNull(expectedThrowableGetter); + } + + final String methodName; + final Class expectedThrownType; + final UnaryOperator expectedThrowableGetter; + } + + public static void throwIOException() throws IOException { + throw new IOException("foo"); + } + + public static void throwNPE() { + throw new NullPointerException("foo"); + } + + public static void throwError() { + throw new Error("Kaput!"); + } + + private static void assertToUnchecked(Exception cause, boolean asis) { + Class expectedType; + if (asis) { + expectedType = cause.getClass(); + } else { + expectedType = ExceptionBox.class; + } + var unchecked = ExceptionBox.toUnchecked(cause); + if (asis) { + assertSame(cause, unchecked); + } else { + assertSame(cause, unchecked.getCause()); + } + } + + private void trace(String format, Object... args) { + Objects.requireNonNull(format); + System.out.println(String.format("[%s]: %s", Thread.currentThread(), String.format(format, args))); + } +} diff --git a/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/function/FunctionalTest.java b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/function/FunctionalTest.java new file mode 100644 index 00000000000..67c082916a6 --- /dev/null +++ b/test/jdk/tools/jpackage/junit/share/jdk.jpackage/jdk/jpackage/internal/util/function/FunctionalTest.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 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.jpackage.internal.util.function; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.Map; +import java.util.function.Supplier; +import jdk.jpackage.internal.util.Slot; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +public class FunctionalTest { + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_toRunnable(boolean error) { + var reply = Slot.createEmpty(); + + var runnable = ThrowingRunnable.toRunnable(() -> { + if (error) { + throw new Exception(); + } else { + reply.set(135); + } + }); + + if (error) { + assertThrowsExactly(ExceptionBox.class, runnable::run); + assertTrue(reply.find().isEmpty()); + } else { + runnable.run(); + assertEquals(135, reply.get()); + } + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_toSupplier(boolean error) { + var supplier = ThrowingSupplier.toSupplier(() -> { + if (error) { + throw new Exception(); + } else { + return 135; + } + }); + + if (error) { + assertThrowsExactly(ExceptionBox.class, supplier::get); + } else { + assertEquals(135, supplier.get()); + } + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_toConsumer(boolean error) { + var reply = Slot.createEmpty(); + + Runnable runnable = () -> { + ThrowingConsumer.toConsumer(v -> { + if (error) { + throw new Exception(); + } else { + reply.set(v); + } + }).accept(135); + }; + + if (error) { + assertThrowsExactly(ExceptionBox.class, runnable::run); + assertTrue(reply.find().isEmpty()); + } else { + runnable.run(); + assertEquals(135, reply.get()); + } + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_toBiConsumer(boolean error) { + var reply = Slot.createEmpty(); + var reply2 = Slot.createEmpty(); + + Runnable runnable = () -> { + ThrowingBiConsumer.toBiConsumer((x, y) -> { + if (error) { + throw new Exception(); + } else { + reply.set(x); + reply2.set(y); + } + }).accept(456, "Hello"); + }; + + if (error) { + assertThrowsExactly(ExceptionBox.class, runnable::run); + assertTrue(reply.find().isEmpty()); + assertTrue(reply2.find().isEmpty()); + } else { + runnable.run(); + assertEquals(456, reply.get()); + assertEquals("Hello", reply2.get()); + } + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_toFunction(boolean error) { + Supplier supplier = () -> { + return ThrowingFunction.toFunction(v -> { + if (error) { + throw new Exception(); + } else { + return String.valueOf(v); + } + }).apply(765); + }; + + if (error) { + assertThrowsExactly(ExceptionBox.class, supplier::get); + } else { + assertEquals("765", supplier.get()); + } + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_toBiFunction(boolean error) { + Supplier< Map.Entry> supplier = () -> { + return ThrowingBiFunction.>toBiFunction((x, y) -> { + if (error) { + throw new Exception(); + } else { + return Map.entry(y, x + 23); + } + }).apply(400, "foo"); + }; + + if (error) { + assertThrowsExactly(ExceptionBox.class, supplier::get); + } else { + assertEquals(Map.entry("foo", 423), supplier.get()); + } + } + + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void test_toUnaryOperator(boolean error) { + Supplier supplier = () -> { + return ThrowingUnaryOperator.toUnaryOperator(v -> { + if (error) { + throw new Exception(); + } else { + return v - 222; + } + }).apply(777); + }; + + if (error) { + assertThrowsExactly(ExceptionBox.class, supplier::get); + } else { + assertEquals(555, supplier.get()); + } + } +} diff --git a/test/jdk/tools/jpackage/junit/tools/jdk/jpackage/test/JUnitAdapter.java b/test/jdk/tools/jpackage/junit/tools/jdk/jpackage/test/JUnitAdapter.java index 5a605b1642d..952b4b520d5 100644 --- a/test/jdk/tools/jpackage/junit/tools/jdk/jpackage/test/JUnitAdapter.java +++ b/test/jdk/tools/jpackage/junit/tools/jdk/jpackage/test/JUnitAdapter.java @@ -49,7 +49,7 @@ public class JUnitAdapter { } } - public static Stream createJPackageTests(ClassLoader testClassLoader, String... args) throws Throwable { + public static Stream createJPackageTests(ClassLoader testClassLoader, String... args) throws Exception { final List tests = new ArrayList<>(); try (final var testBuilder = TestBuilder.build().workDirRoot(Path.of("")).testClassLoader(testClassLoader).testConsumer(tests::add).create()) { for (final var arg : args) { @@ -64,11 +64,11 @@ public class JUnitAdapter { } @TestFactory - Stream createJPackageTests() throws Throwable { + Stream createJPackageTests() throws Exception { return createJPackageTests(getClass().getClassLoader(), "--jpt-run=" + getClass().getName()); } - static List captureJPackageTestLog(ThrowingRunnable runnable) { + static List captureJPackageTestLog(ThrowingRunnable runnable) { final var buf = new ByteArrayOutputStream(); try (PrintStream ps = new PrintStream(buf, true, StandardCharsets.UTF_8)) { TKit.withExtraLogStream(runnable, ps); diff --git a/test/jdk/tools/jpackage/linux/AppAboutUrlTest.java b/test/jdk/tools/jpackage/linux/AppAboutUrlTest.java index aef46e29725..8196ab733c9 100644 --- a/test/jdk/tools/jpackage/linux/AppAboutUrlTest.java +++ b/test/jdk/tools/jpackage/linux/AppAboutUrlTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 AppAboutUrlTest { runTest(JPackageCommand::setFakeRuntime, "", "(none)"); } - private static void runTest(ThrowingConsumer initializer, + private static void runTest(ThrowingConsumer initializer, String expectedDebHomepage, String expectedRpmUrl) { new PackageTest() .forTypes(PackageType.LINUX) diff --git a/test/jdk/tools/jpackage/macosx/CustomInfoPListTest.java b/test/jdk/tools/jpackage/macosx/CustomInfoPListTest.java index dd94330d039..50445c0e9ab 100644 --- a/test/jdk/tools/jpackage/macosx/CustomInfoPListTest.java +++ b/test/jdk/tools/jpackage/macosx/CustomInfoPListTest.java @@ -23,7 +23,6 @@ import static java.util.Collections.unmodifiableSortedSet; import static java.util.Map.entry; -import jdk.jpackage.internal.util.Slot; import static jdk.jpackage.internal.util.PListWriter.writeDict; import static jdk.jpackage.internal.util.PListWriter.writeKey; import static jdk.jpackage.internal.util.PListWriter.writePList; @@ -52,6 +51,7 @@ import java.util.stream.Stream; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; import jdk.jpackage.internal.util.PListReader; +import jdk.jpackage.internal.util.Slot; import jdk.jpackage.internal.util.function.ThrowingBiConsumer; import jdk.jpackage.test.Annotations.Parameter; import jdk.jpackage.test.Annotations.ParameterSupplier; @@ -84,7 +84,7 @@ public class CustomInfoPListTest { @Test @ParameterSupplier("customPLists") - public void testAppImage(TestConfig cfg) throws Throwable { + public void testAppImage(TestConfig cfg) { testApp(new ConfigurationTarget(JPackageCommand.helloAppImage()), cfg); } @@ -254,6 +254,10 @@ public class CustomInfoPListTest { .addArguments(cmd.getAllArguments()) .setPackageType(PackageType.IMAGE) .removeArgumentWithValue("--resource-dir") + // Ignore externally configured runtime if any. + // It may or may not have the "bin" directory, it also can be a bundle. + // These factors affect the runtime plist file (see JDK-8363980) which may not be the default one. + .ignoreDefaultRuntime(true) .setArgumentValue("--dest", TKit.createTempDirectory("vanilla")); vanillaCmd.execute(); @@ -320,8 +324,8 @@ public class CustomInfoPListTest { ; private CustomPListType( - ThrowingBiConsumer inputPlistWriter, - ThrowingBiConsumer outputPlistWriter, + ThrowingBiConsumer inputPlistWriter, + ThrowingBiConsumer outputPlistWriter, String outputPlistFilename) { this.inputPlistWriter = ThrowingBiConsumer.toBiConsumer(inputPlistWriter); this.outputPlistWriter = ThrowingBiConsumer.toBiConsumer(outputPlistWriter); diff --git a/test/jdk/tools/jpackage/macosx/EntitlementsTest.java b/test/jdk/tools/jpackage/macosx/EntitlementsTest.java index aa5879e0c61..6e03c858db3 100644 --- a/test/jdk/tools/jpackage/macosx/EntitlementsTest.java +++ b/test/jdk/tools/jpackage/macosx/EntitlementsTest.java @@ -99,7 +99,7 @@ public class EntitlementsTest { }), ; - EntitlementsSource(ThrowingConsumer initializer) { + EntitlementsSource(ThrowingConsumer initializer) { this.initializer = toConsumer(initializer); } diff --git a/test/jdk/tools/jpackage/share/AppContentTest.java b/test/jdk/tools/jpackage/share/AppContentTest.java index 97c83bba57d..b6066bb9cc4 100644 --- a/test/jdk/tools/jpackage/share/AppContentTest.java +++ b/test/jdk/tools/jpackage/share/AppContentTest.java @@ -37,7 +37,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; @@ -631,7 +630,7 @@ public class AppContentTest { private static final class FileContentFactory implements ContentFactory { - FileContentFactory(ThrowingSupplier factory, Path pathInAppContentRoot) { + FileContentFactory(ThrowingSupplier factory, Path pathInAppContentRoot) { this.factory = ThrowingSupplier.toSupplier(factory); this.pathInAppContentRoot = pathInAppContentRoot; if (pathInAppContentRoot.isAbsolute()) { diff --git a/test/jdk/tools/jpackage/share/AsyncTest.java b/test/jdk/tools/jpackage/share/AsyncTest.java index b2755d4594f..e3a3f7e3cb8 100644 --- a/test/jdk/tools/jpackage/share/AsyncTest.java +++ b/test/jdk/tools/jpackage/share/AsyncTest.java @@ -37,6 +37,7 @@ import java.util.function.Predicate; import java.util.spi.ToolProvider; import java.util.stream.IntStream; import jdk.jpackage.internal.util.function.ThrowingRunnable; +import jdk.jpackage.internal.util.Slot; import jdk.jpackage.test.Annotations.ParameterSupplier; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.HelloApp; @@ -61,7 +62,7 @@ import jdk.jpackage.test.TKit; public class AsyncTest { @Test - public void test() throws Throwable { + public void test() throws Exception { // Create test jar only once. // Besides of saving time, this avoids asynchronous invocations of java tool provider that randomly fail. @@ -94,7 +95,7 @@ public class AsyncTest { future.get(3, TimeUnit.MINUTES); } - Throwable[] fatalError = new Throwable[1]; + var fatalError = Slot.createEmpty(); for (var future : futures) { var result = future.get(); @@ -102,13 +103,11 @@ public class AsyncTest { TKit.trace(String.format("[%s] STDOUT END", result.id())); TKit.trace(String.format("[%s] STDERR BEGIN\n%s", result.id(), result.stderrBuffer())); TKit.trace(String.format("[%s] STDERR END", result.id())); - result.throwable().filter(Predicate.not(TKit::isSkippedException)).ifPresent(t -> { - fatalError[0] = t; - }); + result.exception().filter(Predicate.not(TKit::isSkippedException)).ifPresent(fatalError::set); } - if (fatalError[0] != null) { - throw fatalError[0]; + if (fatalError.find().isPresent()) { + throw fatalError.get(); } } } @@ -143,13 +142,13 @@ public class AsyncTest { } - private record Result(String stdoutBuffer, String stderrBuffer, String id, Optional throwable) { + private record Result(String stdoutBuffer, String stderrBuffer, String id, Optional exception) { Result { Objects.requireNonNull(stdoutBuffer); Objects.requireNonNull(stderrBuffer); Objects.requireNonNull(id); - Objects.requireNonNull(throwable); + Objects.requireNonNull(exception); } } @@ -157,7 +156,7 @@ public class AsyncTest { private record Workload( ByteArrayOutputStream stdoutBuffer, ByteArrayOutputStream stderrBuffer, - ThrowingRunnable runnable, + ThrowingRunnable runnable, String id) implements Callable { Workload { @@ -167,7 +166,7 @@ public class AsyncTest { Objects.requireNonNull(id); } - Workload(ThrowingRunnable runnable, String id) { + Workload(ThrowingRunnable runnable, String id) { this(new ByteArrayOutputStream(), new ByteArrayOutputStream(), runnable, id); } @@ -202,14 +201,14 @@ public class AsyncTest { } }); - Optional err = Optional.empty(); + Optional err = Optional.empty(); try (var bufOut = new PrintStream(stdoutBuffer, true, StandardCharsets.UTF_8); var bufErr = new PrintStream(stderrBuffer, true, StandardCharsets.UTF_8)) { TKit.withStackTraceStream(() -> { TKit.withMainLogStream(runnable, bufOut); }, bufErr); - } catch (Throwable t) { - err = Optional.of(t); + } catch (Exception ex) { + err = Optional.of(ex); } return new Result(stdoutBufferAsString(), stderrBufferAsString(), id, err); } diff --git a/test/jdk/tools/jpackage/share/BasicTest.java b/test/jdk/tools/jpackage/share/BasicTest.java index 958fe150711..0f5d87048dd 100644 --- a/test/jdk/tools/jpackage/share/BasicTest.java +++ b/test/jdk/tools/jpackage/share/BasicTest.java @@ -307,12 +307,12 @@ public final class BasicTest { @Test @Parameter("true") @Parameter("false") - public void testNoOutputDir(boolean appImage) throws Throwable { + public void testNoOutputDir(boolean appImage) throws IOException { var cmd = JPackageCommand.helloAppImage(); final var execDir = cmd.outputDir(); - final ThrowingConsumer initializer = cmdNoOutputDir -> { + final ThrowingConsumer initializer = cmdNoOutputDir -> { cmd.executePrerequisiteActions(); final var pkgType = cmdNoOutputDir.packageType(); diff --git a/test/jdk/tools/jpackage/share/IconTest.java b/test/jdk/tools/jpackage/share/IconTest.java index 12458eda34b..17759db7192 100644 --- a/test/jdk/tools/jpackage/share/IconTest.java +++ b/test/jdk/tools/jpackage/share/IconTest.java @@ -203,7 +203,7 @@ public class IconTest { return withDesktopFile; } - private ThrowingBiConsumer createBundleVerifier() { + private ThrowingBiConsumer createBundleVerifier() { return (cmd, result) -> { Stream.of(Launcher.Main, Launcher.Additional).filter(config::containsKey).forEach(launcher -> { createConsoleOutputVerifier(cmd, launcher).ifPresent(verifier -> { @@ -276,7 +276,7 @@ public class IconTest { return Optional.of(TKit.assertTextStream(lookupString.getValue())); } - private ThrowingConsumer createInstallVerifier() { + private ThrowingConsumer createInstallVerifier() { return cmd -> { var verifier = new LauncherIconVerifier(); diff --git a/test/jdk/tools/jpackage/share/InOutPathTest.java b/test/jdk/tools/jpackage/share/InOutPathTest.java index d36731c2960..211fb843263 100644 --- a/test/jdk/tools/jpackage/share/InOutPathTest.java +++ b/test/jdk/tools/jpackage/share/InOutPathTest.java @@ -21,6 +21,8 @@ * questions. */ +import static jdk.jpackage.test.RunnablePackageTest.Action.CREATE_AND_UNPACK; + import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -31,17 +33,16 @@ import java.util.Set; import java.util.function.Predicate; import java.util.stream.Stream; import jdk.internal.util.OperatingSystem; -import jdk.jpackage.test.AppImageFile; -import jdk.jpackage.test.ApplicationLayout; -import jdk.jpackage.test.PackageFile; +import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.internal.util.function.ThrowingConsumer; +import jdk.jpackage.test.AppImageFile; +import jdk.jpackage.test.ApplicationLayout; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.JPackageCommand.StandardAssert; +import jdk.jpackage.test.PackageFile; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; -import static jdk.jpackage.test.RunnablePackageTest.Action.CREATE_AND_UNPACK; import jdk.jpackage.test.TKit; /* @@ -145,11 +146,11 @@ public final class InOutPathTest { } @Test - public void test() throws Throwable { + public void test() throws Exception { runTest(packageTypes, configure); } - private static Envelope wrap(ThrowingConsumer v, String label) { + private static Envelope wrap(ThrowingConsumer v, String label) { return new Envelope(v, label); } @@ -158,8 +159,8 @@ public final class InOutPathTest { } private static void runTest(Set packageTypes, - ThrowingConsumer configure) throws Throwable { - ThrowingConsumer configureWrapper = cmd -> { + ThrowingConsumer configure) throws Exception { + ThrowingConsumer configureWrapper = cmd -> { // Make sure the input directory is empty in every test run. // This is needed because jpackage output directories in this test // are subdirectories of the input directory. @@ -268,7 +269,7 @@ public final class InOutPathTest { } } - private static final record Envelope(ThrowingConsumer value, String label) { + private static final record Envelope(ThrowingConsumer value, String label) { @Override public String toString() { // Will produce the same test description for the same label every @@ -291,7 +292,7 @@ public final class InOutPathTest { } private final Set packageTypes; - private final ThrowingConsumer configure; + private final ThrowingConsumer configure; // Placing jar file in the "Resources" subdir of the input directory would allow // to use the input directory with `--app-content` on OSX. diff --git a/test/jdk/tools/jpackage/share/PerUserCfgTest.java b/test/jdk/tools/jpackage/share/PerUserCfgTest.java index d2f368cd824..b28eb060b8f 100644 --- a/test/jdk/tools/jpackage/share/PerUserCfgTest.java +++ b/test/jdk/tools/jpackage/share/PerUserCfgTest.java @@ -158,8 +158,8 @@ public class PerUserCfgTest { } private static void withConfigFile(JPackageCommand cmd, Path srcCfgFile, - Path outputCfgFileDir, ThrowingConsumer action) throws - Throwable { + Path outputCfgFileDir, ThrowingConsumer action) throws + Exception { Path targetCfgFile = outputCfgFileDir.resolve(cmd.appLauncherCfgPath( null).getFileName()); TKit.assertPathExists(targetCfgFile, false); diff --git a/test/jdk/tools/jpackage/share/RuntimePackageTest.java b/test/jdk/tools/jpackage/share/RuntimePackageTest.java index 387b46acdfb..6cc668f94f9 100644 --- a/test/jdk/tools/jpackage/share/RuntimePackageTest.java +++ b/test/jdk/tools/jpackage/share/RuntimePackageTest.java @@ -30,7 +30,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.Objects; import java.util.function.Predicate; -import jdk.jpackage.internal.util.function.ThrowingSupplier; +import java.util.function.Supplier; import jdk.jpackage.test.Annotations.Parameter; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.JPackageCommand; @@ -114,7 +114,7 @@ public class RuntimePackageTest { return init(JPackageCommand::createInputRuntimeImage); } - private static PackageTest init(ThrowingSupplier createRuntime) { + private static PackageTest init(Supplier createRuntime) { Objects.requireNonNull(createRuntime); final Path[] runtimeImageDir = new Path[1]; diff --git a/test/jdk/tools/jpackage/share/ServiceTest.java b/test/jdk/tools/jpackage/share/ServiceTest.java index 94d3421a2cd..91950f0dba8 100644 --- a/test/jdk/tools/jpackage/share/ServiceTest.java +++ b/test/jdk/tools/jpackage/share/ServiceTest.java @@ -109,7 +109,7 @@ public class ServiceTest { } @Test - public void test() throws Throwable { + public void test() { var pkg = createPackageTest().addHelloAppInitializer("com.foo.ServiceTest"); LauncherAsServiceVerifier.build().setExpectedValue("A1").applyTo(pkg); createTestInitializer().applyTo(pkg); @@ -117,7 +117,7 @@ public class ServiceTest { } @Test - public void testUpdate() throws Throwable { + public void testUpdate() { var testInitializer = createTestInitializer().setUpgradeCode( "4050AD4D-D6CC-452A-9CB0-58E5FA8C410F"); From 30be94086aad42b99a15a05fe5115f552e8efb8b Mon Sep 17 00:00:00 2001 From: Jonas Norlinder Date: Tue, 16 Dec 2025 21:33:27 +0000 Subject: [PATCH 029/390] 8373625: CPUTimeCounters creates a total counter for unsupported GCs Reviewed-by: sjohanss, tschatzl --- src/hotspot/share/runtime/cpuTimeCounters.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/runtime/cpuTimeCounters.hpp b/src/hotspot/share/runtime/cpuTimeCounters.hpp index 9ad00492731..c2e636bdb1d 100644 --- a/src/hotspot/share/runtime/cpuTimeCounters.hpp +++ b/src/hotspot/share/runtime/cpuTimeCounters.hpp @@ -28,6 +28,7 @@ #define SHARE_RUNTIME_CPUTIMECOUNTERS_HPP +#include "gc/shared/gc_globals.hpp" #include "memory/iterator.hpp" #include "runtime/os.hpp" #include "runtime/perfData.hpp" @@ -83,7 +84,9 @@ public: assert(_instance == nullptr, "we can only allocate one CPUTimeCounters object"); if (UsePerfData && os::is_thread_cpu_time_supported()) { _instance = new CPUTimeCounters(); - create_counter(SUN_THREADS, CPUTimeGroups::CPUTimeType::gc_total); + if (UseG1GC || UseParallelGC) { + create_counter(SUN_THREADS, CPUTimeGroups::CPUTimeType::gc_total); + } } } From 87d881fee01c42f5847031a63d50873b3d438f7a Mon Sep 17 00:00:00 2001 From: Bradford Wetmore Date: Tue, 16 Dec 2025 21:43:43 +0000 Subject: [PATCH 030/390] 8368493: Disable most test JSSE debug output by default, and increase the test default maximum output log size Reviewed-by: jnimeh, hchao --- test/jdk/javax/net/ssl/DTLS/TEST.properties | 1 - .../net/ssl/HttpsURLConnection/Equals.java | 19 ++- .../net/ssl/SSLEngine/NoAuthClientAuth.java | 4 +- .../ssl/SSLSession/ResumeTLS13withSNI.java | 4 +- ...erverNameRejectedTLSSessionResumption.java | 19 ++- .../SSLEngineExplorerMatchedSNI.java | 4 +- .../ssl/Stapling/SSLEngineWithStapling.java | 6 +- test/jdk/javax/net/ssl/TEST.properties | 1 + test/jdk/javax/net/ssl/TLS/TestJSSE.java | 17 ++- test/jdk/javax/net/ssl/TLSCommon/TLSTest.java | 126 ++++++++++-------- .../javax/net/ssl/TLSCommon/TLSWithEdDSA.java | 20 ++- .../javax/net/ssl/TLSv12/ShortRSAKey512.java | 4 +- .../net/ssl/TLSv13/ClientHelloKeyShares.java | 20 ++- .../javax/net/ssl/TLSv13/HRRKeyShares.java | 20 ++- .../compatibility/ClientHelloProcessing.java | 19 ++- .../net/ssl/templates/SSLEngineTemplate.java | 16 +++ .../net/ssl/templates/SSLSocketTemplate.java | 15 +++ .../ssl/SSLEngineImpl/TestBadDNForPeerCA.java | 17 ++- .../SSLEngineImpl/TestBadDNForPeerCA12.java | 18 ++- .../NoInvalidateSocketException.java | 16 ++- .../ResumeClientTLS12withSNI.java | 18 ++- .../AnonCipherWithWantClientAuth.java | 21 ++- .../SigAlgosExtTestWithTLS12.java | 16 ++- .../SigSchemePropOrdering.java | 15 ++- .../ssl/Stapling/StatusResponseManager.java | 5 +- .../ssl/StatusResponseManagerTests.java | 17 ++- test/jdk/sun/security/ssl/TEST.properties | 1 + 27 files changed, 357 insertions(+), 102 deletions(-) create mode 100644 test/jdk/javax/net/ssl/TEST.properties create mode 100644 test/jdk/sun/security/ssl/TEST.properties diff --git a/test/jdk/javax/net/ssl/DTLS/TEST.properties b/test/jdk/javax/net/ssl/DTLS/TEST.properties index a50cba09c0f..ceb6c8c9c42 100644 --- a/test/jdk/javax/net/ssl/DTLS/TEST.properties +++ b/test/jdk/javax/net/ssl/DTLS/TEST.properties @@ -6,4 +6,3 @@ modules = \ java.security.jgss/sun.security.krb5.internal:+open \ java.security.jgss/sun.security.krb5.internal.ktab \ java.base/sun.security.util -maxOutputSize = 2500000 diff --git a/test/jdk/javax/net/ssl/HttpsURLConnection/Equals.java b/test/jdk/javax/net/ssl/HttpsURLConnection/Equals.java index d36dfb2630e..35913edd2bf 100644 --- a/test/jdk/javax/net/ssl/HttpsURLConnection/Equals.java +++ b/test/jdk/javax/net/ssl/HttpsURLConnection/Equals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -27,7 +27,7 @@ * @library /test/lib * @modules jdk.httpserver * @build jdk.test.lib.net.SimpleSSLContext - * @run main/othervm -Djavax.net.debug=ssl,handshake,record Equals + * @run main/othervm Equals */ import com.sun.net.httpserver.*; import java.net.*; @@ -38,9 +38,24 @@ import jdk.test.lib.net.SimpleSSLContext; public class Equals { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=ssl,handshake,record + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + static SSLContext ctx; public static void main(String[] args) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "ssl,handshake,record"); + } + HttpsServer s2 = null; ExecutorService executor = null; try { diff --git a/test/jdk/javax/net/ssl/SSLEngine/NoAuthClientAuth.java b/test/jdk/javax/net/ssl/SSLEngine/NoAuthClientAuth.java index 208fb3935ae..95754a4763e 100644 --- a/test/jdk/javax/net/ssl/SSLEngine/NoAuthClientAuth.java +++ b/test/jdk/javax/net/ssl/SSLEngine/NoAuthClientAuth.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 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 @@ -99,7 +99,7 @@ public class NoAuthClientAuth { * including specific handshake messages, and might be best examined * after gaining some familiarity with this application. */ - private static boolean debug = true; + private static boolean debug = false; private SSLContext sslc; diff --git a/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java b/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java index 3d05607bd39..d288fe70200 100644 --- a/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.java +++ b/test/jdk/javax/net/ssl/SSLSession/ResumeTLS13withSNI.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 @@ -54,7 +54,7 @@ public class ResumeTLS13withSNI { * including specific handshake messages, and might be best examined * after gaining some familiarity with this application. */ - private static final boolean debug = true; + private static final boolean debug = false; private static final ByteBuffer clientOut = ByteBuffer.wrap("Hi Server, I'm Client".getBytes()); diff --git a/test/jdk/javax/net/ssl/SSLSession/ServerNameRejectedTLSSessionResumption.java b/test/jdk/javax/net/ssl/SSLSession/ServerNameRejectedTLSSessionResumption.java index f80f3402c7e..de51b9c565e 100644 --- a/test/jdk/javax/net/ssl/SSLSession/ServerNameRejectedTLSSessionResumption.java +++ b/test/jdk/javax/net/ssl/SSLSession/ServerNameRejectedTLSSessionResumption.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 @@ -43,11 +43,20 @@ import javax.net.ssl.StandardConstants; * between the server and the client happens correctly without any * errors * @library /javax/net/ssl/templates - * @run main/othervm -Djavax.net.debug=all - * ServerNameRejectedTLSSessionResumption + * @run main/othervm ServerNameRejectedTLSSessionResumption */ public class ServerNameRejectedTLSSessionResumption extends SSLContextTemplate { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=all + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; private static final String CLIENT_REQUESTED_SNI = "client.local"; // dummy host, no connection is attempted in this test @@ -56,6 +65,10 @@ public class ServerNameRejectedTLSSessionResumption private static final int PEER_PORT = 12345; public static void main(final String[] args) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + new ServerNameRejectedTLSSessionResumption().runTest(); } diff --git a/test/jdk/javax/net/ssl/ServerName/SSLEngineExplorerMatchedSNI.java b/test/jdk/javax/net/ssl/ServerName/SSLEngineExplorerMatchedSNI.java index a42134abdb1..bb288684384 100644 --- a/test/jdk/javax/net/ssl/ServerName/SSLEngineExplorerMatchedSNI.java +++ b/test/jdk/javax/net/ssl/ServerName/SSLEngineExplorerMatchedSNI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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,7 @@ public class SSLEngineExplorerMatchedSNI extends SSLEngineService { /* * Turn on SSL debugging? */ - static boolean debug = true; + static boolean debug = false; /* * Define the server side of the test. diff --git a/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java b/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java index 506e7b00e6d..34398a4b6f8 100644 --- a/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java +++ b/test/jdk/javax/net/ssl/Stapling/SSLEngineWithStapling.java @@ -99,13 +99,13 @@ public class SSLEngineWithStapling { /* * Enables the JSSE system debugging system property: * - * -Djavax.net.debug=all + * -Djavax.net.debug=ssl,handshake * * This gives a lot of low-level information about operations underway, * including specific handshake messages, and might be best examined * after gaining some familiarity with this application. */ - private static final boolean debug = true; + private static final boolean debug = false; private SSLEngine clientEngine; // client Engine private ByteBuffer clientOut; // write side of clientEngine @@ -151,7 +151,7 @@ public class SSLEngineWithStapling { */ public static void main(String args[]) throws Exception { if (debug) { - System.setProperty("javax.net.debug", "ssl:handshake"); + System.setProperty("javax.net.debug", "ssl,handshake"); } // Create the PKI we will use for the test and start the OCSP servers diff --git a/test/jdk/javax/net/ssl/TEST.properties b/test/jdk/javax/net/ssl/TEST.properties new file mode 100644 index 00000000000..741c2565067 --- /dev/null +++ b/test/jdk/javax/net/ssl/TEST.properties @@ -0,0 +1 @@ +maxOutputSize=500000 diff --git a/test/jdk/javax/net/ssl/TLS/TestJSSE.java b/test/jdk/javax/net/ssl/TLS/TestJSSE.java index 29631064011..baabd7f6054 100644 --- a/test/jdk/javax/net/ssl/TLS/TestJSSE.java +++ b/test/jdk/javax/net/ssl/TLS/TestJSSE.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 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 @@ -27,6 +27,17 @@ import java.security.Security; public class TestJSSE { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=ssl,record + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + private static final String LOCAL_IP = InetAddress.getLoopbackAddress().getHostAddress(); public static void main(String... args) throws Exception { @@ -35,7 +46,9 @@ public class TestJSSE { Security.setProperty("jdk.tls.disabledAlgorithms", ""); // enable debug output - System.setProperty("javax.net.debug", "ssl,record"); + if (debug) { + System.setProperty("javax.net.debug", "ssl,record"); + } String srvProtocol = System.getProperty("SERVER_PROTOCOL"); String clnProtocol = System.getProperty("CLIENT_PROTOCOL"); diff --git a/test/jdk/javax/net/ssl/TLSCommon/TLSTest.java b/test/jdk/javax/net/ssl/TLSCommon/TLSTest.java index 6aec08deedd..fc6369a2bbc 100644 --- a/test/jdk/javax/net/ssl/TLSCommon/TLSTest.java +++ b/test/jdk/javax/net/ssl/TLSCommon/TLSTest.java @@ -49,98 +49,112 @@ import javax.net.ssl.TrustManagerFactory; * @bug 8205111 * @enablePreview * @summary Test TLS with different types of supported keys. - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pkcs1_sha1 TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pkcs1_sha256 TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pkcs1_sha384 TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pkcs1_sha512 TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 ec_rsa_pkcs1_sha256 TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 ecdsa_sha1 TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 ecdsa_secp384r1_sha384 + * @run main/othervm TLSTest TLSv1.3 rsa_pkcs1_sha1 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 rsa_pkcs1_sha256 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 rsa_pkcs1_sha384 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 rsa_pkcs1_sha512 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 ec_rsa_pkcs1_sha256 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 ecdsa_sha1 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 ecdsa_secp384r1_sha384 * TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 ecdsa_secp521r1_sha512 + * @run main/othervm TLSTest TLSv1.3 ecdsa_secp521r1_sha512 * TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_rsae_sha256 TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_rsae_sha384 TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_rsae_sha512 TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_pss_sha256 TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_pss_sha384 TLS_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_pss_sha512 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_rsae_sha256 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_rsae_sha384 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_rsae_sha512 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_pss_sha256 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_pss_sha384 TLS_AES_128_GCM_SHA256 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_pss_sha512 TLS_AES_128_GCM_SHA256 * - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pkcs1_sha1 TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pkcs1_sha256 TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pkcs1_sha384 TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pkcs1_sha512 TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 ec_rsa_pkcs1_sha256 TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 ecdsa_sha1 TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 ecdsa_secp384r1_sha384 + * @run main/othervm TLSTest TLSv1.3 rsa_pkcs1_sha1 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 rsa_pkcs1_sha256 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 rsa_pkcs1_sha384 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 rsa_pkcs1_sha512 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 ec_rsa_pkcs1_sha256 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 ecdsa_sha1 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 ecdsa_secp384r1_sha384 * TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 ecdsa_secp521r1_sha512 + * @run main/othervm TLSTest TLSv1.3 ecdsa_secp521r1_sha512 * TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_rsae_sha256 TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_rsae_sha384 TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_rsae_sha512 TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_pss_sha256 TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_pss_sha384 TLS_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.3 rsa_pss_pss_sha512 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_rsae_sha256 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_rsae_sha384 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_rsae_sha512 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_pss_sha256 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_pss_sha384 TLS_AES_256_GCM_SHA384 + * @run main/othervm TLSTest TLSv1.3 rsa_pss_pss_sha512 TLS_AES_256_GCM_SHA384 * - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 rsa_pkcs1_sha1 TLS_RSA_WITH_AES_128_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 rsa_pkcs1_sha256 + * @run main/othervm TLSTest TLSv1.2 rsa_pkcs1_sha1 TLS_RSA_WITH_AES_128_CBC_SHA + * @run main/othervm TLSTest TLSv1.2 rsa_pkcs1_sha256 * TLS_RSA_WITH_AES_128_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 rsa_pkcs1_sha384 + * @run main/othervm TLSTest TLSv1.2 rsa_pkcs1_sha384 * TLS_RSA_WITH_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 rsa_pkcs1_sha512 + * @run main/othervm TLSTest TLSv1.2 rsa_pkcs1_sha512 * TLS_RSA_WITH_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 ec_rsa_pkcs1_sha256 + * @run main/othervm TLSTest TLSv1.2 ec_rsa_pkcs1_sha256 * TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 ecdsa_sha1 + * @run main/othervm TLSTest TLSv1.2 ecdsa_sha1 * TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 ecdsa_secp384r1_sha384 + * @run main/othervm TLSTest TLSv1.2 ecdsa_secp384r1_sha384 * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 ecdsa_secp521r1_sha512 + * @run main/othervm TLSTest TLSv1.2 ecdsa_secp521r1_sha512 * TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 rsa_pss_rsae_sha256 + * @run main/othervm TLSTest TLSv1.2 rsa_pss_rsae_sha256 * TLS_RSA_WITH_AES_256_CBC_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 rsa_pss_rsae_sha384 + * @run main/othervm TLSTest TLSv1.2 rsa_pss_rsae_sha384 * TLS_RSA_WITH_AES_256_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 rsa_pss_rsae_sha512 + * @run main/othervm TLSTest TLSv1.2 rsa_pss_rsae_sha512 * TLS_RSA_WITH_AES_128_CBC_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 rsa_pss_pss_sha256 + * @run main/othervm TLSTest TLSv1.2 rsa_pss_pss_sha256 * TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 rsa_pss_pss_sha384 + * @run main/othervm TLSTest TLSv1.2 rsa_pss_pss_sha384 * TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.2 rsa_pss_pss_sha512 + * @run main/othervm TLSTest TLSv1.2 rsa_pss_pss_sha512 * TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 * - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.1 rsa_pkcs1_sha1 TLS_RSA_WITH_AES_128_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.1 rsa_pkcs1_sha256 + * @run main/othervm TLSTest TLSv1.1 rsa_pkcs1_sha1 TLS_RSA_WITH_AES_128_CBC_SHA + * @run main/othervm TLSTest TLSv1.1 rsa_pkcs1_sha256 * TLS_RSA_WITH_AES_256_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.1 rsa_pkcs1_sha384 + * @run main/othervm TLSTest TLSv1.1 rsa_pkcs1_sha384 * TLS_RSA_WITH_AES_128_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.1 rsa_pkcs1_sha512 + * @run main/othervm TLSTest TLSv1.1 rsa_pkcs1_sha512 * TLS_RSA_WITH_AES_256_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.1 rsa_pss_rsae_sha256 + * @run main/othervm TLSTest TLSv1.1 rsa_pss_rsae_sha256 * TLS_RSA_WITH_AES_128_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.1 rsa_pss_rsae_sha384 + * @run main/othervm TLSTest TLSv1.1 rsa_pss_rsae_sha384 * TLS_RSA_WITH_AES_256_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1.1 rsa_pss_rsae_sha512 + * @run main/othervm TLSTest TLSv1.1 rsa_pss_rsae_sha512 * TLS_RSA_WITH_AES_128_CBC_SHA * - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1 rsa_pkcs1_sha1 TLS_RSA_WITH_AES_128_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1 rsa_pkcs1_sha256 TLS_RSA_WITH_AES_256_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1 rsa_pkcs1_sha384 TLS_RSA_WITH_AES_128_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1 rsa_pkcs1_sha512 TLS_RSA_WITH_AES_256_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1 rsa_pss_rsae_sha256 + * @run main/othervm TLSTest TLSv1 rsa_pkcs1_sha1 TLS_RSA_WITH_AES_128_CBC_SHA + * @run main/othervm TLSTest TLSv1 rsa_pkcs1_sha256 TLS_RSA_WITH_AES_256_CBC_SHA + * @run main/othervm TLSTest TLSv1 rsa_pkcs1_sha384 TLS_RSA_WITH_AES_128_CBC_SHA + * @run main/othervm TLSTest TLSv1 rsa_pkcs1_sha512 TLS_RSA_WITH_AES_256_CBC_SHA + * @run main/othervm TLSTest TLSv1 rsa_pss_rsae_sha256 * TLS_RSA_WITH_AES_128_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1 rsa_pss_rsae_sha384 + * @run main/othervm TLSTest TLSv1 rsa_pss_rsae_sha384 * TLS_RSA_WITH_AES_256_CBC_SHA - * @run main/othervm -Djavax.net.debug=ssl,handshake TLSTest TLSv1 rsa_pss_rsae_sha512 + * @run main/othervm TLSTest TLSv1 rsa_pss_rsae_sha512 * TLS_RSA_WITH_AES_128_CBC_SHA */ public class TLSTest { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=ssl,handshake + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + private volatile static boolean clientRenegoReady = false; public static void main(String[] args) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "ssl,handshake"); + } final String tlsProtocol = args[0]; final KeyType keyType = KeyType.valueOf(args[1]); diff --git a/test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java b/test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java index 3fabc5bd73c..f21b7b32b6a 100644 --- a/test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.java +++ b/test/jdk/javax/net/ssl/TLSCommon/TLSWithEdDSA.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 @@ -24,8 +24,6 @@ /* * SunJSSE does not support dynamic system properties, no way to re-use * system properties in samevm/agentvm mode. - * For extra debugging output, add -Djavax.net.debug=ssl:handshake into the - * run directive below. */ /* @@ -74,6 +72,18 @@ import javax.net.ssl.X509KeyManager; import jdk.test.lib.security.SecurityUtils; public class TLSWithEdDSA extends SSLSocketTemplate { + + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=ssl,handshake + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + private static final String PASSWD = "passphrase"; private static final String DEF_TRUST_ANCHORS = "CA_DSA_1024:CA_DSA_2048:" + "CA_ECDSA_SECP256R1:CA_ECDSA_SECP384R1:CA_ECDSA_SECP521R1:" + @@ -556,6 +566,10 @@ public class TLSWithEdDSA extends SSLSocketTemplate { } public static void main(String[] args) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "ssl,handshake"); + } + SecurityUtils.removeFromDisabledTlsAlgs("TLSv1.1", "TLSv1"); certFac = CertificateFactory.getInstance("X.509"); String testFormat; diff --git a/test/jdk/javax/net/ssl/TLSv12/ShortRSAKey512.java b/test/jdk/javax/net/ssl/TLSv12/ShortRSAKey512.java index 4d4331dc973..3f8e5e4e6a5 100644 --- a/test/jdk/javax/net/ssl/TLSv12/ShortRSAKey512.java +++ b/test/jdk/javax/net/ssl/TLSv12/ShortRSAKey512.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 ShortRSAKey512 extends SSLContextTemplate { /* * Turn on SSL debugging? */ - static boolean debug = true; + static boolean debug = false; /* * Define the server side of the test. diff --git a/test/jdk/javax/net/ssl/TLSv13/ClientHelloKeyShares.java b/test/jdk/javax/net/ssl/TLSv13/ClientHelloKeyShares.java index 56f37a9e4f1..efb9895b33c 100644 --- a/test/jdk/javax/net/ssl/TLSv13/ClientHelloKeyShares.java +++ b/test/jdk/javax/net/ssl/TLSv13/ClientHelloKeyShares.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 @@ -22,8 +22,7 @@ */ // SunJSSE does not support dynamic system properties, no way to re-use -// system properties in samevm/agentvm mode. For further debugging output -// set the -Djavax.net.debug=ssl:handshake property on the @run lines. +// system properties in samevm/agentvm mode. /* * @test @@ -46,6 +45,17 @@ import java.util.*; public class ClientHelloKeyShares { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=ssl,handshake + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + // Some TLS constants we'll use for testing private static final int TLS_REC_HANDSHAKE = 22; private static final int HELLO_EXT_SUPP_GROUPS = 10; @@ -58,6 +68,10 @@ public class ClientHelloKeyShares { private static final int NG_X448 = 0x001E; public static void main(String args[]) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "ssl,handshake"); + } + // Arguments to this test are an abitrary number of integer // values which will be the expected NamedGroup IDs in the key_share // extension. Expected named group assertions may also be affected diff --git a/test/jdk/javax/net/ssl/TLSv13/HRRKeyShares.java b/test/jdk/javax/net/ssl/TLSv13/HRRKeyShares.java index 313b2c5084b..560faf87049 100644 --- a/test/jdk/javax/net/ssl/TLSv13/HRRKeyShares.java +++ b/test/jdk/javax/net/ssl/TLSv13/HRRKeyShares.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 @@ -22,8 +22,7 @@ */ // SunJSSE does not support dynamic system properties, no way to re-use -// system properties in samevm/agentvm mode. For further debugging output -// set the -Djavax.net.debug=ssl:handshake property on the @run lines. +// system properties in samevm/agentvm mode. /* * @test @@ -48,6 +47,16 @@ import jdk.test.lib.Utils; public class HRRKeyShares { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=ssl,handshake + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; // Some TLS constants we'll use for testing private static final int TLS_REC_HANDSHAKE = 22; @@ -209,6 +218,11 @@ public class HRRKeyShares { } public static void main(String args[]) throws Exception { + + if (debug) { + System.setProperty("javax.net.debug", "ssl,handshake"); + } + System.out.println("Test 1: Good HRR exchange using secp384r1"); hrrKeyShareTest(NG_SECP384R1, true); System.out.println(); diff --git a/test/jdk/javax/net/ssl/compatibility/ClientHelloProcessing.java b/test/jdk/javax/net/ssl/compatibility/ClientHelloProcessing.java index c147f732ec5..4c1b621b180 100644 --- a/test/jdk/javax/net/ssl/compatibility/ClientHelloProcessing.java +++ b/test/jdk/javax/net/ssl/compatibility/ClientHelloProcessing.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,6 +60,17 @@ import java.util.Objects; public class ClientHelloProcessing { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=ssl:handshake + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + private static final ByteBuffer SERVOUTBUF = ByteBuffer.wrap("Server Side".getBytes()); @@ -476,7 +487,11 @@ public class ClientHelloProcessing { public static void main(String[] args) throws Exception { boolean allGood = true; - System.setProperty("javax.net.debug", "ssl:handshake"); + + if (debug) { + System.setProperty("javax.net.debug", "ssl:handshake"); + } + trustMgrFac = makeTrustManagerFactory(trustFilename, passwd); keyMgrFac = makeKeyManagerFactory(keyFilename, passwd); diff --git a/test/jdk/javax/net/ssl/templates/SSLEngineTemplate.java b/test/jdk/javax/net/ssl/templates/SSLEngineTemplate.java index 2c1cfaa44ef..fed82d1164f 100644 --- a/test/jdk/javax/net/ssl/templates/SSLEngineTemplate.java +++ b/test/jdk/javax/net/ssl/templates/SSLEngineTemplate.java @@ -54,6 +54,18 @@ import java.nio.ByteBuffer; * produced. */ public class SSLEngineTemplate extends SSLContextTemplate { + + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=all + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + protected final SSLEngine clientEngine; // client Engine protected final ByteBuffer clientOut; // write side of clientEngine protected final ByteBuffer clientIn; // read side of clientEngine @@ -139,6 +151,10 @@ public class SSLEngineTemplate extends SSLContextTemplate { } public static void main(String[] args) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + new SSLEngineTemplate().runTest(); } diff --git a/test/jdk/javax/net/ssl/templates/SSLSocketTemplate.java b/test/jdk/javax/net/ssl/templates/SSLSocketTemplate.java index 51706cec927..9d1b1fe94c4 100644 --- a/test/jdk/javax/net/ssl/templates/SSLSocketTemplate.java +++ b/test/jdk/javax/net/ssl/templates/SSLSocketTemplate.java @@ -58,11 +58,26 @@ import java.util.concurrent.TimeUnit; */ public class SSLSocketTemplate extends SSLContextTemplate { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=all + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + /* * ================== * Run the test case. */ public static void main(String[] args) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + (new SSLSocketTemplate()).run(); } diff --git a/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.java b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.java index 20b4c39afb1..cbdabea4a19 100644 --- a/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.java +++ b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA.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 @@ -27,7 +27,6 @@ * @library /test/lib * @summary SSLEngine throws IAE during parsing of X500Principal * @run main/othervm TestBadDNForPeerCA - * @run main/othervm -Djavax.net.debug=all TestBadDNForPeerCA */ import javax.net.ssl.KeyManagerFactory; @@ -45,6 +44,16 @@ import java.util.Base64; public class TestBadDNForPeerCA { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=all + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; private static final String proto = "TLSv1.3"; @@ -85,6 +94,10 @@ public class TestBadDNForPeerCA { */ public static void main(String[] args) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + TestBadDNForPeerCA test = new TestBadDNForPeerCA(); try { diff --git a/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.java b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.java index 527ceb406c6..70405b61ab3 100644 --- a/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.java +++ b/test/jdk/sun/security/ssl/SSLEngineImpl/TestBadDNForPeerCA12.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 @@ -27,7 +27,6 @@ * @library /test/lib * @summary SSLEngine throws IAE during parsing of X500Principal * @run main/othervm TestBadDNForPeerCA12 - * @run main/othervm -Djavax.net.debug=all TestBadDNForPeerCA12 */ import javax.net.ssl.KeyManagerFactory; @@ -45,6 +44,17 @@ import java.util.Base64; public class TestBadDNForPeerCA12 { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=all + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + // Test was originally written for TLSv1.2 private static final String proto = "TLSv1.2"; @@ -108,6 +118,10 @@ public class TestBadDNForPeerCA12 { */ public static void main(String[] args) throws Exception { + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + TestBadDNForPeerCA12 test = new TestBadDNForPeerCA12(); try { diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/NoInvalidateSocketException.java b/test/jdk/sun/security/ssl/SSLSessionImpl/NoInvalidateSocketException.java index 696eb58d463..977e005daf3 100644 --- a/test/jdk/sun/security/ssl/SSLSessionImpl/NoInvalidateSocketException.java +++ b/test/jdk/sun/security/ssl/SSLSessionImpl/NoInvalidateSocketException.java @@ -52,6 +52,18 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; public class NoInvalidateSocketException extends SSLSocketTemplate { + + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=ssl,session + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + private static final int ITERATIONS = 10; // This controls how long the main thread waits before closing the socket. @@ -73,8 +85,8 @@ public class NoInvalidateSocketException extends SSLSocketTemplate { private static volatile boolean finished = false; public static void main(String[] args) throws Exception { - if (System.getProperty("javax.net.debug") == null) { - System.setProperty("javax.net.debug", "session"); + if (debug) { + System.setProperty("javax.net.debug", "ssl,session"); } if (args != null && args.length >= 1) { diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeClientTLS12withSNI.java b/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeClientTLS12withSNI.java index c9768c1756c..b21d7aa4e31 100644 --- a/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeClientTLS12withSNI.java +++ b/test/jdk/sun/security/ssl/SSLSessionImpl/ResumeClientTLS12withSNI.java @@ -26,7 +26,7 @@ * @bug 8350830 * @summary TLS 1.2 Client session resumption having ServerNameIndication * @modules java.base/sun.security.tools.keytool - * @run main/othervm -Djavax.net.debug=all ResumeClientTLS12withSNI + * @run main/othervm ResumeClientTLS12withSNI */ import javax.net.ssl.*; @@ -41,6 +41,17 @@ import java.util.*; public class ResumeClientTLS12withSNI { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=all + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + /* * Enables logging of the SSLEngine operations. */ @@ -77,6 +88,11 @@ public class ResumeClientTLS12withSNI { * Main entry point for this test. */ public static void main(String args[]) throws Exception { + + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + Files.deleteIfExists(Path.of(keyFilename)); sun.security.tools.keytool.Main.main( diff --git a/test/jdk/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java b/test/jdk/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java index 145a68a6b0e..d085c1fe890 100644 --- a/test/jdk/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java +++ b/test/jdk/sun/security/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 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 @@ -32,7 +32,7 @@ * @modules jdk.crypto.ec * @library /javax/net/ssl/templates * @summary Calling setWantClientAuth(true) disables anonymous suites - * @run main/othervm -Djavax.net.debug=all AnonCipherWithWantClientAuth + * @run main/othervm AnonCipherWithWantClientAuth */ import java.io.InputStream; @@ -41,10 +41,27 @@ import java.security.Security; import javax.net.ssl.SSLSocket; public class AnonCipherWithWantClientAuth extends SSLSocketTemplate { + + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=all + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + /* * Run the test case. */ public static void main(String[] args) throws Exception { + + if (debug) { + System.setProperty("javax.net.debug", "all"); + } + // reset the security property to make sure that the algorithms // and keys used in this test are not disabled. Security.setProperty("jdk.tls.disabledAlgorithms", ""); diff --git a/test/jdk/sun/security/ssl/SignatureScheme/SigAlgosExtTestWithTLS12.java b/test/jdk/sun/security/ssl/SignatureScheme/SigAlgosExtTestWithTLS12.java index 43bc40fabf2..351d3ad76a1 100644 --- a/test/jdk/sun/security/ssl/SignatureScheme/SigAlgosExtTestWithTLS12.java +++ b/test/jdk/sun/security/ssl/SignatureScheme/SigAlgosExtTestWithTLS12.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (C) 2021, 2024, Tencent. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -56,6 +56,16 @@ import java.nio.ByteBuffer; import java.util.*; public class SigAlgosExtTestWithTLS12 extends SSLEngineTemplate { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=ssl,handshake + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; private static final boolean CLIENT_AUTH = Boolean.getBoolean("test.clientAuth"); @@ -114,7 +124,9 @@ public class SigAlgosExtTestWithTLS12 extends SSLEngineTemplate { } public static void main(String[] args) throws Exception { - System.setProperty("javax.net.debug", "ssl:handshake"); + if (debug) { + System.setProperty("javax.net.debug", "ssl,handshake"); + } try { new SigAlgosExtTestWithTLS12().run(); diff --git a/test/jdk/sun/security/ssl/SignatureScheme/SigSchemePropOrdering.java b/test/jdk/sun/security/ssl/SignatureScheme/SigSchemePropOrdering.java index b7719e6af19..4299c1cc049 100644 --- a/test/jdk/sun/security/ssl/SignatureScheme/SigSchemePropOrdering.java +++ b/test/jdk/sun/security/ssl/SignatureScheme/SigSchemePropOrdering.java @@ -38,6 +38,16 @@ import java.util.Arrays; import java.util.List; public class SigSchemePropOrdering extends AbstractCheckSignatureSchemes { + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=ssl:handshake + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; private static final String SIG_SCHEME_STR = "rsa_pkcs1_sha256,rsa_pss_rsae_sha256,rsa_pss_pss_sha256," + @@ -48,7 +58,10 @@ public class SigSchemePropOrdering extends AbstractCheckSignatureSchemes { } public static void main(String[] args) throws Exception { - System.setProperty("javax.net.debug", "ssl:handshake"); + if (debug) { + System.setProperty("javax.net.debug", "ssl:handshake"); + } + System.setProperty("jdk.tls.client.SignatureSchemes", SIG_SCHEME_STR); System.setProperty("jdk.tls.server.SignatureSchemes", SIG_SCHEME_STR); new SigSchemePropOrdering().run(); diff --git a/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.java b/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.java index 57b16ed7862..6e78c6b4c73 100644 --- a/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.java +++ b/test/jdk/sun/security/ssl/Stapling/StatusResponseManager.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 @@ -28,7 +28,6 @@ * jdk.test.lib.security.CertificateBuilder * @bug 8046321 8339403 * @summary OCSP Stapling for TLS - * @run main/othervm -Djavax.net.debug=ssl:respmgr - * java.base/sun.security.ssl.StatusResponseManagerTests + * @run main/othervm java.base/sun.security.ssl.StatusResponseManagerTests */ diff --git a/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java b/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java index bcfc1290cf0..c7ecbe9f13c 100644 --- a/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java +++ b/test/jdk/sun/security/ssl/Stapling/java.base/sun/security/ssl/StatusResponseManagerTests.java @@ -47,7 +47,17 @@ import static sun.security.ssl.CertStatusExtension.*; */ public class StatusResponseManagerTests { - private static final boolean debug = true; + /* + * Enables the JSSE system debugging system property: + * + * -Djavax.net.debug=ssl:respmgr + * + * This gives a lot of low-level information about operations underway, + * including specific handshake messages, and might be best examined + * after gaining some familiarity with this application. + */ + private static final boolean debug = false; + private static final boolean ocspDebug = false; private static Field responseCacheField; @@ -72,6 +82,11 @@ public class StatusResponseManagerTests { static X509Certificate[] chain; public static void main(String[] args) throws Exception { + + if (debug) { + System.setProperty("javax.net.debug", "ssl:respmgr"); + } + responseCacheField = StatusResponseManager.class.getDeclaredField("responseCache"); responseCacheField.setAccessible(true); diff --git a/test/jdk/sun/security/ssl/TEST.properties b/test/jdk/sun/security/ssl/TEST.properties new file mode 100644 index 00000000000..741c2565067 --- /dev/null +++ b/test/jdk/sun/security/ssl/TEST.properties @@ -0,0 +1 @@ +maxOutputSize=500000 From 3f07710270dbe7268f21828dff20e2eb810b1e70 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Tue, 16 Dec 2025 23:17:29 +0000 Subject: [PATCH 031/390] 8373441: Remove DCmdFactory::_enabled Reviewed-by: kevinw, fparain, jsjolen --- src/hotspot/share/jfr/dcmd/jfrDcmds.cpp | 14 +-- .../share/logging/logDiagnosticCommand.cpp | 2 +- .../share/services/diagnosticCommand.cpp | 111 +++++++++--------- .../share/services/diagnosticFramework.cpp | 7 +- .../share/services/diagnosticFramework.hpp | 31 ++--- src/hotspot/share/services/management.cpp | 6 +- .../management/DiagnosticCommandMBean.java | 4 +- 7 files changed, 77 insertions(+), 98 deletions(-) diff --git a/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp b/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp index d18136e1570..549d879de99 100644 --- a/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp +++ b/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp @@ -47,14 +47,14 @@ bool register_jfr_dcmds() { uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean; - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); // JFR.query Uncomment when developing new queries for the JFR.view command - // DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, true)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + // DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, /*hidden=*/true)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); return true; } diff --git a/src/hotspot/share/logging/logDiagnosticCommand.cpp b/src/hotspot/share/logging/logDiagnosticCommand.cpp index adf596afc94..c9b1015ab45 100644 --- a/src/hotspot/share/logging/logDiagnosticCommand.cpp +++ b/src/hotspot/share/logging/logDiagnosticCommand.cpp @@ -46,7 +46,7 @@ LogDiagnosticCommand::LogDiagnosticCommand(outputStream* output, bool heap_alloc void LogDiagnosticCommand::registerCommand() { uint32_t full_visibility = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean; - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_visibility, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_visibility)); } void LogDiagnosticCommand::execute(DCmdSource source, TRAPS) { diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index 91b23904676..0ff7f445d24 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp @@ -98,78 +98,78 @@ void DCmd::register_dcmds(){ // Third argument specifies if the command is hidden uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean; - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); #if INCLUDE_SERVICES - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(DCmd_Source_Internal | DCmd_Source_AttachAPI, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(DCmd_Source_Internal | DCmd_Source_AttachAPI)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); #if INCLUDE_JVMTI // Both JVMTI and SERVICES have to be enabled to have this dcmd - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); #endif // INCLUDE_JVMTI #endif // INCLUDE_SERVICES #if INCLUDE_JVMTI - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); #endif // INCLUDE_JVMTI - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); #if INCLUDE_JVMTI - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); #endif // INCLUDE_JVMTI - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); #ifdef LINUX - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); #endif // LINUX #if defined(LINUX) || defined(_WIN64) || defined(__APPLE__) - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true,false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true,false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); #endif // LINUX or WINDOWS or MacOS - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); // Enhanced JMX Agent Support // These commands not currently exported via the DiagnosticCommandMBean uint32_t jmx_agent_export_flags = DCmd_Source_Internal | DCmd_Source_AttachAPI; - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags, true,false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags, true,false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags, true,false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags, true,false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(jmx_agent_export_flags)); #if INCLUDE_CDS - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); #endif // INCLUDE_CDS - DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export, true, false)); + DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl(full_export)); } HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), @@ -192,8 +192,7 @@ void HelpDCmd::execute(DCmdSource source, TRAPS) { for (int i = 0; i < cmd_list->length(); i++) { DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i), strlen(cmd_list->at(i))); - output()->print_cr("%s%s", factory->name(), - factory->is_enabled() ? "" : " [disabled]"); + output()->print_cr("%s", factory->name()); output()->print_cr("\t%s", factory->description()); output()->cr(); factory = factory->next(); @@ -203,8 +202,7 @@ void HelpDCmd::execute(DCmdSource source, TRAPS) { DCmdFactory* factory = DCmdFactory::factory(source, _cmd.value(), strlen(_cmd.value())); if (factory != nullptr) { - output()->print_cr("%s%s", factory->name(), - factory->is_enabled() ? "" : " [disabled]"); + output()->print_cr("%s", factory->name()); output()->print_cr("%s", factory->description()); output()->print_cr("\nImpact: %s", factory->impact()); output()->cr(); @@ -223,8 +221,7 @@ void HelpDCmd::execute(DCmdSource source, TRAPS) { for (int i = 0; i < cmd_list->length(); i++) { DCmdFactory* factory = DCmdFactory::factory(source, cmd_list->at(i), strlen(cmd_list->at(i))); - output()->print_cr("%s%s", factory->name(), - factory->is_enabled() ? "" : " [disabled]"); + output()->print_cr("%s", factory->name()); factory = factory->_next; } output()->print_cr("\nFor more information about a specific command use 'help '."); diff --git a/src/hotspot/share/services/diagnosticFramework.cpp b/src/hotspot/share/services/diagnosticFramework.cpp index c37fe7b4e1e..71cc461f161 100644 --- a/src/hotspot/share/services/diagnosticFramework.cpp +++ b/src/hotspot/share/services/diagnosticFramework.cpp @@ -563,10 +563,6 @@ DCmd* DCmdFactory::create_local_DCmd(DCmdSource source, CmdLine &line, outputStream* out, TRAPS) { DCmdFactory* f = factory(source, line.cmd_addr(), line.cmd_len()); if (f != nullptr) { - if (!f->is_enabled()) { - THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), - f->disabled_message()); - } return f->create_resource_instance(out); } THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), @@ -594,8 +590,7 @@ GrowableArray* DCmdFactory::DCmdInfo_list(DCmdSource source ) { if (!factory->is_hidden() && (factory->export_flags() & source)) { array->append(new DCmdInfo(factory->name(), factory->description(), factory->impact(), - factory->num_arguments(), - factory->is_enabled())); + factory->num_arguments())); } factory = factory->next(); } diff --git a/src/hotspot/share/services/diagnosticFramework.hpp b/src/hotspot/share/services/diagnosticFramework.hpp index 206b5ed27b4..5f9253b492e 100644 --- a/src/hotspot/share/services/diagnosticFramework.hpp +++ b/src/hotspot/share/services/diagnosticFramework.hpp @@ -117,21 +117,18 @@ protected: const char* const _description; /* Short description */ const char* const _impact; /* Impact on the JVM */ const int _num_arguments; /* Number of supported options or arguments */ - const bool _is_enabled; /* True if the diagnostic command can be invoked, false otherwise */ public: DCmdInfo(const char* name, const char* description, const char* impact, - int num_arguments, - bool enabled) + int num_arguments) : _name(name), _description(description), _impact(impact), - _num_arguments(num_arguments), _is_enabled(enabled) {} + _num_arguments(num_arguments) {} const char* name() const { return _name; } bool name_equals(const char* cmd_name) const; const char* description() const { return _description; } const char* impact() const { return _impact; } int num_arguments() const { return _num_arguments; } - bool is_enabled() const { return _is_enabled; } }; // A DCmdArgumentInfo instance provides a description of a diagnostic command @@ -233,8 +230,6 @@ public: // static const char* name() { return "";} // static const char* description() { return "";} - static const char* disabled_message() { return "Diagnostic command currently disabled"; } - // The impact() method returns a description of the intrusiveness of the diagnostic // command on the Java Virtual Machine behavior. The rational for this method is that some // diagnostic commands can seriously disrupt the behavior of the Java Virtual Machine @@ -337,8 +332,7 @@ public: }; // Diagnostic commands are not directly instantiated but created with a factory. -// Each diagnostic command class has its own factory. The DCmdFactory class also -// manages the status of the diagnostic command (hidden, enabled). A DCmdFactory +// Each diagnostic command class has its own factory. A DCmdFactory // has to be registered to make the diagnostic command available (see // management.cpp) class DCmdFactory: public CHeapObj { @@ -350,10 +344,6 @@ private: // Pointer to the next factory in the singly-linked list of registered // diagnostic commands DCmdFactory* _next; - // When disabled, a diagnostic command cannot be executed. Any attempt to - // execute it will result in the printing of the disabled message without - // instantiating the command. - const bool _enabled; // When hidden, a diagnostic command doesn't appear in the list of commands // provided by the 'help' command. const bool _hidden; @@ -361,10 +351,9 @@ private: const int _num_arguments; public: - DCmdFactory(int num_arguments, uint32_t flags, bool enabled, bool hidden) - : _next(nullptr), _enabled(enabled), _hidden(hidden), + DCmdFactory(int num_arguments, uint32_t flags, bool hidden) + : _next(nullptr), _hidden(hidden), _export_flags(flags), _num_arguments(num_arguments) {} - bool is_enabled() const { return _enabled; } bool is_hidden() const { return _hidden; } uint32_t export_flags() const { return _export_flags; } int num_arguments() const { return _num_arguments; } @@ -373,11 +362,8 @@ public: virtual const char* name() const = 0; virtual const char* description() const = 0; virtual const char* impact() const = 0; - virtual const char* disabled_message() const = 0; // Register a DCmdFactory to make a diagnostic command available. // Once registered, a diagnostic command must not be unregistered. - // To prevent a diagnostic command from being executed, just set the - // enabled flag to false. static int register_DCmdFactory(DCmdFactory* factory); static DCmdFactory* factory(DCmdSource source, const char* cmd, size_t len); // Returns a resourceArea allocated diagnostic command for the given command line @@ -401,8 +387,8 @@ private: // where this template is used to create and register factories. template class DCmdFactoryImpl : public DCmdFactory { public: - DCmdFactoryImpl(uint32_t flags, bool enabled, bool hidden) : - DCmdFactory(get_num_arguments(), flags, enabled, hidden) { } + DCmdFactoryImpl(uint32_t flags, bool hidden = false) : + DCmdFactory(get_num_arguments(), flags, hidden) { } // Returns a resourceArea allocated instance DCmd* create_resource_instance(outputStream* output) const { return new DCmdClass(output, false); @@ -416,9 +402,6 @@ public: const char* impact() const { return DCmdClass::impact(); } - const char* disabled_message() const { - return DCmdClass::disabled_message(); - } private: #ifdef ASSERT diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp index cc26e2e1352..290e4839c96 100644 --- a/src/hotspot/share/services/management.cpp +++ b/src/hotspot/share/services/management.cpp @@ -2032,7 +2032,11 @@ JVM_ENTRY(void, jmm_GetDiagnosticCommandInfo(JNIEnv *env, jobjectArray cmds, infoArray[i].description = info->description(); infoArray[i].impact = info->impact(); infoArray[i].num_arguments = info->num_arguments(); - infoArray[i].enabled = info->is_enabled(); + + // All registered DCmds are always enabled. We set the dcmdInfo::enabled + // field to true to be compatible with the Java API + // com.sun.management.internal.DiagnosticCommandInfo. + infoArray[i].enabled = true; } JVM_END diff --git a/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java b/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java index d5fedf93855..994757f17c3 100644 --- a/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java +++ b/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -135,7 +135,7 @@ import javax.management.DynamicMBean; * * * dcmd.enabledboolean - * True if the diagnostic command is enabled, false otherwise + * This field is always true -- diagnostic commands cannot be disabled. * * * dcmd.argumentsDescriptor From e635330ae17fd2ce653ec75fd57fdd72d2512bba Mon Sep 17 00:00:00 2001 From: Anjian Wen Date: Wed, 17 Dec 2025 02:41:19 +0000 Subject: [PATCH 032/390] 8373069: RISC-V: implement GHASH intrinsic Reviewed-by: fjiang, fyang --- src/hotspot/cpu/riscv/assembler_riscv.hpp | 3 + src/hotspot/cpu/riscv/globals_riscv.hpp | 3 +- src/hotspot/cpu/riscv/stubGenerator_riscv.cpp | 71 +++++++++++++++++-- src/hotspot/cpu/riscv/vm_version_riscv.cpp | 16 +++++ src/hotspot/cpu/riscv/vm_version_riscv.hpp | 2 + .../os_cpu/linux_riscv/riscv_hwprobe.cpp | 3 + 6 files changed, 90 insertions(+), 8 deletions(-) diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index 711ae03bf27..b657c1f108d 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -2662,6 +2662,9 @@ enum Nf { INSN(vsha2ch_vv, 0b1110111, 0b010, 0b1, 0b101110); INSN(vsha2cl_vv, 0b1110111, 0b010, 0b1, 0b101111); + // Vector GHASH (Zvkg) Extension + INSN(vghsh_vv, 0b1110111, 0b010, 0b1, 0b101100); + #undef INSN #define INSN(NAME, op, funct3, Vs1, funct6) \ diff --git a/src/hotspot/cpu/riscv/globals_riscv.hpp b/src/hotspot/cpu/riscv/globals_riscv.hpp index c78bfaa8ffd..390ed2daeb9 100644 --- a/src/hotspot/cpu/riscv/globals_riscv.hpp +++ b/src/hotspot/cpu/riscv/globals_riscv.hpp @@ -123,6 +123,7 @@ define_pd_global(intx, InlineSmallCode, 1000); product(bool, UseZvkn, false, EXPERIMENTAL, \ "Use Zvkn group extension, Zvkned, Zvknhb, Zvkb, Zvkt") \ product(bool, UseCtxFencei, false, EXPERIMENTAL, \ - "Use PR_RISCV_CTX_SW_FENCEI_ON to avoid explicit icache flush") + "Use PR_RISCV_CTX_SW_FENCEI_ON to avoid explicit icache flush") \ + product(bool, UseZvkg, false, EXPERIMENTAL, "Use Zvkg instructions") #endif // CPU_RISCV_GLOBALS_RISCV_HPP diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 49c80dce88a..75669d0e89c 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -2655,8 +2655,7 @@ class StubGenerator: public StubCodeGenerator { // x10 - input length // address generate_cipherBlockChaining_encryptAESCrypt() { - assert(UseAESIntrinsics, "Must be"); - assert(UseZvkn, "need AES instructions (Zvkned extension) support"); + assert(UseAESIntrinsics, "need AES instructions (Zvkned extension) support"); __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_cipherBlockChaining_encryptAESCrypt_id; StubCodeMark mark(this, stub_id); @@ -2745,8 +2744,7 @@ class StubGenerator: public StubCodeGenerator { // x10 - input length // address generate_cipherBlockChaining_decryptAESCrypt() { - assert(UseAESIntrinsics, "Must be"); - assert(UseZvkn, "need AES instructions (Zvkned extension) support"); + assert(UseAESIntrinsics, "need AES instructions (Zvkned extension) support"); __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_cipherBlockChaining_decryptAESCrypt_id; StubCodeMark mark(this, stub_id); @@ -2950,9 +2948,7 @@ class StubGenerator: public StubCodeGenerator { // x10 - input length // address generate_counterMode_AESCrypt() { - assert(UseAESCTRIntrinsics, "Must be"); - assert(UseZvkn, "need AES instructions (Zvkned extension) support"); - assert(UseZbb, "need basic bit manipulation (Zbb extension) support"); + assert(UseAESCTRIntrinsics, "need AES instructions (Zvkned extension) and Zbb extension support"); __ align(CodeEntryAlignment); StubId stub_id = StubId::stubgen_counterMode_AESCrypt_id; @@ -3001,6 +2997,63 @@ class StubGenerator: public StubCodeGenerator { return start; } + /** + * Arguments: + * + * Input: + * c_rarg0 - current state address + * c_rarg1 - H key address + * c_rarg2 - data address + * c_rarg3 - number of blocks + * + * Output: + * Updated state at c_rarg0 + */ + address generate_ghash_processBlocks() { + assert(UseGHASHIntrinsics, "need GHASH instructions (Zvkg extension) and Zvbb support"); + + __ align(CodeEntryAlignment); + StubId stub_id = StubId::stubgen_ghash_processBlocks_id; + StubCodeMark mark(this, stub_id); + + address start = __ pc(); + __ enter(); + + Register state = c_rarg0; + Register subkeyH = c_rarg1; + Register data = c_rarg2; + Register blocks = c_rarg3; + + VectorRegister partial_hash = v1; + VectorRegister hash_subkey = v2; + VectorRegister cipher_text = v3; + + const unsigned int BLOCK_SIZE = 16; + + __ vsetivli(x0, 2, Assembler::e64, Assembler::m1); + __ vle64_v(hash_subkey, subkeyH); + __ vrev8_v(hash_subkey, hash_subkey); + __ vle64_v(partial_hash, state); + __ vrev8_v(partial_hash, partial_hash); + + __ vsetivli(x0, 4, Assembler::e32, Assembler::m1); + Label L_ghash_loop; + __ bind(L_ghash_loop); + __ vle32_v(cipher_text, data); + __ addi(data, data, BLOCK_SIZE); + __ vghsh_vv(partial_hash, hash_subkey, cipher_text); + __ subi(blocks, blocks, 1); + __ bnez(blocks, L_ghash_loop); + + __ vsetivli(x0, 2, Assembler::e64, Assembler::m1); + __ vrev8_v(partial_hash, partial_hash); + __ vse64_v(partial_hash, state); + __ leave(); + __ ret(); + + return start; + } + // code for comparing 8 characters of strings with Latin1 and Utf16 encoding void compare_string_8_x_LU(Register tmpL, Register tmpU, Register strL, Register strU, Label& DIFF) { @@ -7227,6 +7280,10 @@ static const int64_t right_3_bits = right_n_bits(3); StubRoutines::_counterMode_AESCrypt = generate_counterMode_AESCrypt(); } + if (UseGHASHIntrinsics) { + StubRoutines::_ghash_processBlocks = generate_ghash_processBlocks(); + } + if (UsePoly1305Intrinsics) { StubRoutines::_poly1305_processBlocks = generate_poly1305_processBlocks(); } diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index 75605f25759..22f19c4f5ea 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -457,6 +457,22 @@ void VM_Version::c2_initialize() { FLAG_SET_DEFAULT(UseAESCTRIntrinsics, false); } } + + if (UseZvkg) { + if (FLAG_IS_DEFAULT(UseGHASHIntrinsics) && UseZvbb) { + FLAG_SET_DEFAULT(UseGHASHIntrinsics, true); + } + + if (UseGHASHIntrinsics && !UseZvbb) { + warning("Cannot enable UseGHASHIntrinsics on cpu without UseZvbb support"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); + } + } else { + if (UseGHASHIntrinsics) { + warning("Cannot enable UseGHASHIntrinsics on cpu without UseZvkg support"); + FLAG_SET_DEFAULT(UseGHASHIntrinsics, false); + } + } } #endif // COMPILER2 diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index 168a3a576d0..03c843efc69 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -289,6 +289,8 @@ class VM_Version : public Abstract_VM_Version { decl(Zvfh , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvfh, &ext_v, &ext_Zfh, nullptr)) \ /* Shorthand for Zvkned + Zvknhb + Zvkb + Zvkt */ \ decl(Zvkn , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvkn, &ext_v, nullptr)) \ + /* Zvkg crypto extension for ghash and gcm */ \ + decl(Zvkg , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT_DEP(UseZvkg, &ext_v, nullptr)) \ #define DECLARE_RV_EXT_FEATURE(PRETTY, LINUX_BIT, FSTRING, FLAGF) \ struct ext_##PRETTY##RVExtFeatureValue : public RVExtFeatureValue { \ diff --git a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp index ec756c44fe6..253f460dca3 100644 --- a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp +++ b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp @@ -256,6 +256,9 @@ void RiscvHwprobe::add_features_from_query_result() { is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKT)) { VM_Version::ext_Zvkn.enable_feature(); } + if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVKG)) { + VM_Version::ext_Zvkg.enable_feature(); + } #endif // ====== non-extensions ====== From e9b4696acc966d96d42880e840c8fe27434e4e1b Mon Sep 17 00:00:00 2001 From: Christian Stein Date: Wed, 17 Dec 2025 07:18:26 +0000 Subject: [PATCH 033/390] 8373097: Save command should create missing parent directories Reviewed-by: jlahoda --- .../jdk/internal/jshell/tool/JShellTool.java | 14 +++++++++++++- test/langtools/jdk/jshell/ToolBasicTest.java | 5 ++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java index 795321253fd..9a030f7e46b 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java @@ -3362,7 +3362,19 @@ public class JShellTool implements MessageHandler { // error occurred, already reported return false; } - try (BufferedWriter writer = Files.newBufferedWriter(toPathResolvingUserHome(filename), + // Create missing parent directories before writing to target file + Path target; + try { + target = toPathResolvingUserHome(filename); + Path parent = target.getParent(); + if (parent != null) { + Files.createDirectories(parent); + } + } catch (Exception e) { + errormsg("jshell.err.file.exception", "/save", filename, e); + return false; + } + try (BufferedWriter writer = Files.newBufferedWriter(target, Charset.defaultCharset(), CREATE, TRUNCATE_EXISTING, WRITE)) { if (at.hasOption("-history")) { diff --git a/test/langtools/jdk/jshell/ToolBasicTest.java b/test/langtools/jdk/jshell/ToolBasicTest.java index 5015d1f64b1..7fba0a9cd44 100644 --- a/test/langtools/jdk/jshell/ToolBasicTest.java +++ b/test/langtools/jdk/jshell/ToolBasicTest.java @@ -585,6 +585,7 @@ public class ToolBasicTest extends ReplToolTesting { Compiler compiler = new Compiler(); Path path = compiler.getPath("testSave.repl"); { + Path pathWithDirectories = compiler.getPath("what/ever/testSave.repl"); List list = Arrays.asList( "int a;", "class A { public String toString() { return \"A\"; } }" @@ -593,9 +594,11 @@ public class ToolBasicTest extends ReplToolTesting { (a) -> assertVariable(a, "int", "a"), (a) -> assertCommand(a, "()", null, null, null, "", ""), (a) -> assertClass(a, "class A { public String toString() { return \"A\"; } }", "class", "A"), - (a) -> assertCommand(a, "/save " + path.toString(), "") + (a) -> assertCommand(a, "/save " + path.toString(), ""), + (a) -> assertCommand(a, "/save " + pathWithDirectories.toString(), "") ); assertEquals(list, Files.readAllLines(path)); + assertEquals(list, Files.readAllLines(pathWithDirectories)); } { List output = new ArrayList<>(); From 94c51ce314eea7a4f188fa0db1bae0e3f3dbd230 Mon Sep 17 00:00:00 2001 From: Jan Lahoda Date: Wed, 17 Dec 2025 07:22:37 +0000 Subject: [PATCH 034/390] 8372635: Lambdas do not copy over SYNTHETIC flag for local variables Reviewed-by: vromero, liach --- .../sun/tools/javac/comp/LambdaToMethod.java | 5 +- .../javac/patterns/SyntheticVariables.java | 138 ++++++++++++++++++ 2 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 test/langtools/tools/javac/patterns/SyntheticVariables.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index b13c9e0fe2b..22cb796870b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -1152,7 +1152,7 @@ public class LambdaToMethod extends TreeTranslator { propagateAnnos = false; break; case LOCAL_VAR: - ret = new VarSymbol(sym.flags() & FINAL, sym.name, sym.type, translatedSym); + ret = new VarSymbol(sym.flags(), sym.name, sym.type, translatedSym); ret.pos = sym.pos; // If sym.data == ElementKind.EXCEPTION_PARAMETER, // set ret.data = ElementKind.EXCEPTION_PARAMETER too. @@ -1164,7 +1164,8 @@ public class LambdaToMethod extends TreeTranslator { } break; case PARAM: - ret = new VarSymbol((sym.flags() & FINAL) | PARAMETER, sym.name, types.erasure(sym.type), translatedSym); + Assert.check((sym.flags() & PARAMETER) != 0); + ret = new VarSymbol(sym.flags(), sym.name, types.erasure(sym.type), translatedSym); ret.pos = sym.pos; break; default: diff --git a/test/langtools/tools/javac/patterns/SyntheticVariables.java b/test/langtools/tools/javac/patterns/SyntheticVariables.java new file mode 100644 index 00000000000..26ece40d656 --- /dev/null +++ b/test/langtools/tools/javac/patterns/SyntheticVariables.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 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. + */ + +/* + * @test + * @bug 8372635 + * @enablePreview + * @summary Verify temporary variables created for pattern matching are + * marked as synthetic. + * @compile -g SyntheticVariables.java + * @run main SyntheticVariables + */ + +import java.io.IOException; +import java.io.InputStream; +import java.lang.classfile.Attributes; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassModel; +import java.lang.classfile.MethodModel; +import java.lang.classfile.attribute.CodeAttribute; +import java.lang.classfile.attribute.LocalVariableTableAttribute; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.stream.Collectors; + +public class SyntheticVariables { + + public static void main(String[] args) throws IOException { + try (InputStream in = Test.class.getClassLoader().getResource(Test.class.getName().replace('.', '/') + ".class").openStream()) { + ClassModel model = ClassFile.of().parse(in.readAllBytes()); + Map name2Method = model.methods().stream().collect(Collectors.toMap(m -> m.methodName().stringValue(), m -> m)); + assertEquals(Set.of("str", "b", "b2", "this", "l", "o"), localVars(name2Method.get("testInMethod"))); + assertEquals(Set.of("str", "b", "b2", "l", "o"), localVars(name2Method.get("lambda$testInLambda$0"))); + } + } + + private static Set localVars(MethodModel method) { + CodeAttribute code = method.findAttribute(Attributes.code()).orElseThrow(); + LocalVariableTableAttribute lvt = code.findAttribute(Attributes.localVariableTable()).orElseThrow(); + return lvt.localVariables() + .stream() + .map(info -> info.name().stringValue()) + .collect(Collectors.toSet()); + } + + private static void assertEquals(Set expected, Set actual) { + if (!Objects.equals(expected, actual)) { + throw new AssertionError("Unexpected value, expected: " + expected + + ", got: " + actual); + } + } + + public record Test(Object o) { + private void testInMethod() { + Object o = create(); + + //synthetic variable for the instanceof's expression + boolean b = o.toString() instanceof String str && str.isEmpty(); + + System.err.println(b); + + //synthetic variable for the switch's selector and index: + switch (create()) { + //synthetic variable for the nested component values, + //and for the synthetic catch over the getters + case Test(Test(String str)) when str.isEmpty() -> System.err.println(1); + case Test(Test(String str)) -> System.err.println(2); + default -> System.err.println(2); + } + + List l = List.of(0); + + //synthetic variable for case where the static and dynamic types + //don't match for primitive patterns: + boolean b2 = l.get(0) instanceof int; + + System.err.println(b2); + } + + private void testInLambda() { + Object o = create(); + Runnable r = () -> { + + //synthetic variable for the instanceof's expression + boolean b = o.toString() instanceof String str && str.isEmpty(); + + System.err.println(b); + + //synthetic variable for the switch's selector and index: + switch (create()) { + //synthetic variable for the nested component values, + //and for the synthetic catch over the getters + case Test(Test(String str)) when str.isEmpty() -> System.err.println(1); + case Test(Test(String str)) -> System.err.println(2); + default -> System.err.println(2); + } + + List l = List.of(0); + + //synthetic variable for case where the static and dynamic types + //don't match for primitive patterns: + boolean b2 = l.get(0) instanceof int; + + System.err.println(b2); + }; + } + private static String val = "v"; + public static Test create() { + try { + return new Test(new Test(val)); + } finally { + val += val; + } + } + } +} From 386ad61458a3901622b92ca56982d728c11b846a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Jeli=C5=84ski?= Date: Wed, 17 Dec 2025 07:49:58 +0000 Subject: [PATCH 035/390] 8373409: java/net/httpclient/http3/H3ErrorHandlingTest.java failed due to deadlock Reviewed-by: dfuchs --- .../internal/net/http/quic/QuicEndpoint.java | 66 +++++++++---------- .../httpclient/http3/H3ErrorHandlingTest.java | 1 + 2 files changed, 31 insertions(+), 36 deletions(-) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicEndpoint.java b/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicEndpoint.java index b1de5ef4bfd..8bdba21594c 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicEndpoint.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/quic/QuicEndpoint.java @@ -1581,34 +1581,30 @@ public abstract sealed class QuicEndpoint implements AutoCloseable peerIssuedResetTokens.replaceAll((tok, c) -> c == from ? to : c); } - public void draining(final QuicPacketReceiver connection) { + public void draining(final QuicConnectionImpl connection) { // remap the connection to a DrainingConnection if (closed) return; + + final long idleTimeout = connection.peerPtoMs() * 3; // 3 PTO + connection.localConnectionIdManager().close(); + DrainingConnection draining = new DrainingConnection(connection.connectionIds(), idleTimeout); + // we can ignore stateless reset in the draining state. + remapPeerIssuedResetToken(connection, draining); + connection.connectionIds().forEach((id) -> - connections.compute(id, this::remapDraining)); + connections.compute(id, (i, r) -> remapDraining(i, r, draining))); + draining.startTimer(); assert !connections.containsValue(connection) : connection; } - private DrainingConnection remapDraining(QuicConnectionId id, QuicPacketReceiver conn) { + private DrainingConnection remapDraining(QuicConnectionId id, QuicPacketReceiver conn, DrainingConnection draining) { if (closed) return null; var debugOn = debug.on() && !Thread.currentThread().isVirtual(); - if (conn instanceof ClosingConnection closing) { + if (conn instanceof QuicConnectionImpl || conn instanceof ClosingConnection) { if (debugOn) debug.log("remapping %s to DrainingConnection", id); - final var draining = closing.toDraining(); - remapPeerIssuedResetToken(closing, draining); - draining.startTimer(); - return draining; - } else if (conn instanceof DrainingConnection draining) { - return draining; - } else if (conn instanceof QuicConnectionImpl impl) { - final long idleTimeout = impl.peerPtoMs() * 3; // 3 PTO - impl.localConnectionIdManager().close(); - if (debugOn) debug.log("remapping %s to DrainingConnection", id); - var draining = new DrainingConnection(conn.connectionIds(), idleTimeout); - // we can ignore stateless reset in the draining state. - remapPeerIssuedResetToken(impl, draining); - draining.startTimer(); return draining; + } else if (conn instanceof DrainingConnection d) { + return d; } else if (conn == null) { // connection absent (was probably removed), don't remap to draining if (debugOn) { @@ -1623,30 +1619,32 @@ public abstract sealed class QuicEndpoint implements AutoCloseable protected void closing(QuicConnectionImpl connection, ByteBuffer datagram) { if (closed) return; - ByteBuffer closing = ByteBuffer.allocate(datagram.limit()); - closing.put(datagram.slice()); - closing.flip(); + ByteBuffer closingDatagram = ByteBuffer.allocate(datagram.limit()); + closingDatagram.put(datagram.slice()); + closingDatagram.flip(); + + final long idleTimeout = connection.peerPtoMs() * 3; // 3 PTO + connection.localConnectionIdManager().close(); + var closingConnection = new ClosingConnection(connection.connectionIds(), idleTimeout, datagram); + remapPeerIssuedResetToken(connection, closingConnection); + connection.connectionIds().forEach((id) -> - connections.compute(id, (i, r) -> remapClosing(i, r, closing))); + connections.compute(id, (i, r) -> remapClosing(i, r, closingConnection))); + closingConnection.startTimer(); assert !connections.containsValue(connection) : connection; } - private ClosedConnection remapClosing(QuicConnectionId id, QuicPacketReceiver conn, ByteBuffer datagram) { + private ClosedConnection remapClosing(QuicConnectionId id, QuicPacketReceiver conn, ClosingConnection closingConnection) { if (closed) return null; var debugOn = debug.on() && !Thread.currentThread().isVirtual(); - if (conn instanceof ClosingConnection closing) { + if (conn instanceof QuicConnectionImpl) { + if (debugOn) debug.log("remapping %s to ClosingConnection", id); + return closingConnection; + } else if (conn instanceof ClosingConnection closing) { // we already have a closing datagram, drop the new one return closing; } else if (conn instanceof DrainingConnection draining) { return draining; - } else if (conn instanceof QuicConnectionImpl impl) { - final long idleTimeout = impl.peerPtoMs() * 3; // 3 PTO - impl.localConnectionIdManager().close(); - if (debugOn) debug.log("remapping %s to ClosingConnection", id); - var closing = new ClosingConnection(conn.connectionIds(), idleTimeout, datagram); - remapPeerIssuedResetToken(impl, closing); - closing.startTimer(); - return closing; } else if (conn == null) { // connection absent (was probably removed), don't remap to closing if (debugOn) { @@ -1896,10 +1894,6 @@ public abstract sealed class QuicEndpoint implements AutoCloseable debug.log("ClosingConnection(%s): dropping %s packet", localConnectionIds, headersType); } } - - private DrainingConnection toDraining() { - return new DrainingConnection(localConnectionIds, maxIdleTimeMs); - } } /** diff --git a/test/jdk/java/net/httpclient/http3/H3ErrorHandlingTest.java b/test/jdk/java/net/httpclient/http3/H3ErrorHandlingTest.java index 4315fd36de5..bb5aeacbb0c 100644 --- a/test/jdk/java/net/httpclient/http3/H3ErrorHandlingTest.java +++ b/test/jdk/java/net/httpclient/http3/H3ErrorHandlingTest.java @@ -71,6 +71,7 @@ import static org.testng.Assert.*; /* * @test + * @bug 8373409 * @key intermittent * @comment testResetControlStream may fail if the client doesn't read the stream type * before the stream is reset, From 9e2008bf5e9a63b640eefc6cc7ec5c4f344c4266 Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Wed, 17 Dec 2025 08:44:46 +0000 Subject: [PATCH 036/390] 8373676: Test javax/net/ssl/HttpsURLConnection/SubjectAltNameIP.java fails on a machine without IPV6 Reviewed-by: jpai, dfuchs --- .../net/ssl/HttpsURLConnection/SubjectAltNameIP.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/jdk/javax/net/ssl/HttpsURLConnection/SubjectAltNameIP.java b/test/jdk/javax/net/ssl/HttpsURLConnection/SubjectAltNameIP.java index 2def2f69d6e..cbd2089e7bd 100644 --- a/test/jdk/javax/net/ssl/HttpsURLConnection/SubjectAltNameIP.java +++ b/test/jdk/javax/net/ssl/HttpsURLConnection/SubjectAltNameIP.java @@ -30,7 +30,7 @@ * @modules java.base/sun.net.util * @comment Insert -Djavax.net.debug=all into the following lines to enable SSL debugging * @run main/othervm SubjectAltNameIP 127.0.0.1 - * @run main/othervm SubjectAltNameIP [::1] + * @run main/othervm SubjectAltNameIP ::1 */ import javax.net.ssl.HandshakeCompletedListener; @@ -166,14 +166,19 @@ public class SubjectAltNameIP { } public static void main(String[] args) throws Exception { + boolean isIpv6Addr = IPAddressUtil.isIPv6LiteralAddress(args[0]); - if (IPAddressUtil.isIPv6LiteralAddress(args[0]) && !IPSupport.hasIPv6()) { + if (isIpv6Addr && !IPSupport.hasIPv6()) { throw new SkippedException("Skipping test - IPv6 is not supported"); } /* * Start the tests. */ - new SubjectAltNameIP(args[0]); + if (isIpv6Addr) { // use the URL notion wrapper + new SubjectAltNameIP("[" + args[0] + "]"); + } else { + new SubjectAltNameIP(args[0]); + } } Thread serverThread = null; From 4924b29fa519996b806ac0f4a7c898085f44bc4c Mon Sep 17 00:00:00 2001 From: Michael McMahon Date: Wed, 17 Dec 2025 08:54:56 +0000 Subject: [PATCH 037/390] 8370655: Check EINTR handling InetAddress implementation and NET_ThrowNew Reviewed-by: alanb --- src/java.base/share/native/libnet/net_util.c | 1 - .../unix/native/libnet/Inet4AddressImpl.c | 34 ++++++++++++------- .../unix/native/libnet/Inet6AddressImpl.c | 32 +++++++++++------ .../unix/native/libnet/net_util_md.c | 15 ++++---- .../unix/native/libnet/net_util_md.h | 13 +++++++ 5 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/java.base/share/native/libnet/net_util.c b/src/java.base/share/native/libnet/net_util.c index 5b356d04b3c..7b148f03cfd 100644 --- a/src/java.base/share/native/libnet/net_util.c +++ b/src/java.base/share/native/libnet/net_util.c @@ -86,7 +86,6 @@ DEF_JNI_OnLoad(JavaVM *vm, void *reserved) /* check if SO_REUSEPORT is supported on this platform */ REUSEPORT_available = reuseport_supported(IPv6_available); - return JNI_VERSION_1_2; } diff --git a/src/java.base/unix/native/libnet/Inet4AddressImpl.c b/src/java.base/unix/native/libnet/Inet4AddressImpl.c index fff524e03ae..f537226c330 100644 --- a/src/java.base/unix/native/libnet/Inet4AddressImpl.c +++ b/src/java.base/unix/native/libnet/Inet4AddressImpl.c @@ -108,7 +108,8 @@ Java_java_net_Inet4AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, hints.ai_flags = AI_CANONNAME; hints.ai_family = AF_INET; - error = getaddrinfo(hostname, NULL, &hints, &res); + NET_RESTARTABLE(error, getaddrinfo(hostname, NULL, &hints, &res), + error == EAI_SYSTEM && errno == EINTR); if (error) { #if defined(MACOSX) @@ -229,17 +230,21 @@ Java_java_net_Inet4AddressImpl_getHostByAddr(JNIEnv *env, jobject this, sa.sin_addr.s_addr = htonl(addr); sa.sin_family = AF_INET; - if (getnameinfo((struct sockaddr *)&sa, sizeof(struct sockaddr_in), - host, sizeof(host), NULL, 0, NI_NAMEREQD)) { - JNU_ThrowByName(env, "java/net/UnknownHostException", NULL); - } else { + int r; + + NET_RESTARTABLE(r, getnameinfo((struct sockaddr *)&sa, sizeof(struct sockaddr_in), + host, sizeof(host), NULL, 0, NI_NAMEREQD), + r == EAI_SYSTEM && errno == EINTR); + + if (r == 0) { ret = (*env)->NewStringUTF(env, host); - if (ret == NULL) { - JNU_ThrowByName(env, "java/net/UnknownHostException", NULL); + if (ret != NULL) { + return ret; } } - return ret; + JNU_ThrowByName(env, "java/net/UnknownHostException", NULL); + return NULL; } /** @@ -283,7 +288,8 @@ tcp_ping4(JNIEnv *env, SOCKETADDRESS *sa, SOCKETADDRESS *netif, jint timeout, SET_NONBLOCKING(fd); sa->sa4.sin_port = htons(7); // echo port - connect_rv = connect(fd, &sa->sa, sizeof(struct sockaddr_in)); + NET_RESTARTABLE(connect_rv, connect(fd, &sa->sa, sizeof(struct sockaddr_in)), + connect_rv == -1 && errno == EINTR); // connection established or refused immediately, either way it means // we were able to reach the host! @@ -397,8 +403,11 @@ ping4(JNIEnv *env, jint fd, SOCKETADDRESS *sa, SOCKETADDRESS *netif, icmp->icmp_cksum = 0; // manually calculate checksum icmp->icmp_cksum = in_cksum((u_short *)icmp, plen); + // send it - n = sendto(fd, sendbuf, plen, 0, &sa->sa, sizeof(struct sockaddr_in)); + NET_RESTARTABLE(n, sendto(fd, sendbuf, plen, 0, &sa->sa, sizeof(struct sockaddr_in)), + n == -1 && errno == EINTR) + if (n < 0 && errno != EINPROGRESS) { #if defined(__linux__) /* @@ -422,8 +431,9 @@ ping4(JNIEnv *env, jint fd, SOCKETADDRESS *sa, SOCKETADDRESS *netif, tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2); if (tmout2 >= 0) { len = sizeof(sa_recv); - n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, - (struct sockaddr *)&sa_recv, &len); + NET_RESTARTABLE(n, recvfrom(fd, recvbuf, sizeof(recvbuf), 0, + (struct sockaddr *)&sa_recv, &len), + n == -1 && errno == EINTR); // check if we received enough data if (n < (jint)sizeof(struct ip)) { continue; diff --git a/src/java.base/unix/native/libnet/Inet6AddressImpl.c b/src/java.base/unix/native/libnet/Inet6AddressImpl.c index 83354356936..8dce4f9cc6b 100644 --- a/src/java.base/unix/native/libnet/Inet6AddressImpl.c +++ b/src/java.base/unix/native/libnet/Inet6AddressImpl.c @@ -227,7 +227,8 @@ Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, hints.ai_flags = AI_CANONNAME; hints.ai_family = lookupCharacteristicsToAddressFamily(characteristics); - error = getaddrinfo(hostname, NULL, &hints, &res); + NET_RESTARTABLE(error, getaddrinfo(hostname, NULL, &hints, &res), + error == EAI_SYSTEM && errno == EINTR); if (error) { #if defined(MACOSX) @@ -430,16 +431,20 @@ Java_java_net_Inet6AddressImpl_getHostByAddr(JNIEnv *env, jobject this, len = sizeof(struct sockaddr_in6); } - if (getnameinfo(&sa.sa, len, host, sizeof(host), NULL, 0, NI_NAMEREQD)) { - JNU_ThrowByName(env, "java/net/UnknownHostException", NULL); - } else { + int r; + + NET_RESTARTABLE(r, getnameinfo(&sa.sa, len, host, sizeof(host), NULL, 0, NI_NAMEREQD), + r == EAI_SYSTEM && errno == EINTR); + + if (r == 0) { ret = (*env)->NewStringUTF(env, host); - if (ret == NULL) { - JNU_ThrowByName(env, "java/net/UnknownHostException", NULL); + if (ret != NULL) { + return ret; } } - return ret; + JNU_ThrowByName(env, "java/net/UnknownHostException", NULL); + return NULL; } /** @@ -483,7 +488,8 @@ tcp_ping6(JNIEnv *env, SOCKETADDRESS *sa, SOCKETADDRESS *netif, jint timeout, SET_NONBLOCKING(fd); sa->sa6.sin6_port = htons(7); // echo port - connect_rv = connect(fd, &sa->sa, sizeof(struct sockaddr_in6)); + NET_RESTARTABLE(connect_rv, connect(fd, &sa->sa, sizeof(struct sockaddr_in6)), + connect_rv == -1 && errno == EINTR); // connection established or refused immediately, either way it means // we were able to reach the host! @@ -604,7 +610,10 @@ ping6(JNIEnv *env, jint fd, SOCKETADDRESS *sa, SOCKETADDRESS *netif, memcpy(sendbuf + sizeof(struct icmp6_hdr), &tv, sizeof(tv)); icmp6->icmp6_cksum = 0; // send it - n = sendto(fd, sendbuf, plen, 0, &sa->sa, sizeof(struct sockaddr_in6)); + + NET_RESTARTABLE(n, sendto(fd, sendbuf, plen, 0, &sa->sa, sizeof(struct sockaddr_in6)), + n == -1 && errno == EINTR); + if (n < 0 && errno != EINPROGRESS) { #if defined(__linux__) /* @@ -628,8 +637,9 @@ ping6(JNIEnv *env, jint fd, SOCKETADDRESS *sa, SOCKETADDRESS *netif, tmout2 = NET_Wait(env, fd, NET_WAIT_READ, tmout2); if (tmout2 >= 0) { len = sizeof(sa_recv); - n = recvfrom(fd, recvbuf, sizeof(recvbuf), 0, - (struct sockaddr *)&sa_recv, &len); + NET_RESTARTABLE(n, recvfrom(fd, recvbuf, sizeof(recvbuf), 0, + (struct sockaddr *)&sa_recv, &len), + n == -1 && errno == EINTR); // check if we received enough data if (n < (jint)sizeof(struct icmp6_hdr)) { continue; diff --git a/src/java.base/unix/native/libnet/net_util_md.c b/src/java.base/unix/native/libnet/net_util_md.c index 9bb6a026961..b0915615d96 100644 --- a/src/java.base/unix/native/libnet/net_util_md.c +++ b/src/java.base/unix/native/libnet/net_util_md.c @@ -76,9 +76,6 @@ NET_ThrowNew(JNIEnv *env, int errorNumber, char *msg) { jio_snprintf(fullMsg, sizeof(fullMsg), "socket closed: %s", msg); JNU_ThrowByName(env, JNU_JAVANETPKG "SocketException", fullMsg); break; - case EINTR: - JNU_ThrowByName(env, JNU_JAVAIOPKG "InterruptedIOException", msg); - break; default: errno = errorNumber; JNU_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException", msg); @@ -627,11 +624,11 @@ NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout) pfd.fd = fd; pfd.events = 0; if (flags & NET_WAIT_READ) - pfd.events |= POLLIN; + pfd.events |= POLLIN; if (flags & NET_WAIT_WRITE) - pfd.events |= POLLOUT; + pfd.events |= POLLOUT; if (flags & NET_WAIT_CONNECT) - pfd.events |= POLLOUT; + pfd.events |= POLLOUT; errno = 0; read_rv = poll(&pfd, 1, nanoTimeout / NET_NSEC_PER_MSEC); @@ -639,13 +636,13 @@ NET_Wait(JNIEnv *env, jint fd, jint flags, jint timeout) newNanoTime = JVM_NanoTime(env, 0); nanoTimeout -= (newNanoTime - prevNanoTime); if (nanoTimeout < NET_NSEC_PER_MSEC) { - return read_rv > 0 ? 0 : -1; + return read_rv > 0 ? 0 : -1; } prevNanoTime = newNanoTime; if (read_rv > 0) { - break; + break; } - } /* while */ + } /* while */ return (nanoTimeout / NET_NSEC_PER_MSEC); } diff --git a/src/java.base/unix/native/libnet/net_util_md.h b/src/java.base/unix/native/libnet/net_util_md.h index 902cf96732f..d6cb3250bbe 100644 --- a/src/java.base/unix/native/libnet/net_util_md.h +++ b/src/java.base/unix/native/libnet/net_util_md.h @@ -80,4 +80,17 @@ void NET_ThrowUnknownHostExceptionWithGaiError(JNIEnv *env, void NET_ThrowByNameWithLastError(JNIEnv *env, const char *name, const char *defaultDetail); +/** + * Invokes CALL in a loop, setting RET to return value. + * Invokes PREDICATE for condition to restart CALL (in loop) + * Return RET otherwise + */ +#define NET_RESTARTABLE(RET,CALL,PREDICATE) \ + while (1) { \ + RET = CALL; \ + if (!(PREDICATE)) { \ + break; \ + } \ + } + #endif /* NET_UTILS_MD_H */ From af18fbd42d2a437dd35f33e557a8906ca0c3bd07 Mon Sep 17 00:00:00 2001 From: Arno Zeller Date: Wed, 17 Dec 2025 09:08:29 +0000 Subject: [PATCH 038/390] 8371559: Intermittent timeouts in test javax/net/ssl/Stapling/HttpsUrlConnClient.java Reviewed-by: mbaesken, myankelevich --- .../net/ssl/Stapling/HttpsUrlConnClient.java | 86 +++++++++++-------- 1 file changed, 48 insertions(+), 38 deletions(-) diff --git a/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java b/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java index b9829621d68..c34311f1689 100644 --- a/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java +++ b/test/jdk/javax/net/ssl/Stapling/HttpsUrlConnClient.java @@ -33,7 +33,11 @@ * @run main/othervm HttpsUrlConnClient RSASSA-PSS RSASSA-PSS */ -import java.io.*; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; import java.math.BigInteger; import java.security.KeyPair; import java.security.KeyPairGenerator; @@ -41,7 +45,9 @@ import java.net.Socket; import java.net.URL; import java.net.HttpURLConnection; import java.net.InetAddress; + import javax.net.ssl.*; + import java.security.KeyStore; import java.security.PublicKey; import java.security.Security; @@ -55,7 +61,16 @@ import java.security.cert.X509Certificate; import java.security.cert.PKIXRevocationChecker; import java.security.spec.PKCS8EncodedKeySpec; import java.text.SimpleDateFormat; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.TimeZone; +import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import jdk.test.lib.security.SimpleOCSPServer; @@ -92,10 +107,6 @@ public class HttpsUrlConnClient { static String INT_ALIAS = "intermediate"; static String SSL_ALIAS = "ssl"; - /* - * Is the server ready to serve? - */ - volatile static boolean serverReady = false; volatile int serverPort = 0; volatile Exception serverException = null; @@ -164,7 +175,7 @@ public class HttpsUrlConnClient { ClientParameters cliParams = new ClientParameters(); cliParams.protocols = allowedProts; ServerParameters servParams = new ServerParameters(); - serverReady = false; + CountDownLatch serverReady = new CountDownLatch(1); System.out.println("====================================="); System.out.println("Stapling enabled, PKIXParameters with"); @@ -192,7 +203,7 @@ public class HttpsUrlConnClient { Security.setProperty("ocsp.enable", "false"); HttpsUrlConnClient sslTest = new HttpsUrlConnClient(cliParams, - servParams); + servParams, serverReady); TestResult tr = sslTest.getResult(); if (!checkClientValidationFailure(tr.clientExc, BasicReason.REVOKED)) { if (tr.clientExc != null) { @@ -219,10 +230,11 @@ public class HttpsUrlConnClient { /* * Define the server side of the test. * - * If the server prematurely exits, serverReady will be set to true + * If the server prematurely exits, serverReady will be counted down * to avoid infinite hangs. */ - void doServerSide(ServerParameters servParams) throws Exception { + void doServerSide(ServerParameters servParams, CountDownLatch serverReady) + throws Exception { // Selectively enable or disable the feature System.setProperty("jdk.tls.server.enableStatusRequestExtension", @@ -274,7 +286,7 @@ public class HttpsUrlConnClient { /* * Signal Client, we're ready for his connect. */ - serverReady = true; + serverReady.countDown(); try (SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept(); BufferedReader in = new BufferedReader( @@ -306,18 +318,13 @@ public class HttpsUrlConnClient { /* * Define the client side of the test. * - * If the server prematurely exits, serverReady will be set to true + * If the server prematurely exits, serverReady will be counted down * to avoid infinite hangs. */ - void doClientSide(ClientParameters cliParams) throws Exception { + void doClientSide(ClientParameters cliParams, CountDownLatch serverReady) + throws Exception { - // Wait 5 seconds for server ready - for (int i = 0; (i < 100 && !serverReady); i++) { - Thread.sleep(50); - } - if (!serverReady) { - throw new RuntimeException("Server not ready yet"); - } + serverReady.await(); // Selectively enable or disable the feature System.setProperty("jdk.tls.client.enableStatusRequestExtension", @@ -373,16 +380,16 @@ public class HttpsUrlConnClient { * * Fork off the other side, then do your work. */ - HttpsUrlConnClient(ClientParameters cliParams, - ServerParameters servParams) throws Exception { + HttpsUrlConnClient(ClientParameters cliParams, ServerParameters servParams, + CountDownLatch serverReady) throws Exception { Exception startException = null; try { if (separateServerThread) { - startServer(servParams, true); - startClient(cliParams, false); + startServer(servParams, true, serverReady); + startClient(cliParams, false, serverReady); } else { - startClient(cliParams, true); - startServer(servParams, false); + startClient(cliParams, true, serverReady); + startServer(servParams, false, serverReady); } } catch (Exception e) { startException = e; @@ -453,51 +460,53 @@ public class HttpsUrlConnClient { return tr; } - final void startServer(ServerParameters servParams, boolean newThread) - throws Exception { + final void startServer(ServerParameters servParams, boolean newThread, + CountDownLatch serverReady) throws IOException { if (newThread) { serverThread = new Thread() { @Override public void run() { try { - doServerSide(servParams); + doServerSide(servParams, serverReady); } catch (Exception e) { /* * Our server thread just died. * * Release the client, if not active already... */ - System.err.println("Server died..."); - serverReady = true; + System.err.println("Server died: " + e); serverException = e; + } finally { + serverReady.countDown(); } } }; serverThread.start(); } else { try { - doServerSide(servParams); + doServerSide(servParams, serverReady); } catch (Exception e) { + System.err.println("Server died: " + e); serverException = e; } finally { - serverReady = true; + serverReady.countDown(); } } } - final void startClient(ClientParameters cliParams, boolean newThread) - throws Exception { + final void startClient(ClientParameters cliParams, boolean newThread, + CountDownLatch serverReady) throws Exception { if (newThread) { clientThread = new Thread() { @Override public void run() { try { - doClientSide(cliParams); + doClientSide(cliParams, serverReady); } catch (Exception e) { /* * Our client thread just died. */ - System.err.println("Client died..."); + System.err.println("Client died: " + e); clientException = e; } } @@ -505,9 +514,10 @@ public class HttpsUrlConnClient { clientThread.start(); } else { try { - doClientSide(cliParams); + doClientSide(cliParams, serverReady); } catch (Exception e) { clientException = e; + System.err.println("Client died: " + e); } } } From fc76403b01c4e801f2a58810deeec2a6ebfa8458 Mon Sep 17 00:00:00 2001 From: Raffaello Giulietti Date: Wed, 17 Dec 2025 09:20:48 +0000 Subject: [PATCH 039/390] 8373798: Refactor java/math tests to use JUnit Reviewed-by: darcy --- .../jdk/java/math/BigDecimal/Constructor.java | 56 +++++--- .../math/BigInteger/LargeValueExceptions.java | 134 ++++++++++-------- 2 files changed, 111 insertions(+), 79 deletions(-) diff --git a/test/jdk/java/math/BigDecimal/Constructor.java b/test/jdk/java/math/BigDecimal/Constructor.java index b7371074225..975d96772a6 100644 --- a/test/jdk/java/math/BigDecimal/Constructor.java +++ b/test/jdk/java/math/BigDecimal/Constructor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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,45 +26,57 @@ * @bug 4259453 8200698 * @summary Test constructors of BigDecimal * @library .. - * @run testng Constructor + * @run junit Constructor */ +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + import java.math.BigDecimal; -import org.testng.annotations.Test; public class Constructor { - @Test(expectedExceptions=NumberFormatException.class) + @Test public void stringConstructor() { - BigDecimal bd = new BigDecimal("1.2e"); + Assertions.assertThrows(NumberFormatException.class, () -> { + BigDecimal bd = new BigDecimal("1.2e"); + }); } - @Test(expectedExceptions=NumberFormatException.class) + @Test public void charArrayConstructorNegativeOffset() { - BigDecimal bd = new BigDecimal(new char[5], -1, 4, null); + Assertions.assertThrows(NumberFormatException.class, () -> { + BigDecimal bd = new BigDecimal(new char[5], -1, 4, null); + }); } - @Test(expectedExceptions=NumberFormatException.class) + @Test public void charArrayConstructorNegativeLength() { - BigDecimal bd = new BigDecimal(new char[5], 0, -1, null); + Assertions.assertThrows(NumberFormatException.class, () -> { + BigDecimal bd = new BigDecimal(new char[5], 0, -1, null); + }); } - @Test(expectedExceptions=NumberFormatException.class) + @Test public void charArrayConstructorIntegerOverflow() { - try { - BigDecimal bd = new BigDecimal(new char[5], Integer.MAX_VALUE - 5, - 6, null); - } catch (NumberFormatException nfe) { - if (nfe.getCause() instanceof IndexOutOfBoundsException) { - throw new RuntimeException - ("NumberFormatException should not have a cause"); - } else { - throw nfe; + Assertions.assertThrows(NumberFormatException.class, () -> { + try { + BigDecimal bd = new BigDecimal(new char[5], Integer.MAX_VALUE - 5, + 6, null); + } catch (NumberFormatException nfe) { + if (nfe.getCause() instanceof IndexOutOfBoundsException) { + throw new RuntimeException + ("NumberFormatException should not have a cause"); + } else { + throw nfe; + } } - } + }); } - @Test(expectedExceptions=NumberFormatException.class) + @Test public void charArrayConstructorIndexOutOfBounds() { - BigDecimal bd = new BigDecimal(new char[5], 1, 5, null); + Assertions.assertThrows(NumberFormatException.class, () -> { + BigDecimal bd = new BigDecimal(new char[5], 1, 5, null); + }); } } diff --git a/test/jdk/java/math/BigInteger/LargeValueExceptions.java b/test/jdk/java/math/BigInteger/LargeValueExceptions.java index 4c85281a5c0..9670691e51c 100644 --- a/test/jdk/java/math/BigInteger/LargeValueExceptions.java +++ b/test/jdk/java/math/BigInteger/LargeValueExceptions.java @@ -26,13 +26,16 @@ * @bug 8200698 * @summary Tests that exceptions are thrown for ops which would overflow * @requires (sun.arch.data.model == "64" & os.maxMemory >= 4g) - * @run testng/othervm/timeout=480 -Xmx4g LargeValueExceptions + * @run junit/othervm/timeout=480 -Xmx4g LargeValueExceptions */ + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; + import java.math.BigInteger; + import static java.math.BigInteger.ONE; -import org.testng.ITestResult; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.Test; // // The intent of this test is to probe the boundaries between overflow and @@ -64,47 +67,48 @@ public class LargeValueExceptions { // Half BigInteger.MAX_MAG_LENGTH private static final int MAX_INTS_HALF = MAX_INTS / 2; - // Print the run time of each sub-test in milliseconds - @AfterMethod - public void getRunTime(ITestResult tr) { - long time = tr.getEndMillis() - tr.getStartMillis(); - System.out.printf("Run time: %d ms%n", time); - } - // --- squaring --- // Largest no overflow determined by examining data lengths alone. - @Test(enabled=false) + @Test + @Disabled public void squareNoOverflow() { BigInteger x = ONE.shiftLeft(16*MAX_INTS - 1).subtract(ONE); BigInteger y = x.multiply(x); } // Smallest no overflow determined by extra calculations. - @Test(enabled=false) + @Test + @Disabled public void squareIndefiniteOverflowSuccess() { BigInteger x = ONE.shiftLeft(16*MAX_INTS - 1); BigInteger y = x.multiply(x); } // Largest overflow detected by extra calculations. - @Test(expectedExceptions=ArithmeticException.class,enabled=false) + @Test + @Disabled public void squareIndefiniteOverflowFailure() { - BigInteger x = ONE.shiftLeft(16*MAX_INTS).subtract(ONE); - BigInteger y = x.multiply(x); + Assertions.assertThrows(ArithmeticException.class, () -> { + BigInteger x = ONE.shiftLeft(16*MAX_INTS).subtract(ONE); + BigInteger y = x.multiply(x); + }); } // Smallest overflow detected by examining data lengths alone. - @Test(expectedExceptions=ArithmeticException.class) + @Test public void squareDefiniteOverflow() { - BigInteger x = ONE.shiftLeft(16*MAX_INTS); - BigInteger y = x.multiply(x); + Assertions.assertThrows(ArithmeticException.class, () -> { + BigInteger x = ONE.shiftLeft(16*MAX_INTS); + BigInteger y = x.multiply(x); + }); } // --- multiplication --- // Largest no overflow determined by examining data lengths alone. - @Test(enabled=false) + @Test + @Disabled public void multiplyNoOverflow() { final int halfMaxBits = MAX_INTS_HALF << 5; @@ -114,7 +118,8 @@ public class LargeValueExceptions { } // Smallest no overflow determined by extra calculations. - @Test(enabled=false) + @Test + @Disabled public void multiplyIndefiniteOverflowSuccess() { BigInteger x = ONE.shiftLeft((int)(MAX_BITS/2) - 1); long m = MAX_BITS - x.bitLength(); @@ -130,68 +135,83 @@ public class LargeValueExceptions { } // Largest overflow detected by extra calculations. - @Test(expectedExceptions=ArithmeticException.class,enabled=false) + @Test + @Disabled public void multiplyIndefiniteOverflowFailure() { - BigInteger x = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE); - long m = MAX_BITS - x.bitLength(); + Assertions.assertThrows(ArithmeticException.class, () -> { + BigInteger x = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE); + long m = MAX_BITS - x.bitLength(); - BigInteger y = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE); - long n = MAX_BITS - y.bitLength(); + BigInteger y = ONE.shiftLeft((int)(MAX_BITS/2)).subtract(ONE); + long n = MAX_BITS - y.bitLength(); - if (m + n != MAX_BITS) { - throw new RuntimeException("Unexpected leading zero sum"); - } + if (m + n != MAX_BITS) { + throw new RuntimeException("Unexpected leading zero sum"); + } - BigInteger z = x.multiply(y); + BigInteger z = x.multiply(y); + }); } // Smallest overflow detected by examining data lengths alone. - @Test(expectedExceptions=ArithmeticException.class) + @Test public void multiplyDefiniteOverflow() { - // multiply by 4 as MAX_INTS_HALF refers to ints - byte[] xmag = new byte[4*MAX_INTS_HALF]; - xmag[0] = (byte)0xff; - BigInteger x = new BigInteger(1, xmag); + Assertions.assertThrows(ArithmeticException.class, () -> { + // multiply by 4 as MAX_INTS_HALF refers to ints + byte[] xmag = new byte[4*MAX_INTS_HALF]; + xmag[0] = (byte)0xff; + BigInteger x = new BigInteger(1, xmag); - byte[] ymag = new byte[4*MAX_INTS_HALF + 1]; - ymag[0] = (byte)0xff; - BigInteger y = new BigInteger(1, ymag); + byte[] ymag = new byte[4*MAX_INTS_HALF + 1]; + ymag[0] = (byte)0xff; + BigInteger y = new BigInteger(1, ymag); - BigInteger z = x.multiply(y); + BigInteger z = x.multiply(y); + }); } // --- exponentiation --- - @Test(expectedExceptions=ArithmeticException.class) + @Test public void powOverflow() { - BigInteger.TEN.pow(Integer.MAX_VALUE); + Assertions.assertThrows(ArithmeticException.class, () -> { + BigInteger.TEN.pow(Integer.MAX_VALUE); + }); } - @Test(expectedExceptions=ArithmeticException.class) + @Test public void powOverflow1() { - int shift = 20; - int exponent = 1 << shift; - BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)); - BigInteger y = x.pow(exponent); + Assertions.assertThrows(ArithmeticException.class, () -> { + int shift = 20; + int exponent = 1 << shift; + BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)); + BigInteger y = x.pow(exponent); + }); } - @Test(expectedExceptions=ArithmeticException.class) + @Test public void powOverflow2() { - int shift = 20; - int exponent = 1 << shift; - BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).add(ONE); - BigInteger y = x.pow(exponent); + Assertions.assertThrows(ArithmeticException.class, () -> { + int shift = 20; + int exponent = 1 << shift; + BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).add(ONE); + BigInteger y = x.pow(exponent); + }); } - @Test(expectedExceptions=ArithmeticException.class,enabled=false) + @Test + @Disabled public void powOverflow3() { - int shift = 20; - int exponent = 1 << shift; - BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).subtract(ONE); - BigInteger y = x.pow(exponent); + Assertions.assertThrows(ArithmeticException.class, () -> { + int shift = 20; + int exponent = 1 << shift; + BigInteger x = ONE.shiftLeft((int)(MAX_BITS / exponent)).subtract(ONE); + BigInteger y = x.pow(exponent); + }); } - @Test(enabled=false) + @Test + @Disabled public void powOverflow4() { int shift = 20; int exponent = 1 << shift; From 9a23f8aa337e1292179625ce9bb8abe22c9e22e2 Mon Sep 17 00:00:00 2001 From: Aggelos Biboudis Date: Wed, 17 Dec 2025 10:31:23 +0000 Subject: [PATCH 040/390] 8373552: ExactConversionsSupport: bad JLS links in javadoc Reviewed-by: liach, iris --- .../java/lang/runtime/ExactConversionsSupport.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/lang/runtime/ExactConversionsSupport.java b/src/java.base/share/classes/java/lang/runtime/ExactConversionsSupport.java index 6e17a4b85a0..b86891749da 100644 --- a/src/java.base/share/classes/java/lang/runtime/ExactConversionsSupport.java +++ b/src/java.base/share/classes/java/lang/runtime/ExactConversionsSupport.java @@ -64,9 +64,12 @@ package java.lang.runtime; * floating-point type is considered exact. * * - * @jls 5.7.1 Exact Testing Conversions - * @jls 5.7.2 Unconditionally Exact Testing Conversions - * @jls 15.20.2 The instanceof Operator + * @see + * JLS 5.7.1 Exact Testing Conversions + * @see + * JLS 5.7.2 Unconditionally Exact Testing Conversions + * @see + * JLS 15.20.2 The instanceof Operator * * @implNote Some exactness checks describe a test which can be redirected * safely through one of the existing methods. Those are omitted too (i.e., From e4636d69e7e41477619a163e97fd3af2e5942dde Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 17 Dec 2025 11:17:39 +0000 Subject: [PATCH 041/390] 8373420: C2: Add true/false_proj*() methods for IfNode as a replacement for proj_out*(true/false) Reviewed-by: dfenacci, roland, epeter --- src/hotspot/share/opto/castnode.cpp | 7 +++---- src/hotspot/share/opto/castnode.hpp | 2 +- src/hotspot/share/opto/cfgnode.hpp | 22 ++++++++++++++++++++-- src/hotspot/share/opto/ifnode.cpp | 16 +++++++++------- src/hotspot/share/opto/loopTransform.cpp | 18 ++++++++---------- src/hotspot/share/opto/loopUnswitch.cpp | 2 +- src/hotspot/share/opto/loopnode.cpp | 17 ++++++++--------- src/hotspot/share/opto/loopnode.hpp | 2 +- src/hotspot/share/opto/loopopts.cpp | 16 ++++++++-------- src/hotspot/share/opto/macro.cpp | 4 ++-- src/hotspot/share/opto/stringopts.cpp | 2 +- 11 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/hotspot/share/opto/castnode.cpp b/src/hotspot/share/opto/castnode.cpp index 9c764f22e38..998b6a79903 100644 --- a/src/hotspot/share/opto/castnode.cpp +++ b/src/hotspot/share/opto/castnode.cpp @@ -313,8 +313,7 @@ void CastIINode::remove_range_check_cast(Compile* C) { } } - -bool CastLLNode::is_inner_loop_backedge(ProjNode* proj) { +bool CastLLNode::is_inner_loop_backedge(IfProjNode* proj) { if (proj != nullptr) { Node* ctrl_use = proj->unique_ctrl_out_or_null(); if (ctrl_use != nullptr && ctrl_use->Opcode() == Op_Loop && @@ -333,8 +332,8 @@ bool CastLLNode::cmp_used_at_inner_loop_exit_test(CmpNode* cmp) { for (DUIterator_Fast jmax, j = bol->fast_outs(jmax); j < jmax; j++) { Node* iff = bol->fast_out(j); if (iff->Opcode() == Op_If) { - ProjNode* true_proj = iff->as_If()->proj_out_or_null(true); - ProjNode* false_proj = iff->as_If()->proj_out_or_null(false); + IfTrueNode* true_proj = iff->as_If()->true_proj_or_null(); + IfFalseNode* false_proj = iff->as_If()->false_proj_or_null(); if (is_inner_loop_backedge(true_proj) || is_inner_loop_backedge(false_proj)) { return true; } diff --git a/src/hotspot/share/opto/castnode.hpp b/src/hotspot/share/opto/castnode.hpp index 2ff13e44780..f22df546f41 100644 --- a/src/hotspot/share/opto/castnode.hpp +++ b/src/hotspot/share/opto/castnode.hpp @@ -239,7 +239,7 @@ public: init_class_id(Class_CastLL); } - static bool is_inner_loop_backedge(ProjNode* proj); + static bool is_inner_loop_backedge(IfProjNode* proj); static bool cmp_used_at_inner_loop_exit_test(CmpNode* cmp); bool used_at_inner_loop_exit_test() const; diff --git a/src/hotspot/share/opto/cfgnode.hpp b/src/hotspot/share/opto/cfgnode.hpp index ef799f4c39a..5f7f4790443 100644 --- a/src/hotspot/share/opto/cfgnode.hpp +++ b/src/hotspot/share/opto/cfgnode.hpp @@ -354,7 +354,7 @@ class IfNode : public MultiBranchNode { static bool is_dominator_unc(CallStaticJavaNode* dom_unc, CallStaticJavaNode* unc); protected: - ProjNode* range_check_trap_proj(int& flip, Node*& l, Node*& r); + IfProjNode* range_check_trap_proj(int& flip, Node*& l, Node*& r) const; Node* Ideal_common(PhaseGVN *phase, bool can_reshape); Node* search_identical(int dist, PhaseIterGVN* igvn); @@ -433,6 +433,24 @@ public: static IfNode* make_with_same_profile(IfNode* if_node_profile, Node* ctrl, Node* bol); + IfTrueNode* true_proj() const { + return proj_out(true)->as_IfTrue(); + } + + IfTrueNode* true_proj_or_null() const { + ProjNode* true_proj = proj_out_or_null(true); + return true_proj == nullptr ? nullptr : true_proj->as_IfTrue(); + } + + IfFalseNode* false_proj() const { + return proj_out(false)->as_IfFalse(); + } + + IfFalseNode* false_proj_or_null() const { + ProjNode* false_proj = proj_out_or_null(false); + return false_proj == nullptr ? nullptr : false_proj->as_IfFalse(); + } + virtual int Opcode() const; virtual bool pinned() const { return true; } virtual const Type *bottom_type() const { return TypeTuple::IFBOTH; } @@ -523,7 +541,7 @@ class ParsePredicateNode : public IfNode { // Return the uncommon trap If projection of this Parse Predicate. ParsePredicateUncommonProj* uncommon_proj() const { - return proj_out(0)->as_IfFalse(); + return false_proj(); } Node* uncommon_trap() const; diff --git a/src/hotspot/share/opto/ifnode.cpp b/src/hotspot/share/opto/ifnode.cpp index 83e975b95a2..763888b65b2 100644 --- a/src/hotspot/share/opto/ifnode.cpp +++ b/src/hotspot/share/opto/ifnode.cpp @@ -487,7 +487,7 @@ IfNode* IfNode::make_with_same_profile(IfNode* if_node_profile, Node* ctrl, Node // if this IfNode follows a range check pattern return the projection // for the failed path -ProjNode* IfNode::range_check_trap_proj(int& flip_test, Node*& l, Node*& r) { +IfProjNode* IfNode::range_check_trap_proj(int& flip_test, Node*& l, Node*& r) const { if (outcnt() != 2) { return nullptr; } @@ -515,8 +515,10 @@ ProjNode* IfNode::range_check_trap_proj(int& flip_test, Node*& l, Node*& r) { // Flip 1: If (Bool[<] CmpU(l, LoadRange)) ... // Flip 2: If (Bool[<=] CmpU(LoadRange, l)) ... - ProjNode* iftrap = proj_out_or_null(flip_test == 2 ? true : false); - return iftrap; + if (flip_test == 2) { + return true_proj_or_null(); + } + return false_proj_or_null(); } @@ -528,7 +530,7 @@ int RangeCheckNode::is_range_check(Node* &range, Node* &index, jint &offset) { int flip_test = 0; Node* l = nullptr; Node* r = nullptr; - ProjNode* iftrap = range_check_trap_proj(flip_test, l, r); + IfProjNode* iftrap = range_check_trap_proj(flip_test, l, r); if (iftrap == nullptr) { return 0; @@ -1875,8 +1877,8 @@ static IfNode* idealize_test(PhaseGVN* phase, IfNode* iff) { assert(iff->in(0) != nullptr, "If must be live"); if (iff->outcnt() != 2) return nullptr; // Malformed projections. - Node* old_if_f = iff->proj_out(false); - Node* old_if_t = iff->proj_out(true); + IfFalseNode* old_if_f = iff->false_proj(); + IfTrueNode* old_if_t = iff->true_proj(); // CountedLoopEnds want the back-control test to be TRUE, regardless of // whether they are testing a 'gt' or 'lt' condition. The 'gt' condition @@ -2192,7 +2194,7 @@ void ParsePredicateNode::mark_useless(PhaseIterGVN& igvn) { } Node* ParsePredicateNode::uncommon_trap() const { - ParsePredicateUncommonProj* uncommon_proj = proj_out(0)->as_IfFalse(); + ParsePredicateUncommonProj* uncommon_proj = false_proj(); Node* uct_region_or_call = uncommon_proj->unique_ctrl_out(); assert(uct_region_or_call->is_Region() || uct_region_or_call->is_Call(), "must be a region or call uct"); return uct_region_or_call; diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp index 41bce0fe9b5..fdb3ab89b82 100644 --- a/src/hotspot/share/opto/loopTransform.cpp +++ b/src/hotspot/share/opto/loopTransform.cpp @@ -87,7 +87,7 @@ void IdealLoopTree::record_for_igvn() { Node* outer_safepoint = l->outer_safepoint(); assert(outer_safepoint != nullptr, "missing piece of strip mined loop"); _phase->_igvn._worklist.push(outer_safepoint); - Node* cle_out = _head->as_CountedLoop()->loopexit()->proj_out(false); + IfFalseNode* cle_out = _head->as_CountedLoop()->loopexit()->false_proj(); assert(cle_out != nullptr, "missing piece of strip mined loop"); _phase->_igvn._worklist.push(cle_out); } @@ -1464,9 +1464,8 @@ void PhaseIdealLoop::insert_pre_post_loops(IdealLoopTree *loop, Node_List &old_n pre_end->_prob = PROB_FAIR; // Find the pre-loop normal exit. - Node* pre_exit = pre_end->proj_out(false); - assert(pre_exit->Opcode() == Op_IfFalse, ""); - IfFalseNode *new_pre_exit = new IfFalseNode(pre_end); + IfFalseNode* pre_exit = pre_end->false_proj(); + IfFalseNode* new_pre_exit = new IfFalseNode(pre_end); _igvn.register_new_node_with_optimizer(new_pre_exit); set_idom(new_pre_exit, pre_end, dd_main_head); set_loop(new_pre_exit, outer_loop->_parent); @@ -1707,8 +1706,7 @@ Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree* loop, Node_List& old_new, //------------------------------ // Step A: Create a new post-Loop. - Node* main_exit = outer_main_end->proj_out(false); - assert(main_exit->Opcode() == Op_IfFalse, ""); + IfFalseNode* main_exit = outer_main_end->false_proj(); int dd_main_exit = dom_depth(main_exit); // Step A1: Clone the loop body of main. The clone becomes the post-loop. @@ -1721,7 +1719,7 @@ Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree* loop, Node_List& old_new, post_head->set_post_loop(main_head); // clone_loop() above changes the exit projection - main_exit = outer_main_end->proj_out(false); + main_exit = outer_main_end->false_proj(); // Reduce the post-loop trip count. CountedLoopEndNode* post_end = old_new[main_end->_idx]->as_CountedLoopEnd(); @@ -1786,7 +1784,7 @@ Node *PhaseIdealLoop::insert_post_loop(IdealLoopTree* loop, Node_List& old_new, // right after the execution of the inner CountedLoop. // We have to make sure that such stores in the post loop have the right memory inputs from the main loop // The moved store node is always attached right after the inner loop exit, and just before the safepoint - const Node* if_false = main_end->proj_out(false); + const IfFalseNode* if_false = main_end->false_proj(); for (DUIterator j = if_false->outs(); if_false->has_out(j); j++) { Node* store = if_false->out(j); if (store->is_Store()) { @@ -3944,7 +3942,7 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) { return false; } - Node* exit = head->loopexit()->proj_out_or_null(0); + IfFalseNode* exit = head->loopexit()->false_proj_or_null(); if (exit == nullptr) { return false; } @@ -3988,7 +3986,7 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) { // If the store is on the backedge, it is not executed in the last // iteration, and we must subtract 1 from the len. - Node* backedge = head->loopexit()->proj_out(1); + IfTrueNode* backedge = head->loopexit()->true_proj(); if (store->in(0) == backedge) { len = new SubINode(len, _igvn.intcon(1)); _igvn.register_new_node_with_optimizer(len); diff --git a/src/hotspot/share/opto/loopUnswitch.cpp b/src/hotspot/share/opto/loopUnswitch.cpp index 287f8354dc1..cc83bdda561 100644 --- a/src/hotspot/share/opto/loopUnswitch.cpp +++ b/src/hotspot/share/opto/loopUnswitch.cpp @@ -488,7 +488,7 @@ IfTrueNode* PhaseIdealLoop::create_new_if_for_multiversion(IfTrueNode* multivers IfNode* multiversion_if = multiversioning_fast_proj->in(0)->as_If(); Node* entry = multiversion_if->in(0); OpaqueMultiversioningNode* opaque = multiversion_if->in(1)->as_OpaqueMultiversioning(); - IfFalseNode* multiversion_slow_proj = multiversion_if->proj_out(0)->as_IfFalse(); + IfFalseNode* multiversion_slow_proj = multiversion_if->false_proj(); Node* slow_path = multiversion_slow_proj->unique_ctrl_out(); // The slow_loop may still be delayed, and waiting for runtime-checks to be added to the diff --git a/src/hotspot/share/opto/loopnode.cpp b/src/hotspot/share/opto/loopnode.cpp index 42d3ee105f8..dacc1a1a734 100644 --- a/src/hotspot/share/opto/loopnode.cpp +++ b/src/hotspot/share/opto/loopnode.cpp @@ -79,11 +79,10 @@ bool LoopNode::is_valid_counted_loop(BasicType bt) const { BaseCountedLoopNode* l = as_BaseCountedLoop(); BaseCountedLoopEndNode* le = l->loopexit_or_null(); if (le != nullptr && - le->proj_out_or_null(1 /* true */) == l->in(LoopNode::LoopBackControl)) { + le->true_proj_or_null() == l->in(LoopNode::LoopBackControl)) { Node* phi = l->phi(); - Node* exit = le->proj_out_or_null(0 /* false */); - if (exit != nullptr && exit->Opcode() == Op_IfFalse && - phi != nullptr && phi->is_Phi() && + IfFalseNode* exit = le->false_proj_or_null(); + if (exit != nullptr && phi != nullptr && phi->is_Phi() && phi->in(LoopNode::LoopBackControl) == l->incr() && le->loopnode() == l && le->stride_is_con()) { return true; @@ -942,7 +941,7 @@ bool PhaseIdealLoop::create_loop_nest(IdealLoopTree* loop, Node_List &old_new) { safepoint = find_safepoint(back_control, x, loop); } - Node* exit_branch = exit_test->proj_out(false); + IfFalseNode* exit_branch = exit_test->false_proj(); Node* entry_control = head->in(LoopNode::EntryControl); // Clone the control flow of the loop to build an outer loop @@ -3087,7 +3086,7 @@ IfFalseNode* OuterStripMinedLoopNode::outer_loop_exit() const { if (le == nullptr) { return nullptr; } - Node* c = le->proj_out_or_null(false); + IfFalseNode* c = le->false_proj_or_null(); if (c == nullptr) { return nullptr; } @@ -3407,7 +3406,7 @@ void OuterStripMinedLoopNode::adjust_strip_mined_loop(PhaseIterGVN* igvn) { return; } - Node* cle_tail = inner_cle->proj_out(true); + IfTrueNode* cle_tail = inner_cle->true_proj(); ResourceMark rm; Node_List old_new; if (cle_tail->outcnt() > 1) { @@ -3549,7 +3548,7 @@ void OuterStripMinedLoopNode::transform_to_counted_loop(PhaseIterGVN* igvn, Phas iloop->replace_node_and_forward_ctrl(outer_le, new_end); } // the backedge of the inner loop must be rewired to the new loop end - Node* backedge = cle->proj_out(true); + IfTrueNode* backedge = cle->true_proj(); igvn->replace_input_of(backedge, 0, new_end); if (iloop != nullptr) { iloop->set_idom(backedge, new_end, iloop->dom_depth(new_end) + 1); @@ -3630,7 +3629,7 @@ const Type* OuterStripMinedLoopEndNode::Value(PhaseGVN* phase) const { bool OuterStripMinedLoopEndNode::is_expanded(PhaseGVN *phase) const { // The outer strip mined loop head only has Phi uses after expansion if (phase->is_IterGVN()) { - Node* backedge = proj_out_or_null(true); + IfTrueNode* backedge = true_proj_or_null(); if (backedge != nullptr) { Node* head = backedge->unique_ctrl_out_or_null(); if (head != nullptr && head->is_OuterStripMinedLoop()) { diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index 3b97d76773f..ffc283ac941 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp @@ -607,7 +607,7 @@ public: virtual SafePointNode* outer_safepoint() const; CountedLoopNode* inner_counted_loop() const { return unique_ctrl_out()->as_CountedLoop(); } CountedLoopEndNode* inner_counted_loop_end() const { return inner_counted_loop()->loopexit(); } - IfFalseNode* inner_loop_exit() const { return inner_counted_loop_end()->proj_out(false)->as_IfFalse(); } + IfFalseNode* inner_loop_exit() const { return inner_counted_loop_end()->false_proj(); } void adjust_strip_mined_loop(PhaseIterGVN* igvn); diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index b1422d5db20..8f85b7f270e 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -1321,8 +1321,8 @@ bool PhaseIdealLoop::identical_backtoback_ifs(Node *n) { return false; } IfNode* dom_if = dom->as_If(); - Node* proj_true = dom_if->proj_out(1); - Node* proj_false = dom_if->proj_out(0); + IfTrueNode* proj_true = dom_if->true_proj(); + IfFalseNode* proj_false = dom_if->false_proj(); for (uint i = 1; i < region->req(); i++) { if (is_dominator(proj_true, region->in(i))) { @@ -1585,8 +1585,8 @@ bool PhaseIdealLoop::try_merge_identical_ifs(Node* n) { dom_if->in(1)->in(1)->as_SubTypeCheck()->method() != nullptr), "only for subtype checks with profile data attached"); _igvn.replace_input_of(n, 1, dom_if->in(1)); } - ProjNode* dom_proj_true = dom_if->proj_out(1); - ProjNode* dom_proj_false = dom_if->proj_out(0); + IfTrueNode* dom_proj_true = dom_if->true_proj(); + IfFalseNode* dom_proj_false = dom_if->false_proj(); // Now split the IF RegionNode* new_false_region; @@ -1630,10 +1630,10 @@ bool PhaseIdealLoop::try_merge_identical_ifs(Node* n) { // unrelated control dependency. for (uint i = 1; i < new_false_region->req(); i++) { if (is_dominator(dom_proj_true, new_false_region->in(i))) { - dominated_by(dom_proj_true->as_IfProj(), new_false_region->in(i)->in(0)->as_If()); + dominated_by(dom_proj_true, new_false_region->in(i)->in(0)->as_If()); } else { assert(is_dominator(dom_proj_false, new_false_region->in(i)), "bad if"); - dominated_by(dom_proj_false->as_IfProj(), new_false_region->in(i)->in(0)->as_If()); + dominated_by(dom_proj_false, new_false_region->in(i)->in(0)->as_If()); } } return true; @@ -2394,7 +2394,7 @@ void PhaseIdealLoop::clone_outer_loop(LoopNode* head, CloneLoopMode mode, IdealL CountedLoopEndNode* cle = cl->loopexit(); CountedLoopNode* new_cl = old_new[cl->_idx]->as_CountedLoop(); CountedLoopEndNode* new_cle = new_cl->as_CountedLoop()->loopexit_or_null(); - Node* cle_out = cle->proj_out(false); + IfFalseNode* cle_out = cle->false_proj(); Node* new_sfpt = nullptr; Node* new_cle_out = cle_out->clone(); @@ -2691,7 +2691,7 @@ void PhaseIdealLoop::fix_ctrl_uses(const Node_List& body, const IdealLoopTree* l if (use->in(0) == cle) { IfFalseNode* cle_out = use->as_IfFalse(); IfNode* le = cl->outer_loop_end(); - use = le->proj_out(false); + use = le->false_proj(); use_loop = get_loop(use); if (mode == CloneIncludesStripMined) { nnn = old_new[le->_idx]; diff --git a/src/hotspot/share/opto/macro.cpp b/src/hotspot/share/opto/macro.cpp index bc07f937f1e..80818a4ddc7 100644 --- a/src/hotspot/share/opto/macro.cpp +++ b/src/hotspot/share/opto/macro.cpp @@ -2379,8 +2379,8 @@ void PhaseMacroExpand::expand_subtypecheck_node(SubTypeCheckNode *check) { continue; } - Node* iftrue = iff->as_If()->proj_out(1); - Node* iffalse = iff->as_If()->proj_out(0); + IfTrueNode* iftrue = iff->as_If()->true_proj(); + IfFalseNode* iffalse = iff->as_If()->false_proj(); Node* ctrl = iff->in(0); Node* subklass = nullptr; diff --git a/src/hotspot/share/opto/stringopts.cpp b/src/hotspot/share/opto/stringopts.cpp index 6b98c4ca2b0..e499ba932e1 100644 --- a/src/hotspot/share/opto/stringopts.cpp +++ b/src/hotspot/share/opto/stringopts.cpp @@ -255,7 +255,7 @@ void StringConcat::eliminate_unneeded_control() { Compile* C = _stringopts->C; C->gvn_replace_by(n, n->in(0)->in(0)); // get rid of the other projection - C->gvn_replace_by(n->in(0)->as_If()->proj_out(false), C->top()); + C->gvn_replace_by(n->in(0)->as_If()->false_proj(), C->top()); } else if (n->is_Region()) { Node* iff = n->in(1)->in(0); assert(n->req() == 3 && n->in(2)->in(0) == iff, "not a diamond"); From 5e7ae281326ca306339aaba101d4206dffdb9ca0 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 17 Dec 2025 12:13:58 +0000 Subject: [PATCH 042/390] 8373677: Clear text HttpServer connection could fail fast if receiving SSL ClientHello Reviewed-by: jpai, djelinski --- .../classes/sun/net/httpserver/Request.java | 37 +++- .../sun/net/httpserver/ServerImpl.java | 12 +- .../net/httpserver/ClearTextServerSSL.java | 159 ++++++++++++++++++ 3 files changed, 206 insertions(+), 2 deletions(-) create mode 100644 test/jdk/com/sun/net/httpserver/ClearTextServerSSL.java diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java index 4a4afc8d7ce..75eeb29f015 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/Request.java @@ -25,6 +25,7 @@ package sun.net.httpserver; +import java.net.ProtocolException; import java.nio.*; import java.io.*; import java.nio.channels.*; @@ -39,15 +40,18 @@ class Request { static final int BUF_LEN = 2048; static final byte CR = 13; static final byte LF = 10; + static final byte FIRST_CHAR = 32; private String startLine; private SocketChannel chan; private InputStream is; private OutputStream os; private final int maxReqHeaderSize; + private final boolean firstClearRequest; - Request(InputStream rawInputStream, OutputStream rawout) throws IOException { + Request(InputStream rawInputStream, OutputStream rawout, boolean firstClearRequest) throws IOException { this.maxReqHeaderSize = ServerConfig.getMaxReqHeaderSize(); + this.firstClearRequest = firstClearRequest; is = rawInputStream; os = rawout; do { @@ -78,6 +82,25 @@ class Request { boolean gotCR = false, gotLF = false; pos = 0; lineBuf = new StringBuffer(); long lsize = 32; + + // For the first request that comes on a clear connection + // we will check that the first non CR/LF char on the + // request line is eligible. This should be the first char + // of a method name, so it should be at least greater or equal + // to 32 (FIRST_CHAR) which is the space character. + // The main goal here is to fail fast if we receive 0x16 (22) which + // happens to be the first byte of a TLS handshake record. + // This is typically what would be received if a TLS client opened + // a TLS connection on a non-TLS server. + // If we receive 0x16 we should close the connection immediately as + // it indicates we're receiving a ClientHello on a clear + // connection, and we will never receive the expected CRLF that + // terminates the first request line. + // Though we could check only for 0x16, any characters < 32 + // (excluding CRLF) is not expected at this position in a + // request line, so we can still fail here early if any of + // those are detected. + int offset = 0; while (!gotLF) { int c = is.read(); if (c == -1) { @@ -89,6 +112,12 @@ class Request { } else { gotCR = false; consume(CR); + if (firstClearRequest && offset == 0) { + if (c < FIRST_CHAR) { + throw new ProtocolException("Unexpected start of request line"); + } + offset++; + } consume(c); lsize = lsize + 2; } @@ -96,6 +125,12 @@ class Request { if (c == CR) { gotCR = true; } else { + if (firstClearRequest && offset == 0) { + if (c < FIRST_CHAR) { + throw new ProtocolException("Unexpected start of request line"); + } + offset++; + } consume(c); lsize = lsize + 1; } diff --git a/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java b/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java index 1eb918b4e66..e8c8d336e03 100644 --- a/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java +++ b/src/jdk.httpserver/share/classes/sun/net/httpserver/ServerImpl.java @@ -45,6 +45,7 @@ import java.lang.System.Logger; import java.lang.System.Logger.Level; import java.net.BindException; import java.net.InetSocketAddress; +import java.net.ProtocolException; import java.net.ServerSocket; import java.net.URI; import java.net.URISyntaxException; @@ -733,7 +734,16 @@ class ServerImpl { connection.raw = rawin; connection.rawout = rawout; } - Request req = new Request(rawin, rawout); + + Request req; + try { + req = new Request(rawin, rawout, newconnection && !https); + } catch (ProtocolException pe) { + logger.log(Level.DEBUG, "closing due to: " + pe); + reject(Code.HTTP_BAD_REQUEST, "", pe.getMessage()); + return; + } + requestLine = req.requestLine(); if (requestLine == null) { /* connection closed */ diff --git a/test/jdk/com/sun/net/httpserver/ClearTextServerSSL.java b/test/jdk/com/sun/net/httpserver/ClearTextServerSSL.java new file mode 100644 index 00000000000..75e4f3fcf45 --- /dev/null +++ b/test/jdk/com/sun/net/httpserver/ClearTextServerSSL.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 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. + */ + +/* + * @test + * @bug 8373677 + * @summary Tests for verifying that a non-SSL server can detect + * when a client attempts to use SSL. + * @library /test/lib + * @run junit/othervm ${test.main.class} + */ + +import com.sun.net.httpserver.HttpExchange; +import com.sun.net.httpserver.HttpHandler; +import com.sun.net.httpserver.HttpServer; +import jdk.test.lib.net.SimpleSSLContext; +import jdk.test.lib.net.URIBuilder; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.util.logging.ConsoleHandler; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.net.ssl.SSLException; + +import static com.sun.net.httpserver.HttpExchange.RSPBODY_EMPTY; +import static java.net.http.HttpClient.Builder.NO_PROXY; +import static org.junit.jupiter.api.Assertions.*; + +public class ClearTextServerSSL { + + static final InetAddress LOOPBACK_ADDR = InetAddress.getLoopbackAddress(); + static final boolean ENABLE_LOGGING = true; + static final Logger logger = Logger.getLogger("com.sun.net.httpserver"); + + static final String CTXT_PATH = "/ClearTextServerSSL"; + + @BeforeAll + public static void setup() { + if (ENABLE_LOGGING) { + ConsoleHandler ch = new ConsoleHandler(); + logger.setLevel(Level.ALL); + ch.setLevel(Level.ALL); + logger.addHandler(ch); + } + } + + @Test + public void test() throws Exception { + var sslContext = new SimpleSSLContext().get(); + var handler = new TestHandler(); + var server = HttpServer.create(new InetSocketAddress(LOOPBACK_ADDR, 0), 0); + server.createContext(path(""), handler); + server.start(); + try (var client = HttpClient.newBuilder() + .sslContext(sslContext) + .proxy(NO_PROXY) + .build()) { + var request = HttpRequest.newBuilder() + .uri(uri("http", server, path("/clear"))) + .build(); + var response = client.send(request, HttpResponse.BodyHandlers.ofString()); + assertEquals(200, response.statusCode()); + var sslRequest = HttpRequest.newBuilder() + .uri(uri("https", server, path("/ssl"))) + .build(); + Assertions.assertThrows(SSLException.class, () -> { + client.send(sslRequest, HttpResponse.BodyHandlers.ofString()); + }); + try (var socket = new Socket()) { + socket.connect(server.getAddress()); + byte[] badRequest = { + 22, 'B', 'A', 'D', ' ', + '/', ' ' , + 'H', 'T', 'T', 'P', '/', '1', '.', '1' }; + socket.getOutputStream().write(badRequest); + socket.getOutputStream().flush(); + var reader = new InputStreamReader(socket.getInputStream()); + var line = reader.readAllLines(); + Assertions.assertEquals("HTTP/1.1 400 Bad Request", line.get(0)); + System.out.println("Got expected response:"); + line.stream().map(l -> "\t" + l).forEach(System.out::println); + } + + } finally { + server.stop(0); + } + } + + // --- infra --- + + static String path(String path) { + assert CTXT_PATH.startsWith("/"); + assert !CTXT_PATH.endsWith("/"); + if (path.startsWith("/")) { + return CTXT_PATH + path; + } else { + return CTXT_PATH + "/" + path; + } + } + + static URI uri(String scheme, HttpServer server, String path) throws URISyntaxException { + return URIBuilder.newBuilder() + .scheme(scheme) + .loopback() + .port(server.getAddress().getPort()) + .path(path) + .build(); + } + + /** + * A test handler that reads any request bytes and sends + * an empty 200 response + */ + static class TestHandler implements HttpHandler { + @java.lang.Override + public void handle(HttpExchange exchange) throws IOException { + try (var reqBody = exchange.getRequestBody()) { + reqBody.readAllBytes(); + exchange.sendResponseHeaders(200, RSPBODY_EMPTY); + } catch (Throwable t) { + t.printStackTrace(); + exchange.sendResponseHeaders(500, RSPBODY_EMPTY); + } + } + } +} From 39306d7ab901a1d27d9bfd80f04d917b4d17d07f Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Wed, 17 Dec 2025 13:19:49 +0000 Subject: [PATCH 043/390] 8373800: Remove ScopedValueBindingsResolver Reviewed-by: alanb, liach --- src/hotspot/share/classfile/vmClassMacros.hpp | 3 +++ src/hotspot/share/prims/jvm.cpp | 13 +------------ 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/src/hotspot/share/classfile/vmClassMacros.hpp b/src/hotspot/share/classfile/vmClassMacros.hpp index 04f0aaaaa44..71d6b9f22b2 100644 --- a/src/hotspot/share/classfile/vmClassMacros.hpp +++ b/src/hotspot/share/classfile/vmClassMacros.hpp @@ -190,6 +190,9 @@ /* GC support */ \ do_klass(FillerObject_klass, jdk_internal_vm_FillerObject ) \ \ + /* Scoped Values */ \ + do_klass(ScopedValue_Carrier_klass, java_lang_ScopedValue_Carrier ) \ + \ /*end*/ #endif // SHARE_CLASSFILE_VMCLASSMACROS_HPP diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 48d89235c98..ef5aca96a57 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -1211,22 +1211,11 @@ JVM_ENTRY(jboolean, JVM_IsHiddenClass(JNIEnv *env, jclass cls)) JVM_END -class ScopedValueBindingsResolver { -public: - InstanceKlass* Carrier_klass; - ScopedValueBindingsResolver(JavaThread* THREAD) { - Klass *k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_ScopedValue_Carrier(), true, THREAD); - Carrier_klass = InstanceKlass::cast(k); - } -}; - JVM_ENTRY(jobject, JVM_FindScopedValueBindings(JNIEnv *env, jclass cls)) ResourceMark rm(THREAD); GrowableArray* local_array = new GrowableArray(12); JvmtiVMObjectAllocEventCollector oam; - static ScopedValueBindingsResolver resolver(THREAD); - // Iterate through Java frames vframeStream vfst(thread); for(; !vfst.at_end(); vfst.next()) { @@ -1239,7 +1228,7 @@ JVM_ENTRY(jobject, JVM_FindScopedValueBindings(JNIEnv *env, jclass cls)) InstanceKlass* holder = method->method_holder(); if (name == vmSymbols::runWith_method_name()) { if (holder == vmClasses::Thread_klass() - || holder == resolver.Carrier_klass) { + || holder == vmClasses::ScopedValue_Carrier_klass()) { loc = 1; } } From 9862f8f0d351448803f8930333d5a7286e6c3565 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn Date: Wed, 17 Dec 2025 13:38:37 +0000 Subject: [PATCH 044/390] 8373513: C2: Move ProjNode::other_if_proj() to IfProjNode Reviewed-by: epeter, roland --- src/hotspot/share/opto/cfgnode.cpp | 4 +- src/hotspot/share/opto/cfgnode.hpp | 21 +++++---- src/hotspot/share/opto/ifnode.cpp | 57 +++++++++++++------------ src/hotspot/share/opto/library_call.cpp | 2 +- src/hotspot/share/opto/memnode.cpp | 2 +- src/hotspot/share/opto/multnode.cpp | 7 +-- src/hotspot/share/opto/multnode.hpp | 3 -- src/hotspot/share/opto/predicates.cpp | 4 +- 8 files changed, 49 insertions(+), 51 deletions(-) diff --git a/src/hotspot/share/opto/cfgnode.cpp b/src/hotspot/share/opto/cfgnode.cpp index 776a2d4c90b..ad5adfca8e5 100644 --- a/src/hotspot/share/opto/cfgnode.cpp +++ b/src/hotspot/share/opto/cfgnode.cpp @@ -933,8 +933,8 @@ bool RegionNode::optimize_trichotomy(PhaseIterGVN* igvn) { } // At this point we know that region->in(idx1) and region->(idx2) map to the same // value and control flow. Now search for ifs that feed into these region inputs. - ProjNode* proj1 = region->in(idx1)->isa_Proj(); - ProjNode* proj2 = region->in(idx2)->isa_Proj(); + IfProjNode* proj1 = region->in(idx1)->isa_IfProj(); + IfProjNode* proj2 = region->in(idx2)->isa_IfProj(); if (proj1 == nullptr || proj1->outcnt() != 1 || proj2 == nullptr || proj2->outcnt() != 1) { return false; // No projection inputs with region as unique user found diff --git a/src/hotspot/share/opto/cfgnode.hpp b/src/hotspot/share/opto/cfgnode.hpp index 5f7f4790443..fd40123078a 100644 --- a/src/hotspot/share/opto/cfgnode.hpp +++ b/src/hotspot/share/opto/cfgnode.hpp @@ -342,15 +342,15 @@ class IfNode : public MultiBranchNode { // Helper methods for fold_compares bool cmpi_folds(PhaseIterGVN* igvn, bool fold_ne = false); bool is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn); - bool has_shared_region(ProjNode* proj, ProjNode*& success, ProjNode*& fail); - bool has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNode*& fail, PhaseIterGVN* igvn); - Node* merge_uncommon_traps(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn); + bool has_shared_region(IfProjNode* proj, IfProjNode*& success, IfProjNode*& fail) const; + bool has_only_uncommon_traps(IfProjNode* proj, IfProjNode*& success, IfProjNode*& fail, PhaseIterGVN* igvn) const; + Node* merge_uncommon_traps(IfProjNode* proj, IfProjNode* success, IfProjNode* fail, PhaseIterGVN* igvn); static void improve_address_types(Node* l, Node* r, ProjNode* fail, PhaseIterGVN* igvn); - bool is_cmp_with_loadrange(ProjNode* proj); - bool is_null_check(ProjNode* proj, PhaseIterGVN* igvn); - bool is_side_effect_free_test(ProjNode* proj, PhaseIterGVN* igvn); - void reroute_side_effect_free_unc(ProjNode* proj, ProjNode* dom_proj, PhaseIterGVN* igvn); - bool fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn); + bool is_cmp_with_loadrange(IfProjNode* proj) const; + bool is_null_check(IfProjNode* proj, PhaseIterGVN* igvn) const; + bool is_side_effect_free_test(IfProjNode* proj, PhaseIterGVN* igvn) const; + static void reroute_side_effect_free_unc(IfProjNode* proj, IfProjNode* dom_proj, PhaseIterGVN* igvn); + bool fold_compares_helper(IfProjNode* proj, IfProjNode* success, IfProjNode* fail, PhaseIterGVN* igvn); static bool is_dominator_unc(CallStaticJavaNode* dom_unc, CallStaticJavaNode* unc); protected: @@ -559,6 +559,11 @@ public: IfProjNode(IfNode *ifnode, uint idx) : CProjNode(ifnode,idx) {} virtual Node* Identity(PhaseGVN* phase); + // Return the other IfProj node. + IfProjNode* other_if_proj() const { + return in(0)->as_If()->proj_out(1 - _con)->as_IfProj(); + } + void pin_array_access_nodes(PhaseIterGVN* igvn); protected: diff --git a/src/hotspot/share/opto/ifnode.cpp b/src/hotspot/share/opto/ifnode.cpp index 763888b65b2..cd8017f9fb3 100644 --- a/src/hotspot/share/opto/ifnode.cpp +++ b/src/hotspot/share/opto/ifnode.cpp @@ -771,7 +771,7 @@ bool IfNode::cmpi_folds(PhaseIterGVN* igvn, bool fold_ne) { // Is a dominating control suitable for folding with this if? bool IfNode::is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn) { return ctrl != nullptr && - ctrl->is_Proj() && + ctrl->is_IfProj() && ctrl->outcnt() == 1 && // No side-effects ctrl->in(0) != nullptr && ctrl->in(0)->Opcode() == Op_If && @@ -784,8 +784,8 @@ bool IfNode::is_ctrl_folds(Node* ctrl, PhaseIterGVN* igvn) { } // Do this If and the dominating If share a region? -bool IfNode::has_shared_region(ProjNode* proj, ProjNode*& success, ProjNode*& fail) { - ProjNode* otherproj = proj->other_if_proj(); +bool IfNode::has_shared_region(IfProjNode* proj, IfProjNode*& success, IfProjNode*& fail) const { + IfProjNode* otherproj = proj->other_if_proj(); Node* otherproj_ctrl_use = otherproj->unique_ctrl_out_or_null(); RegionNode* region = (otherproj_ctrl_use != nullptr && otherproj_ctrl_use->is_Region()) ? otherproj_ctrl_use->as_Region() : nullptr; success = nullptr; @@ -793,13 +793,14 @@ bool IfNode::has_shared_region(ProjNode* proj, ProjNode*& success, ProjNode*& fa if (otherproj->outcnt() == 1 && region != nullptr && !region->has_phi()) { for (int i = 0; i < 2; i++) { - ProjNode* proj = proj_out(i); - if (success == nullptr && proj->outcnt() == 1 && proj->unique_out() == region) { - success = proj; + IfProjNode* next_proj = proj_out(i)->as_IfProj(); + if (success == nullptr && next_proj->outcnt() == 1 && next_proj->unique_out() == region) { + success = next_proj; } else if (fail == nullptr) { - fail = proj; + fail = next_proj; } else { - success = fail = nullptr; + success = nullptr; + fail = nullptr; } } } @@ -850,8 +851,8 @@ ProjNode* IfNode::uncommon_trap_proj(CallStaticJavaNode*& call, Deoptimization:: } // Do this If and the dominating If both branch out to an uncommon trap -bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNode*& fail, PhaseIterGVN* igvn) { - ProjNode* otherproj = proj->other_if_proj(); +bool IfNode::has_only_uncommon_traps(IfProjNode* proj, IfProjNode*& success, IfProjNode*& fail, PhaseIterGVN* igvn) const { + IfProjNode* otherproj = proj->other_if_proj(); CallStaticJavaNode* dom_unc = otherproj->is_uncommon_trap_proj(); if (otherproj->outcnt() == 1 && dom_unc != nullptr) { @@ -888,8 +889,8 @@ bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNod !igvn->C->too_many_traps(dom_method, dom_bci, Deoptimization::Reason_range_check) && // Return true if c2 manages to reconcile with UnstableIf optimization. See the comments for it. igvn->C->remove_unstable_if_trap(dom_unc, true/*yield*/)) { - success = unc_proj; - fail = unc_proj->other_if_proj(); + success = unc_proj->as_IfProj(); + fail = unc_proj->as_IfProj()->other_if_proj(); return true; } } @@ -898,7 +899,7 @@ bool IfNode::has_only_uncommon_traps(ProjNode* proj, ProjNode*& success, ProjNod } // Check that the 2 CmpI can be folded into as single CmpU and proceed with the folding -bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn) { +bool IfNode::fold_compares_helper(IfProjNode* proj, IfProjNode* success, IfProjNode* fail, PhaseIterGVN* igvn) { Node* this_cmp = in(1)->in(1); BoolNode* this_bool = in(1)->as_Bool(); IfNode* dom_iff = proj->in(0)->as_If(); @@ -906,7 +907,7 @@ bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* f Node* lo = dom_iff->in(1)->in(1)->in(2); Node* hi = this_cmp->in(2); Node* n = this_cmp->in(1); - ProjNode* otherproj = proj->other_if_proj(); + IfProjNode* otherproj = proj->other_if_proj(); const TypeInt* lo_type = IfNode::filtered_int_type(igvn, n, otherproj); const TypeInt* hi_type = IfNode::filtered_int_type(igvn, n, success); @@ -1108,11 +1109,11 @@ bool IfNode::fold_compares_helper(ProjNode* proj, ProjNode* success, ProjNode* f // Merge the branches that trap for this If and the dominating If into // a single region that branches to the uncommon trap for the // dominating If -Node* IfNode::merge_uncommon_traps(ProjNode* proj, ProjNode* success, ProjNode* fail, PhaseIterGVN* igvn) { +Node* IfNode::merge_uncommon_traps(IfProjNode* proj, IfProjNode* success, IfProjNode* fail, PhaseIterGVN* igvn) { Node* res = this; assert(success->in(0) == this, "bad projection"); - ProjNode* otherproj = proj->other_if_proj(); + IfProjNode* otherproj = proj->other_if_proj(); CallStaticJavaNode* unc = success->is_uncommon_trap_proj(); CallStaticJavaNode* dom_unc = otherproj->is_uncommon_trap_proj(); @@ -1239,7 +1240,7 @@ void IfNode::improve_address_types(Node* l, Node* r, ProjNode* fail, PhaseIterGV #endif } -bool IfNode::is_cmp_with_loadrange(ProjNode* proj) { +bool IfNode::is_cmp_with_loadrange(IfProjNode* proj) const { if (in(1) != nullptr && in(1)->in(1) != nullptr && in(1)->in(1)->in(2) != nullptr) { @@ -1258,7 +1259,7 @@ bool IfNode::is_cmp_with_loadrange(ProjNode* proj) { return false; } -bool IfNode::is_null_check(ProjNode* proj, PhaseIterGVN* igvn) { +bool IfNode::is_null_check(IfProjNode* proj, PhaseIterGVN* igvn) const { Node* other = in(1)->in(1)->in(2); if (other->in(MemNode::Address) != nullptr && proj->in(0)->in(1) != nullptr && @@ -1275,7 +1276,7 @@ bool IfNode::is_null_check(ProjNode* proj, PhaseIterGVN* igvn) { // Check that the If that is in between the 2 integer comparisons has // no side effect -bool IfNode::is_side_effect_free_test(ProjNode* proj, PhaseIterGVN* igvn) { +bool IfNode::is_side_effect_free_test(IfProjNode* proj, PhaseIterGVN* igvn) const { if (proj == nullptr) { return false; } @@ -1315,9 +1316,9 @@ bool IfNode::is_side_effect_free_test(ProjNode* proj, PhaseIterGVN* igvn) { // won't be guarded by the first CmpI anymore. It can trap in cases // where the first CmpI would have prevented it from executing: on a // trap, we need to restart execution at the state of the first CmpI -void IfNode::reroute_side_effect_free_unc(ProjNode* proj, ProjNode* dom_proj, PhaseIterGVN* igvn) { +void IfNode::reroute_side_effect_free_unc(IfProjNode* proj, IfProjNode* dom_proj, PhaseIterGVN* igvn) { CallStaticJavaNode* dom_unc = dom_proj->is_uncommon_trap_if_pattern(); - ProjNode* otherproj = proj->other_if_proj(); + IfProjNode* otherproj = proj->other_if_proj(); CallStaticJavaNode* unc = proj->is_uncommon_trap_if_pattern(); Node* call_proj = dom_unc->unique_ctrl_out(); Node* halt = call_proj->unique_ctrl_out(); @@ -1348,9 +1349,9 @@ Node* IfNode::fold_compares(PhaseIterGVN* igvn) { if (is_ctrl_folds(ctrl, igvn)) { // A integer comparison immediately dominated by another integer // comparison - ProjNode* success = nullptr; - ProjNode* fail = nullptr; - ProjNode* dom_cmp = ctrl->as_Proj(); + IfProjNode* success = nullptr; + IfProjNode* fail = nullptr; + IfProjNode* dom_cmp = ctrl->as_IfProj(); if (has_shared_region(dom_cmp, success, fail) && // Next call modifies graph so must be last fold_compares_helper(dom_cmp, success, fail, igvn)) { @@ -1364,11 +1365,11 @@ Node* IfNode::fold_compares(PhaseIterGVN* igvn) { return nullptr; } else if (ctrl->in(0) != nullptr && ctrl->in(0)->in(0) != nullptr) { - ProjNode* success = nullptr; - ProjNode* fail = nullptr; + IfProjNode* success = nullptr; + IfProjNode* fail = nullptr; Node* dom = ctrl->in(0)->in(0); - ProjNode* dom_cmp = dom->isa_Proj(); - ProjNode* other_cmp = ctrl->isa_Proj(); + IfProjNode* dom_cmp = dom->isa_IfProj(); + IfProjNode* other_cmp = ctrl->isa_IfProj(); // Check if it's an integer comparison dominated by another // integer comparison with another test in between diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 2263fa720ce..a057f66a989 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -6171,7 +6171,7 @@ LibraryCallKit::tightly_coupled_allocation(Node* ptr) { CallStaticJavaNode* LibraryCallKit::get_uncommon_trap_from_success_proj(Node* node) { if (node->is_IfProj()) { - Node* other_proj = node->as_IfProj()->other_if_proj(); + IfProjNode* other_proj = node->as_IfProj()->other_if_proj(); for (DUIterator_Fast jmax, j = other_proj->fast_outs(jmax); j < jmax; j++) { Node* obs = other_proj->fast_out(j); if (obs->in(0) == other_proj && obs->is_CallStaticJava() && diff --git a/src/hotspot/share/opto/memnode.cpp b/src/hotspot/share/opto/memnode.cpp index 19ff90df5ed..5b76f5b42cf 100644 --- a/src/hotspot/share/opto/memnode.cpp +++ b/src/hotspot/share/opto/memnode.cpp @@ -3103,7 +3103,7 @@ MergePrimitiveStores::CFGStatus MergePrimitiveStores::cfg_status_for_pair(const ctrl_use->in(0)->outcnt() != 2) { return CFGStatus::Failure; // Not RangeCheck. } - ProjNode* other_proj = ctrl_use->as_IfProj()->other_if_proj(); + IfProjNode* other_proj = ctrl_use->as_IfProj()->other_if_proj(); Node* trap = other_proj->is_uncommon_trap_proj(Deoptimization::Reason_range_check); if (trap != merge_mem->unique_out() || ctrl_use->in(0)->in(0) != ctrl_def) { diff --git a/src/hotspot/share/opto/multnode.cpp b/src/hotspot/share/opto/multnode.cpp index 9409a2f6af3..05867a35268 100644 --- a/src/hotspot/share/opto/multnode.cpp +++ b/src/hotspot/share/opto/multnode.cpp @@ -260,12 +260,7 @@ CallStaticJavaNode* ProjNode::is_uncommon_trap_if_pattern(Deoptimization::DeoptR // Not a projection of an If or variation of a dead If node. return nullptr; } - return other_if_proj()->is_uncommon_trap_proj(reason); -} - -ProjNode* ProjNode::other_if_proj() const { - assert(_con == 0 || _con == 1, "not an if?"); - return in(0)->as_If()->proj_out(1-_con); + return as_IfProj()->other_if_proj()->is_uncommon_trap_proj(reason); } NarrowMemProjNode::NarrowMemProjNode(InitializeNode* src, const TypePtr* adr_type) diff --git a/src/hotspot/share/opto/multnode.hpp b/src/hotspot/share/opto/multnode.hpp index be1351cc5b1..692b69118c9 100644 --- a/src/hotspot/share/opto/multnode.hpp +++ b/src/hotspot/share/opto/multnode.hpp @@ -200,9 +200,6 @@ public: // other_proj->[region->..]call_uct" // null otherwise CallStaticJavaNode* is_uncommon_trap_if_pattern(Deoptimization::DeoptReason reason = Deoptimization::Reason_none) const; - - // Return other proj node when this is a If proj node - ProjNode* other_if_proj() const; }; // A ProjNode variant that captures an adr_type(). Used as a projection of InitializeNode to have the right adr_type() diff --git a/src/hotspot/share/opto/predicates.cpp b/src/hotspot/share/opto/predicates.cpp index 2489ff563a9..89bc4374ca6 100644 --- a/src/hotspot/share/opto/predicates.cpp +++ b/src/hotspot/share/opto/predicates.cpp @@ -65,7 +65,7 @@ bool AssertionPredicate::has_assertion_predicate_opaque(const Node* predicate_pr // Check if the other projection (UCT projection) of `success_proj` has a Halt node as output. bool AssertionPredicate::has_halt(const IfTrueNode* success_proj) { - ProjNode* other_proj = success_proj->other_if_proj(); + IfProjNode* other_proj = success_proj->other_if_proj(); return other_proj->outcnt() == 1 && other_proj->unique_out()->Opcode() == Op_Halt; } @@ -396,7 +396,7 @@ bool InitializedAssertionPredicate::is_predicate(const Node* maybe_success_proj) #ifdef ASSERT bool InitializedAssertionPredicate::has_halt(const IfTrueNode* success_proj) { - ProjNode* other_proj = success_proj->other_if_proj(); + IfProjNode* other_proj = success_proj->other_if_proj(); if (other_proj->outcnt() != 1) { return false; } From 4e05748f0899cabb235c71ecdf4256d4ad137a0d Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Wed, 17 Dec 2025 18:17:24 +0000 Subject: [PATCH 045/390] 8373716: Refactor further java/util tests from TestNG to JUnit Reviewed-by: naoto --- .../Calendar/CalendarDisplayNamesTest.java | 12 +++--- .../util/Calendar/JapaneseLenientEraTest.java | 21 +++++----- .../SupplementalJapaneseEraTestRun.java | 16 ++++---- .../util/Properties/CompatibilityTest.java | 19 +++++----- .../java/util/Properties/EncodingTest.java | 18 +++++---- .../java/util/Properties/InitialCapacity.java | 14 ++++--- .../Properties/PropertiesEntrySetTest.java | 38 +++++++++---------- .../util/Properties/PropertiesStoreTest.java | 38 ++++++++++--------- .../modules/basic/BasicTest.java | 18 +++++---- .../modules/cache/CacheTest.java | 15 ++++---- .../CaseInsensitiveNameClash.java | 14 ++++--- .../modules/visibility/VisibilityTest.java | 36 +++++++++--------- .../java/util/TimeZone/NegativeDSTTest.java | 23 +++++------ .../util/TimeZone/ZoneIdRoundTripTest.java | 21 +++++----- 14 files changed, 162 insertions(+), 141 deletions(-) diff --git a/test/jdk/java/util/Calendar/CalendarDisplayNamesTest.java b/test/jdk/java/util/Calendar/CalendarDisplayNamesTest.java index 7c40714fc02..171bea55fcf 100644 --- a/test/jdk/java/util/Calendar/CalendarDisplayNamesTest.java +++ b/test/jdk/java/util/Calendar/CalendarDisplayNamesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -21,21 +21,21 @@ * questions. */ -import org.testng.Assert; -import org.testng.annotations.Test; import java.util.Calendar; import java.util.Locale; import java.util.Map; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; /** * @test * @bug 8262108 8174269 * @summary Verify the results returned by Calendar.getDisplayNames() API * @comment Locale providers: CLDR,SPI - * @run testng/othervm -Djava.locale.providers=CLDR,SPI CalendarDisplayNamesTest + * @run junit/othervm -Djava.locale.providers=CLDR,SPI CalendarDisplayNamesTest * @comment Locale providers: default - * @run testng CalendarDisplayNamesTest + * @run junit CalendarDisplayNamesTest */ public class CalendarDisplayNamesTest { @@ -55,7 +55,7 @@ public class CalendarDisplayNamesTest { continue; } for (final Integer fieldValue : names.values()) { - Assert.assertTrue(fieldValue == Calendar.AM || fieldValue == Calendar.PM, + Assertions.assertTrue(fieldValue == Calendar.AM || fieldValue == Calendar.PM, "Invalid field value " + fieldValue + " for calendar field AM_PM, in locale " + locale + " with style " + style); } diff --git a/test/jdk/java/util/Calendar/JapaneseLenientEraTest.java b/test/jdk/java/util/Calendar/JapaneseLenientEraTest.java index 6a909a23a18..ca726afc29b 100644 --- a/test/jdk/java/util/Calendar/JapaneseLenientEraTest.java +++ b/test/jdk/java/util/Calendar/JapaneseLenientEraTest.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 @@ -25,7 +25,7 @@ * @test * @bug 8206120 * @summary Test whether lenient era is accepted in JapaneseImperialCalendar - * @run testng/othervm JapaneseLenientEraTest + * @run junit/othervm JapaneseLenientEraTest */ import java.text.DateFormat; @@ -34,15 +34,15 @@ import java.util.Calendar; import java.util.Date; import java.util.Locale; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; -import static org.testng.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -@Test +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class JapaneseLenientEraTest { - @DataProvider(name="lenientEra") - Object[][] names() { + Object[][] lenientEra() { return new Object[][] { // lenient era/year, strict era/year { "Meiji 123", "Heisei 2" }, @@ -51,7 +51,8 @@ public class JapaneseLenientEraTest { }; } - @Test(dataProvider="lenientEra") + @ParameterizedTest + @MethodSource("lenientEra") public void testLenientEra(String lenient, String strict) throws Exception { Calendar c = new Calendar.Builder() .setCalendarType("japanese") @@ -61,6 +62,6 @@ public class JapaneseLenientEraTest { Date lenDate = df.parse(lenient + "-01-01"); df.setLenient(false); Date strDate = df.parse(strict + "-01-01"); - assertEquals(lenDate, strDate); + assertEquals(strDate, lenDate); } } diff --git a/test/jdk/java/util/Calendar/SupplementalJapaneseEraTestRun.java b/test/jdk/java/util/Calendar/SupplementalJapaneseEraTestRun.java index 8eac4a97ef7..878955fdcc4 100644 --- a/test/jdk/java/util/Calendar/SupplementalJapaneseEraTestRun.java +++ b/test/jdk/java/util/Calendar/SupplementalJapaneseEraTestRun.java @@ -27,7 +27,7 @@ * @summary Test for jdk.calendar.japanese.supplemental.era support * @library /test/lib * @build SupplementalJapaneseEraTest - * @run testng/othervm SupplementalJapaneseEraTestRun + * @run junit/othervm SupplementalJapaneseEraTestRun */ import java.util.Calendar; @@ -45,11 +45,12 @@ import static java.util.Calendar.YEAR; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.Utils; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class SupplementalJapaneseEraTestRun { - @DataProvider(name = "validprop") Object[][] validPropertyData() { return new Object[][] { //Tests with valid property values @@ -58,7 +59,6 @@ public class SupplementalJapaneseEraTestRun { }; } - @DataProvider(name = "invalidprop") Object[][] invalidPropertyData() { return new Object[][] { //Tests with invalid property values @@ -76,7 +76,8 @@ public class SupplementalJapaneseEraTestRun { }; } - @Test(dataProvider = "validprop") + @ParameterizedTest + @MethodSource("validPropertyData") public void ValidPropertyValuesTest(String prop) throws Throwable { //get the start time of the fictional next era @@ -84,7 +85,8 @@ public class SupplementalJapaneseEraTestRun { testRun(prop + startTime, List.of("-t")); } - @Test(dataProvider = "invalidprop") + @ParameterizedTest + @MethodSource("invalidPropertyData") public void InvalidPropertyValuesTest(String prop) throws Throwable { //get the start time of the fictional next era diff --git a/test/jdk/java/util/Properties/CompatibilityTest.java b/test/jdk/java/util/Properties/CompatibilityTest.java index 29c7be6fbcd..839680806c1 100644 --- a/test/jdk/java/util/Properties/CompatibilityTest.java +++ b/test/jdk/java/util/Properties/CompatibilityTest.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 @@ -24,19 +24,19 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Properties; -import org.testng.Assert; - -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /* * @test * @bug 8252354 - * @run testng CompatibilityTest + * @run junit CompatibilityTest * @summary Verify compatibility. */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class CompatibilityTest { - @DataProvider(name = "entries") public Object[][] getEntries() throws IOException { return new Object[][]{ {8, 238923}, @@ -53,9 +53,10 @@ public class CompatibilityTest { * @param value the value * @throws IOException */ - @Test(dataProvider = "entries") + @ParameterizedTest + @MethodSource("getEntries") void testThrows(Object key, Object value) throws IOException { - Assert.assertThrows(ClassCastException.class, () -> storeToXML(key, value)); + Assertions.assertThrows(ClassCastException.class, () -> storeToXML(key, value)); } void storeToXML(Object key, Object value) throws IOException { diff --git a/test/jdk/java/util/Properties/EncodingTest.java b/test/jdk/java/util/Properties/EncodingTest.java index d97730a37c7..069d16155f0 100644 --- a/test/jdk/java/util/Properties/EncodingTest.java +++ b/test/jdk/java/util/Properties/EncodingTest.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 @@ -27,19 +27,20 @@ import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.Properties; -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * @test * @bug 8183743 * @summary Test to verify the new overload method with Charset functions the * same as the existing method that takes a charset name. - * @run testng EncodingTest + * @run junit EncodingTest */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class EncodingTest { - @DataProvider(name = "parameters") public Object[][] getParameters() throws IOException { return new Object[][]{ {StandardCharsets.UTF_8.name(), null}, @@ -51,7 +52,8 @@ public class EncodingTest { * encoding name or a charset can be read with Properties#loadFromXML that * returns the same Properties object. */ - @Test(dataProvider = "parameters") + @ParameterizedTest + @MethodSource("getParameters") void testLoadAndStore(String encoding, Charset charset) throws IOException { Properties props = new Properties(); props.put("k0", "\u6C34"); @@ -74,6 +76,6 @@ public class EncodingTest { } } - Assert.assertEquals(props, p); + Assertions.assertEquals(p, props); } } diff --git a/test/jdk/java/util/Properties/InitialCapacity.java b/test/jdk/java/util/Properties/InitialCapacity.java index 81e5421bbef..d684c37adf4 100644 --- a/test/jdk/java/util/Properties/InitialCapacity.java +++ b/test/jdk/java/util/Properties/InitialCapacity.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 @@ -22,18 +22,22 @@ */ import java.util.Properties; -import org.testng.annotations.Test; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; /* * @test * @bug 8189319 * @summary Test that Properties(int initialCapacity) throws exceptions (or doesn't) as expected - * @run testng InitialCapacity + * @run junit InitialCapacity */ public class InitialCapacity { - @Test(expectedExceptions = IllegalArgumentException.class) - public void negativeInitCap() { Properties p = new Properties(-1); } + @Test + public void negativeInitCap() { Assertions.assertThrows(IllegalArgumentException.class, () -> { + Properties p = new Properties(-1); + }); +} @Test public void positiveInitCap() { Properties p = new Properties(10); } diff --git a/test/jdk/java/util/Properties/PropertiesEntrySetTest.java b/test/jdk/java/util/Properties/PropertiesEntrySetTest.java index d7d58be44dd..f3262f734e3 100644 --- a/test/jdk/java/util/Properties/PropertiesEntrySetTest.java +++ b/test/jdk/java/util/Properties/PropertiesEntrySetTest.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 @@ -26,17 +26,17 @@ * @bug 8245694 * @summary tests the entrySet() method of Properties class * @author Yu Li - * @run testng PropertiesEntrySetTest + * @run junit PropertiesEntrySetTest */ -import org.testng.annotations.Test; import java.util.Properties; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertThrows; -import static org.testng.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; public class PropertiesEntrySetTest { @@ -99,13 +99,13 @@ public class PropertiesEntrySetTest { public void testToString() { Properties a = new Properties(); var aEntrySet = a.entrySet(); - assertEquals(aEntrySet.toString(), "[]"); + assertEquals("[]", aEntrySet.toString()); a.setProperty("p1", "1"); - assertEquals(aEntrySet.toString(), "[p1=1]"); + assertEquals("[p1=1]", aEntrySet.toString()); a.setProperty("p2", "2"); - assertEquals(aEntrySet.size(), 2); + assertEquals(2, aEntrySet.size()); assertTrue(aEntrySet.toString().trim().startsWith("[")); assertTrue(aEntrySet.toString().contains("p1=1")); assertTrue(aEntrySet.toString().contains("p2=2")); @@ -115,18 +115,18 @@ public class PropertiesEntrySetTest { b.setProperty("p2", "2"); b.setProperty("p1", "1"); var bEntrySet = b.entrySet(); - assertEquals(bEntrySet.size(), 2); + assertEquals(2, bEntrySet.size()); assertTrue(bEntrySet.toString().trim().startsWith("[")); assertTrue(bEntrySet.toString().contains("p1=1")); assertTrue(bEntrySet.toString().contains("p2=2")); assertTrue(bEntrySet.toString().trim().endsWith("]")); b.setProperty("p0", "0"); - assertEquals(bEntrySet.size(), 3); + assertEquals(3, bEntrySet.size()); assertTrue(bEntrySet.toString().contains("p0=0")); b.remove("p1"); - assertEquals(bEntrySet.size(), 2); + assertEquals(2, bEntrySet.size()); assertFalse(bEntrySet.toString().contains("p1=1")); assertTrue(bEntrySet.toString().trim().startsWith("[")); assertTrue(bEntrySet.toString().contains("p0=0")); @@ -134,7 +134,7 @@ public class PropertiesEntrySetTest { assertTrue(bEntrySet.toString().trim().endsWith("]")); b.remove("p0", "0"); - assertEquals(bEntrySet.size(), 1); + assertEquals(1, bEntrySet.size()); assertFalse(bEntrySet.toString().contains("p0=0")); assertTrue(bEntrySet.toString().trim().startsWith("[")); assertTrue(bEntrySet.toString().contains("p2=2")); @@ -151,13 +151,13 @@ public class PropertiesEntrySetTest { a.setProperty("p1", "1"); a.setProperty("p2", "2"); var aEntrySet = a.entrySet(); - assertEquals(aEntrySet.size(), 2); + assertEquals(2, aEntrySet.size()); var i = aEntrySet.iterator(); var e1 = i.next(); i.remove(); assertFalse(aEntrySet.contains(e1)); - assertEquals(aEntrySet.size(), 1); + assertEquals(1, aEntrySet.size()); var e2 = i.next(); aEntrySet.remove(e2); @@ -172,14 +172,14 @@ public class PropertiesEntrySetTest { var bEntrySet = b.entrySet(); assertFalse(bEntrySet.containsAll(aEntrySet)); - assertEquals(bEntrySet.size(), 2); + assertEquals(2, bEntrySet.size()); assertTrue(bEntrySet.removeAll(aEntrySet)); - assertEquals(bEntrySet.size(), 1); + assertEquals(1, bEntrySet.size()); assertTrue(bEntrySet.retainAll(aEntrySet)); assertTrue(bEntrySet.isEmpty()); - assertEquals(aEntrySet.size(), 2); + assertEquals(2, aEntrySet.size()); aEntrySet.clear(); assertTrue(aEntrySet.isEmpty()); diff --git a/test/jdk/java/util/Properties/PropertiesStoreTest.java b/test/jdk/java/util/Properties/PropertiesStoreTest.java index b5a5b5a45aa..88c24698a14 100644 --- a/test/jdk/java/util/Properties/PropertiesStoreTest.java +++ b/test/jdk/java/util/Properties/PropertiesStoreTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -21,9 +21,6 @@ * questions. */ -import org.testng.Assert; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import java.io.BufferedReader; import java.io.IOException; @@ -45,13 +42,18 @@ import java.util.Properties; import java.util.Set; import java.util.TreeSet; import java.util.stream.Collectors; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /* * @test * @summary tests the order in which the Properties.store() method writes out the properties * @bug 8231640 8282023 - * @run testng/othervm PropertiesStoreTest + * @run junit/othervm PropertiesStoreTest */ +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class PropertiesStoreTest { private static final String DATE_FORMAT_PATTERN = "EEE MMM dd HH:mm:ss zzz uuuu"; @@ -60,7 +62,6 @@ public class PropertiesStoreTest { private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(DATE_FORMAT_PATTERN, Locale.US); private static final Locale PREV_LOCALE = Locale.getDefault(); - @DataProvider(name = "propsProvider") private Object[][] createProps() { final Properties simple = new Properties(); simple.setProperty("1", "one"); @@ -101,7 +102,6 @@ public class PropertiesStoreTest { /** * Returns a {@link Locale} to use for testing */ - @DataProvider(name = "localeProvider") private Object[][] provideLocales() { // pick a non-english locale for testing Set locales = Arrays.stream(Locale.getAvailableLocales()) @@ -122,7 +122,8 @@ public class PropertiesStoreTest { * Tests that the {@link Properties#store(Writer, String)} API writes out the properties * in the expected order */ - @Test(dataProvider = "propsProvider") + @ParameterizedTest + @MethodSource("createProps") public void testStoreWriterKeyOrder(final Properties props, final String[] expectedOrder) throws Exception { // Properties.store(...) to a temp file final Path tmpFile = Files.createTempFile("8231640", "props"); @@ -136,7 +137,8 @@ public class PropertiesStoreTest { * Tests that the {@link Properties#store(OutputStream, String)} API writes out the properties * in the expected order */ - @Test(dataProvider = "propsProvider") + @ParameterizedTest + @MethodSource("createProps") public void testStoreOutputStreamKeyOrder(final Properties props, final String[] expectedOrder) throws Exception { // Properties.store(...) to a temp file final Path tmpFile = Files.createTempFile("8231640", "props"); @@ -161,7 +163,7 @@ public class PropertiesStoreTest { try (final InputStream is = Files.newInputStream(storedProps)) { loaded.load(is); } - Assert.assertEquals(loaded, props, "Unexpected properties loaded from stored state"); + Assertions.assertEquals(props, loaded, "Unexpected properties loaded from stored state"); // now read lines from the stored file and keep track of the order in which the keys were // found in that file. Compare that order with the expected store order of the keys. @@ -169,10 +171,10 @@ public class PropertiesStoreTest { try (final BufferedReader reader = Files.newBufferedReader(storedProps)) { actualOrder = readInOrder(reader); } - Assert.assertEquals(actualOrder.size(), expectedOrder.length, + Assertions.assertEquals(expectedOrder.length, actualOrder.size(), "Unexpected number of keys read from stored properties"); if (!Arrays.equals(actualOrder.toArray(new String[0]), expectedOrder)) { - Assert.fail("Unexpected order of stored property keys. Expected order: " + Arrays.toString(expectedOrder) + Assertions.fail("Unexpected order of stored property keys. Expected order: " + Arrays.toString(expectedOrder) + ", found order: " + actualOrder); } } @@ -180,7 +182,8 @@ public class PropertiesStoreTest { /** * Tests that {@link Properties#store(Writer, String)} writes out a proper date comment */ - @Test(dataProvider = "localeProvider") + @ParameterizedTest + @MethodSource("provideLocales") public void testStoreWriterDateComment(final Locale testLocale) throws Exception { // switch the default locale to the one being tested Locale.setDefault(testLocale); @@ -202,7 +205,8 @@ public class PropertiesStoreTest { /** * Tests that {@link Properties#store(OutputStream, String)} writes out a proper date comment */ - @Test(dataProvider = "localeProvider") + @ParameterizedTest + @MethodSource("provideLocales") public void testStoreOutputStreamDateComment(final Locale testLocale) throws Exception { // switch the default locale to the one being tested Locale.setDefault(testLocale); @@ -232,19 +236,19 @@ public class PropertiesStoreTest { while ((line = reader.readLine()) != null) { if (line.startsWith("#")) { if (comment != null) { - Assert.fail("More than one comment line found in the stored properties file " + file); + Assertions.fail("More than one comment line found in the stored properties file " + file); } comment = line.substring(1); } } } if (comment == null) { - Assert.fail("No comment line found in the stored properties file " + file); + Assertions.fail("No comment line found in the stored properties file " + file); } try { FORMATTER.parse(comment); } catch (DateTimeParseException pe) { - Assert.fail("Unexpected date comment: " + comment, pe); + Assertions.fail("Unexpected date comment: " + comment, pe); } } diff --git a/test/jdk/java/util/ResourceBundle/modules/basic/BasicTest.java b/test/jdk/java/util/ResourceBundle/modules/basic/BasicTest.java index 69f0db83258..c17c4622ecb 100644 --- a/test/jdk/java/util/ResourceBundle/modules/basic/BasicTest.java +++ b/test/jdk/java/util/ResourceBundle/modules/basic/BasicTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, 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 @@ -43,7 +43,7 @@ * jdk.test.lib.compiler.CompilerUtils * jdk.test.lib.process.ProcessTools * ModuleTestUtil - * @run testng BasicTest + * @run junit BasicTest */ import java.nio.file.Path; @@ -54,13 +54,15 @@ import jdk.test.lib.JDKToolLauncher; import jdk.test.lib.Utils; import jdk.test.lib.compiler.CompilerUtils; import jdk.test.lib.process.ProcessTools; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; import static jdk.test.lib.Asserts.assertEquals; -import static org.testng.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -@Test +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class BasicTest { private static final String SRC_DIR_APPBASIC = "srcAppbasic"; private static final String SRC_DIR_APPBASIC2 = "srcAppbasic2"; @@ -92,7 +94,6 @@ public class BasicTest { private static final String MAIN = "test/jdk.test.Main"; - @DataProvider(name = "basicTestData") Object[][] basicTestData() { return new Object[][] { // Named module "test" contains resource bundles for root and en, @@ -122,7 +123,8 @@ public class BasicTest { }; } - @Test(dataProvider = "basicTestData") + @ParameterizedTest + @MethodSource("basicTestData") public void runBasicTest(String src, String mod, List moduleList, List localeList, String resFormat) throws Throwable { Path srcPath = Paths.get(Utils.TEST_SRC, src); diff --git a/test/jdk/java/util/ResourceBundle/modules/cache/CacheTest.java b/test/jdk/java/util/ResourceBundle/modules/cache/CacheTest.java index 5655eb5de2d..df72af38855 100644 --- a/test/jdk/java/util/ResourceBundle/modules/cache/CacheTest.java +++ b/test/jdk/java/util/ResourceBundle/modules/cache/CacheTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -27,7 +27,7 @@ * @library /test/lib * @modules jdk.compiler * @build CacheTest jdk.test.lib.compiler.CompilerUtils - * @run testng CacheTest + * @run junit CacheTest */ import java.nio.file.Files; @@ -37,11 +37,12 @@ import java.nio.file.Paths; import static jdk.test.lib.process.ProcessTools.*; import jdk.test.lib.compiler.CompilerUtils; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; -@Test +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class CacheTest { private static final String TEST_SRC = System.getProperty("test.src"); @@ -55,7 +56,7 @@ public class CacheTest { private static final String MAIN = "test/jdk.test.Main"; private static final String MAIN_CLASS = "jdk.test.Main"; - @BeforeTest + @BeforeAll public void compileTestModules() throws Exception { for (String mn : new String[] {MAIN_BUNDLES_MODULE, TEST_MODULE}) { diff --git a/test/jdk/java/util/ResourceBundle/modules/casesensitive/CaseInsensitiveNameClash.java b/test/jdk/java/util/ResourceBundle/modules/casesensitive/CaseInsensitiveNameClash.java index 914ebf6bbf0..45f52b512c8 100644 --- a/test/jdk/java/util/ResourceBundle/modules/casesensitive/CaseInsensitiveNameClash.java +++ b/test/jdk/java/util/ResourceBundle/modules/casesensitive/CaseInsensitiveNameClash.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, 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 @@ -28,7 +28,7 @@ * @modules jdk.compiler * @build jdk.test.lib.compiler.CompilerUtils * jdk.test.lib.process.ProcessTools CaseInsensitiveNameClash - * @run testng CaseInsensitiveNameClash + * @run junit CaseInsensitiveNameClash */ import java.nio.file.Files; @@ -37,10 +37,12 @@ import java.nio.file.Paths; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.compiler.CompilerUtils; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; -import static org.testng.Assert.*; +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class CaseInsensitiveNameClash { private static final String TEST_SRC = System.getProperty("test.src"); @@ -54,7 +56,7 @@ public class CaseInsensitiveNameClash { /** * Compiles the module used by the test */ - @BeforeTest + @BeforeAll public void compileAll() throws Exception { Path msrc = SRC_DIR.resolve(MODULE); assertTrue(CompilerUtils.compile(msrc, MODS_DIR, diff --git a/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java b/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java index e0fdb9a93ab..ee9da88d705 100644 --- a/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.java +++ b/test/jdk/java/util/ResourceBundle/modules/visibility/VisibilityTest.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 @@ -34,7 +34,7 @@ * jdk.test.lib.compiler.CompilerUtils * jdk.test.lib.process.ProcessTools * ModuleTestUtil - * @run testng VisibilityTest + * @run junit VisibilityTest */ import java.nio.file.Path; @@ -46,13 +46,13 @@ import jdk.test.lib.JDKToolLauncher; import jdk.test.lib.Utils; import jdk.test.lib.process.ProcessTools; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -import static org.testng.Assert.assertEquals; - -@Test +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class VisibilityTest { private static final Path SRC_DIR = Paths.get(Utils.TEST_SRC, "src"); private static final Path MODS_DIR = Paths.get(Utils.TEST_CLASSES, "mods"); @@ -63,7 +63,7 @@ public class VisibilityTest { private static final List MODULE_LIST = List.of("embargo", "exported.named.bundles", "named.bundles", "test"); - @BeforeTest + @BeforeAll public void prepareTestEnv() throws Throwable { MODULE_LIST.forEach(mn -> ModuleTestUtil.prepareModule(SRC_DIR, MODS_DIR, mn, ".properties")); @@ -93,7 +93,6 @@ public class VisibilityTest { * "exported.named.bundle" are exported to unnamed modules. */ - @DataProvider(name = "RunWithTestResData") Object[][] RunWithTestResData() { return new Object[][] { // Tests using jdk.test.TestWithNoModuleArg and jdk.embargo.TestWithNoModuleArg. @@ -188,7 +187,6 @@ public class VisibilityTest { }; } - @DataProvider(name = "RunWithExportedResData") Object[][] RunWithExportedResData() { return new Object[][] { // Tests using jdk.test.TestWithNoModuleArg and jdk.embargo.TestWithNoModuleArg @@ -285,7 +283,6 @@ public class VisibilityTest { }; } - @DataProvider(name = "RunWithPkgResData") Object[][] RunWithPkgResData() { return new Object[][] { // jdk.pkg.resources.* are in an unnamed module. @@ -300,10 +297,11 @@ public class VisibilityTest { /** * Test cases with jdk.test.resources.* */ - @Test(dataProvider = "RunWithTestResData") + @ParameterizedTest + @MethodSource("RunWithTestResData") public void RunWithTestRes(List argsList) throws Throwable { int exitCode = runCmd(argsList); - assertEquals(exitCode, 0, "Execution of the tests with " + assertEquals(0, exitCode, "Execution of the tests with " + "jdk.test.resources.* failed. " + "Unexpected exit code: " + exitCode); } @@ -311,10 +309,11 @@ public class VisibilityTest { /** * Test cases with jdk.test.resources.exported.* */ - @Test(dataProvider = "RunWithExportedResData") + @ParameterizedTest + @MethodSource("RunWithExportedResData") public void RunWithExportedRes(List argsList) throws Throwable { int exitCode = runCmd(argsList); - assertEquals(exitCode, 0, "Execution of the tests with " + assertEquals(0, exitCode, "Execution of the tests with " + "jdk.test.resources.exported.* failed. " + "Unexpected exit code: " + exitCode); } @@ -322,10 +321,11 @@ public class VisibilityTest { /** * Test cases with jdk.pkg.resources.* */ - @Test(dataProvider = "RunWithPkgResData") + @ParameterizedTest + @MethodSource("RunWithPkgResData") public void RunWithPkgRes(List argsList) throws Throwable { int exitCode = runCmd(argsList); - assertEquals(exitCode, 0, "Execution of the tests with " + assertEquals(0, exitCode, "Execution of the tests with " + "jdk.pkg.resources.* failed. " + "Unexpected exit code: " + exitCode); } diff --git a/test/jdk/java/util/TimeZone/NegativeDSTTest.java b/test/jdk/java/util/TimeZone/NegativeDSTTest.java index eb46b8d4b29..ab9438f2388 100644 --- a/test/jdk/java/util/TimeZone/NegativeDSTTest.java +++ b/test/jdk/java/util/TimeZone/NegativeDSTTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2024, 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 @@ -21,7 +21,7 @@ * questions. */ -import static org.testng.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.time.Instant; import java.time.LocalDate; @@ -31,18 +31,19 @@ import java.time.ZoneId; import java.util.Date; import java.util.TimeZone; -import org.testng.annotations.Test; -import org.testng.annotations.DataProvider; -import static org.testng.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * @test * @bug 8212970 8324065 * @summary Test whether the savings are positive in time zones that have * negative savings in the source TZ files. - * @run testng NegativeDSTTest + * @run junit NegativeDSTTest */ -@Test +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class NegativeDSTTest { private static final TimeZone DUBLIN = TimeZone.getTimeZone("Europe/Dublin"); @@ -51,7 +52,6 @@ public class NegativeDSTTest { private static final TimeZone CASABLANCA = TimeZone.getTimeZone("Africa/Casablanca"); private static final int ONE_HOUR = 3600_000; - @DataProvider private Object[][] negativeDST () { return new Object[][] { // TimeZone, localDate, offset, isDaylightSavings @@ -88,10 +88,11 @@ public class NegativeDSTTest { }; } - @Test(dataProvider="negativeDST") + @ParameterizedTest + @MethodSource("negativeDST") public void test_NegativeDST(TimeZone tz, LocalDate ld, int offset, boolean isDST) { Date d = Date.from(Instant.from(ZonedDateTime.of(ld, LocalTime.MIN, tz.toZoneId()))); - assertEquals(tz.getOffset(d.getTime()), offset); - assertEquals(tz.inDaylightTime(d), isDST); + assertEquals(offset, tz.getOffset(d.getTime())); + assertEquals(isDST, tz.inDaylightTime(d)); } } diff --git a/test/jdk/java/util/TimeZone/ZoneIdRoundTripTest.java b/test/jdk/java/util/TimeZone/ZoneIdRoundTripTest.java index 0f1eeb88328..16e24f7cb27 100644 --- a/test/jdk/java/util/TimeZone/ZoneIdRoundTripTest.java +++ b/test/jdk/java/util/TimeZone/ZoneIdRoundTripTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 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 @@ -25,20 +25,20 @@ import java.time.ZoneId; import java.time.ZoneOffset; import java.util.TimeZone; -import org.testng.annotations.Test; -import org.testng.annotations.DataProvider; -import static org.testng.Assert.assertEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; /** * @test * @bug 8285844 * @summary Checks round-trips between TimeZone and ZoneId are consistent - * @run testng ZoneIdRoundTripTest + * @run junit ZoneIdRoundTripTest */ -@Test +@TestInstance(TestInstance.Lifecycle.PER_CLASS) public class ZoneIdRoundTripTest { - @DataProvider private Object[][] testZoneIds() { return new Object[][] { {ZoneId.of("Z"), 0}, @@ -60,11 +60,12 @@ public class ZoneIdRoundTripTest { }; } - @Test(dataProvider="testZoneIds") + @ParameterizedTest + @MethodSource("testZoneIds") public void test_ZoneIdRoundTrip(ZoneId zid, int offset) { var tz = TimeZone.getTimeZone(zid); - assertEquals(tz.getRawOffset(), offset); - assertEquals(tz.toZoneId().normalized(), zid.normalized()); + assertEquals(offset, tz.getRawOffset()); + assertEquals(zid.normalized(), tz.toZoneId().normalized()); } } From f3a48560b5e3a280f6f76031eb3d475ff9ee49f4 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Wed, 17 Dec 2025 18:44:49 +0000 Subject: [PATCH 046/390] 8373807: test/jdk/java/net/httpclient/websocket/DummyWebSocketServer.java getURI() uses "localhost" Reviewed-by: jpai --- .../net/httpclient/websocket/DummyWebSocketServer.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/jdk/java/net/httpclient/websocket/DummyWebSocketServer.java b/test/jdk/java/net/httpclient/websocket/DummyWebSocketServer.java index 9034cf9f28a..abc1748e3f2 100644 --- a/test/jdk/java/net/httpclient/websocket/DummyWebSocketServer.java +++ b/test/jdk/java/net/httpclient/websocket/DummyWebSocketServer.java @@ -351,7 +351,14 @@ public class DummyWebSocketServer implements Closeable { if (!started.get()) { throw new IllegalStateException("Not yet started"); } - return URI.create("ws://localhost:" + address.getPort()); + String ip = address.getAddress().isAnyLocalAddress() + ? InetAddress.getLoopbackAddress().getHostAddress() + : address.getAddress().getHostAddress(); + if (ip.indexOf(':') >= 0) { + ip = String.format("[%s]", ip); + } + + return URI.create("ws://" + ip + ":" + address.getPort()); } private boolean readRequest(SocketChannel channel, StringBuilder request) From e75726ee03ca4664827ca5d680c02bcf2a96f4ea Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Wed, 17 Dec 2025 20:52:14 +0000 Subject: [PATCH 047/390] 8373832: Test java/lang/invoke/TestVHInvokerCaching.java tests nothing Reviewed-by: jvernee, shade --- test/jdk/java/lang/invoke/TestVHInvokerCaching.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/jdk/java/lang/invoke/TestVHInvokerCaching.java b/test/jdk/java/lang/invoke/TestVHInvokerCaching.java index ccd97f82e9b..0a1ae5914ca 100644 --- a/test/jdk/java/lang/invoke/TestVHInvokerCaching.java +++ b/test/jdk/java/lang/invoke/TestVHInvokerCaching.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -37,7 +37,7 @@ import java.util.ArrayList; import java.util.List; import static java.lang.invoke.MethodHandles.lookup; -import static org.testng.Assert.assertSame; +import static org.testng.Assert.*; public class TestVHInvokerCaching { @@ -74,7 +74,7 @@ public class TestVHInvokerCaching { MethodHandles.Lookup lookup = lookup(); - for (Field field : Holder.class.getFields()) { + for (Field field : Holder.class.getDeclaredFields()) { String fieldName = field.getName(); Class fieldType = field.getType(); @@ -82,6 +82,8 @@ public class TestVHInvokerCaching { testHandles.add(lookup.findVarHandle(Holder.class, fieldName, fieldType)); } + assertFalse(testHandles.isEmpty()); + return testHandles.stream().map(vh -> new Object[]{ vh }).toArray(Object[][]::new); } } From b3fab41460eabf253879d140b55b6b12036c7c10 Mon Sep 17 00:00:00 2001 From: David Holmes Date: Wed, 17 Dec 2025 22:14:39 +0000 Subject: [PATCH 048/390] 8373654: Tests in sources/ should only run once Reviewed-by: shade, lmesnik --- test/hotspot/jtreg/sources/TestIncludesAreSorted.java | 2 ++ test/hotspot/jtreg/sources/TestNoNULL.java | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/hotspot/jtreg/sources/TestIncludesAreSorted.java b/test/hotspot/jtreg/sources/TestIncludesAreSorted.java index e0e77992ace..f8694da6c5a 100644 --- a/test/hotspot/jtreg/sources/TestIncludesAreSorted.java +++ b/test/hotspot/jtreg/sources/TestIncludesAreSorted.java @@ -24,6 +24,8 @@ /* * @test * @bug 8343802 + * @comment Only need to run this once, in tier1. + * @requires vm.flagless & vm.debug * @summary Tests that HotSpot C++ files have sorted includes * @build SortIncludes * @run main TestIncludesAreSorted diff --git a/test/hotspot/jtreg/sources/TestNoNULL.java b/test/hotspot/jtreg/sources/TestNoNULL.java index 9c993572aea..b914ea6c799 100644 --- a/test/hotspot/jtreg/sources/TestNoNULL.java +++ b/test/hotspot/jtreg/sources/TestNoNULL.java @@ -24,6 +24,8 @@ /* * @test * @bug 8343802 + * @comment Only need to run this once, in tier1. + * @requires vm.flagless & vm.debug * @summary Test prevent NULL backsliding in hotspot code and tests * @run main TestNoNULL */ From 232b41b2227bc9d03d88d316aa28d0cbe87086f7 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Wed, 17 Dec 2025 22:16:38 +0000 Subject: [PATCH 049/390] 8373392: Replace CDS object subgraphs with @AOTSafeClassInitializer Reviewed-by: liach, heidinga --- src/hotspot/share/cds/aotArtifactFinder.cpp | 6 +- src/hotspot/share/cds/aotClassInitializer.cpp | 6 +- src/hotspot/share/cds/aotMetaspace.cpp | 2 +- src/hotspot/share/cds/cdsConfig.cpp | 10 +- src/hotspot/share/cds/cdsConfig.hpp | 1 - src/hotspot/share/cds/cdsEnumKlass.cpp | 4 +- src/hotspot/share/cds/cdsEnumKlass.hpp | 2 +- src/hotspot/share/cds/cdsHeapVerifier.cpp | 2 +- src/hotspot/share/cds/finalImageRecipes.cpp | 2 + src/hotspot/share/cds/heapShared.cpp | 48 ++-- .../share/classes/java/lang/Byte.java | 2 + .../share/classes/java/lang/Character.java | 2 + .../share/classes/java/lang/Integer.java | 75 +++-- .../share/classes/java/lang/Long.java | 2 + .../share/classes/java/lang/Module.java | 2 + .../share/classes/java/lang/ModuleLayer.java | 2 + .../share/classes/java/lang/Short.java | 2 + .../java/lang/module/Configuration.java | 2 + .../java/util/ImmutableCollections.java | 15 +- .../classes/java/util/jar/Attributes.java | 4 + .../internal/loader/ArchivedClassLoaders.java | 2 + .../jdk/internal/math/FDBigInteger.java | 3 + .../internal/module/ArchivedBootLayer.java | 4 +- .../internal/module/ArchivedModuleGraph.java | 5 +- .../classes/sun/util/locale/BaseLocale.java | 14 +- test/hotspot/jtreg/TEST.groups | 1 + .../cds/SharedSymbolTableBucketSize.java | 44 ++- .../cds/appcds/aotCache/AOTLoggingTag.java | 11 - .../appcds/aotCache/HeapObjectIdentity.java | 261 ++++++++++++++++++ .../cacheObject/ArchiveHeapTestClass.java | 156 +---------- 30 files changed, 456 insertions(+), 236 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotCache/HeapObjectIdentity.java diff --git a/src/hotspot/share/cds/aotArtifactFinder.cpp b/src/hotspot/share/cds/aotArtifactFinder.cpp index 5f346e832a8..f85f1e46520 100644 --- a/src/hotspot/share/cds/aotArtifactFinder.cpp +++ b/src/hotspot/share/cds/aotArtifactFinder.cpp @@ -145,7 +145,7 @@ void AOTArtifactFinder::find_artifacts() { #if INCLUDE_CDS_JAVA_HEAP // Keep scanning until we discover no more class that need to be AOT-initialized. - if (CDSConfig::is_initing_classes_at_dump_time()) { + if (CDSConfig::is_dumping_aot_linked_classes()) { while (_pending_aot_inited_classes->length() > 0) { InstanceKlass* ik = _pending_aot_inited_classes->pop(); HeapShared::copy_and_rescan_aot_inited_mirror(ik); @@ -188,7 +188,7 @@ void AOTArtifactFinder::end_scanning_for_oops() { } void AOTArtifactFinder::add_aot_inited_class(InstanceKlass* ik) { - if (CDSConfig::is_initing_classes_at_dump_time()) { + if (CDSConfig::is_dumping_aot_linked_classes()) { if (RegeneratedClasses::is_regenerated_object(ik)) { precond(RegeneratedClasses::get_original_object(ik)->is_initialized()); } else { @@ -258,7 +258,7 @@ void AOTArtifactFinder::add_cached_instance_class(InstanceKlass* ik) { return; } scan_oops_in_instance_class(ik); - if (ik->is_hidden() && CDSConfig::is_initing_classes_at_dump_time()) { + if (ik->is_hidden() && CDSConfig::is_dumping_aot_linked_classes()) { bool succeed = AOTClassLinker::try_add_candidate(ik); guarantee(succeed, "All cached hidden classes must be aot-linkable"); add_aot_inited_class(ik); diff --git a/src/hotspot/share/cds/aotClassInitializer.cpp b/src/hotspot/share/cds/aotClassInitializer.cpp index 00db747622f..06fc3af6f30 100644 --- a/src/hotspot/share/cds/aotClassInitializer.cpp +++ b/src/hotspot/share/cds/aotClassInitializer.cpp @@ -40,7 +40,7 @@ DEBUG_ONLY(InstanceKlass* _aot_init_class = nullptr;) bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) { assert(!ArchiveBuilder::is_active() || !ArchiveBuilder::current()->is_in_buffer_space(ik), "must be source klass"); - if (!CDSConfig::is_initing_classes_at_dump_time()) { + if (!CDSConfig::is_dumping_aot_linked_classes()) { return false; } @@ -64,7 +64,7 @@ bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) { // Automatic selection for aot-inited classes // ========================================== // - // When CDSConfig::is_initing_classes_at_dump_time is enabled, + // When CDSConfig::is_dumping_aot_linked_classes is enabled, // AOTArtifactFinder::find_artifacts() finds the classes of all // heap objects that are reachable from HeapShared::_run_time_special_subgraph, // and mark these classes as aot-inited. This preserves the initialized @@ -310,7 +310,7 @@ void AOTClassInitializer::init_test_class(TRAPS) { // // -XX:AOTInitTestClass is NOT a general mechanism for including user-defined objects into // the AOT cache. Therefore, this option is NOT available in product JVM. - if (AOTInitTestClass != nullptr && CDSConfig::is_initing_classes_at_dump_time()) { + if (AOTInitTestClass != nullptr && CDSConfig::is_dumping_aot_linked_classes()) { log_info(aot)("Debug build only: force initialization of AOTInitTestClass %s", AOTInitTestClass); TempNewSymbol class_name = SymbolTable::new_symbol(AOTInitTestClass); Handle app_loader(THREAD, SystemDictionary::java_system_loader()); diff --git a/src/hotspot/share/cds/aotMetaspace.cpp b/src/hotspot/share/cds/aotMetaspace.cpp index 098d3baed58..3824a2be3e2 100644 --- a/src/hotspot/share/cds/aotMetaspace.cpp +++ b/src/hotspot/share/cds/aotMetaspace.cpp @@ -1141,7 +1141,7 @@ void AOTMetaspace::dump_static_archive_impl(StaticArchiveBuilder& builder, TRAPS AOTReferenceObjSupport::initialize(CHECK); AOTReferenceObjSupport::stabilize_cached_reference_objects(CHECK); - if (CDSConfig::is_initing_classes_at_dump_time()) { + if (CDSConfig::is_dumping_aot_linked_classes()) { // java.lang.Class::reflectionFactory cannot be archived yet. We set this field // to null, and it will be initialized again at runtime. log_debug(aot)("Resetting Class::reflectionFactory"); diff --git a/src/hotspot/share/cds/cdsConfig.cpp b/src/hotspot/share/cds/cdsConfig.cpp index 86533e212d8..5f6b568dd6e 100644 --- a/src/hotspot/share/cds/cdsConfig.cpp +++ b/src/hotspot/share/cds/cdsConfig.cpp @@ -1026,23 +1026,19 @@ void CDSConfig::set_has_aot_linked_classes(bool has_aot_linked_classes) { _has_aot_linked_classes |= has_aot_linked_classes; } -bool CDSConfig::is_initing_classes_at_dump_time() { - return is_dumping_heap() && is_dumping_aot_linked_classes(); -} - bool CDSConfig::is_dumping_invokedynamic() { // Requires is_dumping_aot_linked_classes(). Otherwise the classes of some archived heap // objects used by the archive indy callsites may be replaced at runtime. return AOTInvokeDynamicLinking && is_dumping_aot_linked_classes() && is_dumping_heap(); } -// When we are dumping aot-linked classes and we are able to write archived heap objects, we automatically -// enable the archiving of MethodHandles. This will in turn enable the archiving of MethodTypes and hidden +// When we are dumping aot-linked classes, we automatically enable the archiving of MethodHandles. +// This will in turn enable the archiving of MethodTypes and hidden // classes that are used in the implementation of MethodHandles. // Archived MethodHandles are required for higher-level optimizations such as AOT resolution of invokedynamic // and dynamic proxies. bool CDSConfig::is_dumping_method_handles() { - return is_initing_classes_at_dump_time(); + return is_dumping_aot_linked_classes(); } #endif // INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/cdsConfig.hpp b/src/hotspot/share/cds/cdsConfig.hpp index d199e97eefd..202904e8231 100644 --- a/src/hotspot/share/cds/cdsConfig.hpp +++ b/src/hotspot/share/cds/cdsConfig.hpp @@ -187,7 +187,6 @@ public: static void disable_heap_dumping() { CDS_ONLY(_disable_heap_dumping = true); } static bool is_dumping_heap() NOT_CDS_JAVA_HEAP_RETURN_(false); static bool is_loading_heap() NOT_CDS_JAVA_HEAP_RETURN_(false); - static bool is_initing_classes_at_dump_time() NOT_CDS_JAVA_HEAP_RETURN_(false); static bool is_dumping_invokedynamic() NOT_CDS_JAVA_HEAP_RETURN_(false); static bool is_dumping_method_handles() NOT_CDS_JAVA_HEAP_RETURN_(false); diff --git a/src/hotspot/share/cds/cdsEnumKlass.cpp b/src/hotspot/share/cds/cdsEnumKlass.cpp index 1bf6ba4eba8..177d1d6e3ad 100644 --- a/src/hotspot/share/cds/cdsEnumKlass.cpp +++ b/src/hotspot/share/cds/cdsEnumKlass.cpp @@ -40,7 +40,7 @@ bool CDSEnumKlass::is_enum_obj(oop orig_obj) { } // !!! This is legacy support for enum classes before JEP 483. This file is not used when -// !!! CDSConfig::is_initing_classes_at_dump_time()==true. +// !!! CDSConfig::is_dumping_aot_linked_classes()==true. // // Java Enum classes have synthetic methods that look like this // enum MyEnum {FOO, BAR} @@ -63,7 +63,7 @@ bool CDSEnumKlass::is_enum_obj(oop orig_obj) { void CDSEnumKlass::handle_enum_obj(int level, KlassSubGraphInfo* subgraph_info, oop orig_obj) { - assert(!CDSConfig::is_initing_classes_at_dump_time(), "only for legacy support of enums"); + assert(!CDSConfig::is_dumping_aot_linked_classes(), "only for legacy support of enums"); assert(level > 1, "must never be called at the first (outermost) level"); assert(is_enum_obj(orig_obj), "must be"); diff --git a/src/hotspot/share/cds/cdsEnumKlass.hpp b/src/hotspot/share/cds/cdsEnumKlass.hpp index e6019ff705e..a4829368430 100644 --- a/src/hotspot/share/cds/cdsEnumKlass.hpp +++ b/src/hotspot/share/cds/cdsEnumKlass.hpp @@ -35,7 +35,7 @@ class JavaFieldStream; class KlassSubGraphInfo; // This is legacy support for enum classes before JEP 483. This code is not needed when -// CDSConfig::is_initing_classes_at_dump_time()==true. +// CDSConfig::is_dumping_aot_linked_classes()==true. class CDSEnumKlass: AllStatic { public: static bool is_enum_obj(oop orig_obj); diff --git a/src/hotspot/share/cds/cdsHeapVerifier.cpp b/src/hotspot/share/cds/cdsHeapVerifier.cpp index 65063b4b005..3ed0dce1f66 100644 --- a/src/hotspot/share/cds/cdsHeapVerifier.cpp +++ b/src/hotspot/share/cds/cdsHeapVerifier.cpp @@ -156,7 +156,7 @@ CDSHeapVerifier::CDSHeapVerifier() : _archived_objs(0), _problems(0) # undef ADD_EXCL - if (CDSConfig::is_initing_classes_at_dump_time()) { + if (CDSConfig::is_dumping_aot_linked_classes()) { add_shared_secret_accessors(); } ClassLoaderDataGraph::classes_do(this); diff --git a/src/hotspot/share/cds/finalImageRecipes.cpp b/src/hotspot/share/cds/finalImageRecipes.cpp index bf8a760904c..8ba4514dfed 100644 --- a/src/hotspot/share/cds/finalImageRecipes.cpp +++ b/src/hotspot/share/cds/finalImageRecipes.cpp @@ -206,6 +206,8 @@ void FinalImageRecipes::load_all_classes(TRAPS) { if (ik->has_aot_safe_initializer() && (flags & WAS_INITED) != 0) { assert(ik->class_loader() == nullptr, "supported only for boot classes for now"); + ResourceMark rm(THREAD); + log_info(aot, init)("Initializing %s", ik->external_name()); ik->initialize(CHECK); } } diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index f2382289c7d..fdc335f3799 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -209,8 +209,14 @@ static bool is_subgraph_root_class_of(ArchivableStaticFieldInfo fields[], Instan } bool HeapShared::is_subgraph_root_class(InstanceKlass* ik) { - return is_subgraph_root_class_of(archive_subgraph_entry_fields, ik) || - is_subgraph_root_class_of(fmg_archive_subgraph_entry_fields, ik); + assert(CDSConfig::is_dumping_heap(), "dump-time only"); + if (!CDSConfig::is_dumping_aot_linked_classes()) { + // Legacy CDS archive support (to be deprecated) + return is_subgraph_root_class_of(archive_subgraph_entry_fields, ik) || + is_subgraph_root_class_of(fmg_archive_subgraph_entry_fields, ik); + } else { + return false; + } } oop HeapShared::CachedOopInfo::orig_referrer() const { @@ -934,12 +940,16 @@ void HeapShared::scan_java_class(Klass* orig_k) { void HeapShared::archive_subgraphs() { assert(CDSConfig::is_dumping_heap(), "must be"); - archive_object_subgraphs(archive_subgraph_entry_fields, - false /* is_full_module_graph */); + if (!CDSConfig::is_dumping_aot_linked_classes()) { + archive_object_subgraphs(archive_subgraph_entry_fields, + false /* is_full_module_graph */); + if (CDSConfig::is_dumping_full_module_graph()) { + archive_object_subgraphs(fmg_archive_subgraph_entry_fields, + true /* is_full_module_graph */); + } + } if (CDSConfig::is_dumping_full_module_graph()) { - archive_object_subgraphs(fmg_archive_subgraph_entry_fields, - true /* is_full_module_graph */); Modules::verify_archived_modules(); } } @@ -1295,8 +1305,10 @@ void HeapShared::resolve_classes(JavaThread* current) { if (!is_archived_heap_in_use()) { return; // nothing to do } - resolve_classes_for_subgraphs(current, archive_subgraph_entry_fields); - resolve_classes_for_subgraphs(current, fmg_archive_subgraph_entry_fields); + if (!CDSConfig::is_using_aot_linked_classes()) { + resolve_classes_for_subgraphs(current, archive_subgraph_entry_fields); + resolve_classes_for_subgraphs(current, fmg_archive_subgraph_entry_fields); + } } void HeapShared::resolve_classes_for_subgraphs(JavaThread* current, ArchivableStaticFieldInfo fields[]) { @@ -1734,13 +1746,13 @@ bool HeapShared::walk_one_object(PendingOopStack* stack, int level, KlassSubGrap } } - if (CDSConfig::is_initing_classes_at_dump_time()) { + if (CDSConfig::is_dumping_aot_linked_classes()) { if (java_lang_Class::is_instance(orig_obj)) { orig_obj = scratch_java_mirror(orig_obj); assert(orig_obj != nullptr, "must be archived"); } } else if (java_lang_Class::is_instance(orig_obj) && subgraph_info != _dump_time_special_subgraph) { - // Without CDSConfig::is_initing_classes_at_dump_time(), we only allow archived objects to + // Without CDSConfig::is_dumping_aot_linked_classes(), we only allow archived objects to // point to the mirrors of (1) j.l.Object, (2) primitive classes, and (3) box classes. These are initialized // very early by HeapShared::init_box_classes(). if (orig_obj == vmClasses::Object_klass()->java_mirror() @@ -1808,9 +1820,9 @@ bool HeapShared::walk_one_object(PendingOopStack* stack, int level, KlassSubGrap orig_obj->oop_iterate(&pusher); } - if (CDSConfig::is_initing_classes_at_dump_time()) { - // The classes of all archived enum instances have been marked as aot-init, - // so there's nothing else to be done in the production run. + if (CDSConfig::is_dumping_aot_linked_classes()) { + // The enum klasses are archived with aot-initialized mirror. + // See AOTClassInitializer::can_archive_initialized_mirror(). } else { // This is legacy support for enum classes before JEP 483 -- we cannot rerun // the enum's in the production run, so special handling is needed. @@ -1949,7 +1961,7 @@ void HeapShared::verify_reachable_objects_from(oop obj) { #endif void HeapShared::check_special_subgraph_classes() { - if (CDSConfig::is_initing_classes_at_dump_time()) { + if (CDSConfig::is_dumping_aot_linked_classes()) { // We can have aot-initialized classes (such as Enums) that can reference objects // of arbitrary types. Currently, we trust the JEP 483 implementation to only // aot-initialize classes that are "safe". @@ -2136,9 +2148,11 @@ void HeapShared::init_subgraph_entry_fields(ArchivableStaticFieldInfo fields[], void HeapShared::init_subgraph_entry_fields(TRAPS) { assert(CDSConfig::is_dumping_heap(), "must be"); _dump_time_subgraph_info_table = new (mtClass)DumpTimeKlassSubGraphInfoTable(); - init_subgraph_entry_fields(archive_subgraph_entry_fields, CHECK); - if (CDSConfig::is_dumping_full_module_graph()) { - init_subgraph_entry_fields(fmg_archive_subgraph_entry_fields, CHECK); + if (!CDSConfig::is_dumping_aot_linked_classes()) { + init_subgraph_entry_fields(archive_subgraph_entry_fields, CHECK); + if (CDSConfig::is_dumping_full_module_graph()) { + init_subgraph_entry_fields(fmg_archive_subgraph_entry_fields, CHECK); + } } } diff --git a/src/java.base/share/classes/java/lang/Byte.java b/src/java.base/share/classes/java/lang/Byte.java index d9913e354a4..0f3f7f40d05 100644 --- a/src/java.base/share/classes/java/lang/Byte.java +++ b/src/java.base/share/classes/java/lang/Byte.java @@ -26,6 +26,7 @@ package java.lang; import jdk.internal.misc.CDS; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; import jdk.internal.vm.annotation.IntrinsicCandidate; import jdk.internal.vm.annotation.Stable; @@ -103,6 +104,7 @@ public final class Byte extends Number implements Comparable, Constable { return Optional.of(DynamicConstantDesc.ofNamed(BSM_EXPLICIT_CAST, DEFAULT_NAME, CD_byte, intValue())); } + @AOTSafeClassInitializer private static final class ByteCache { private ByteCache() {} diff --git a/src/java.base/share/classes/java/lang/Character.java b/src/java.base/share/classes/java/lang/Character.java index b71849eaee7..ffda729a45a 100644 --- a/src/java.base/share/classes/java/lang/Character.java +++ b/src/java.base/share/classes/java/lang/Character.java @@ -26,6 +26,7 @@ package java.lang; import jdk.internal.misc.CDS; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; import jdk.internal.vm.annotation.IntrinsicCandidate; import jdk.internal.vm.annotation.Stable; @@ -9379,6 +9380,7 @@ class Character implements java.io.Serializable, Comparable, Constabl this.value = value; } + @AOTSafeClassInitializer private static final class CharacterCache { private CharacterCache(){} diff --git a/src/java.base/share/classes/java/lang/Integer.java b/src/java.base/share/classes/java/lang/Integer.java index 2742ec40abf..a9da1c32490 100644 --- a/src/java.base/share/classes/java/lang/Integer.java +++ b/src/java.base/share/classes/java/lang/Integer.java @@ -28,6 +28,8 @@ package java.lang; import jdk.internal.misc.CDS; import jdk.internal.misc.VM; import jdk.internal.util.DecimalDigits; +import jdk.internal.vm.annotation.AOTRuntimeSetup; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.IntrinsicCandidate; import jdk.internal.vm.annotation.Stable; @@ -891,15 +893,20 @@ public final class Integer extends Number * with new Integer object(s) after initialization. */ + @AOTSafeClassInitializer private static final class IntegerCache { static final int low = -128; - static final int high; + @Stable static int high; - @Stable - static final Integer[] cache; + @Stable static Integer[] cache; static Integer[] archivedCache; static { + runtimeSetup(); + } + + @AOTRuntimeSetup + private static void runtimeSetup() { // high value may be configured by property int h = 127; String integerCacheHighPropValue = @@ -915,34 +922,50 @@ public final class Integer extends Number } high = h; - // Load IntegerCache.archivedCache from archive, if possible - CDS.initializeFromArchive(IntegerCache.class); - int size = (high - low) + 1; - - // Use the archived cache if it exists and is large enough - if (archivedCache == null || size > archivedCache.length) { - Integer[] c = new Integer[size]; - int j = low; - // If archive has Integer cache, we must use all instances from it. - // Otherwise, the identity checks between archived Integers and - // runtime-cached Integers would fail. - int archivedSize = (archivedCache == null) ? 0 : archivedCache.length; - for (int i = 0; i < archivedSize; i++) { - c[i] = archivedCache[i]; - assert j == archivedCache[i]; - j++; - } - // Fill the rest of the cache. - for (int i = archivedSize; i < size; i++) { - c[i] = new Integer(j++); - } - archivedCache = c; + Integer[] precomputed = null; + if (cache != null) { + // IntegerCache has been AOT-initialized. + precomputed = cache; + } else { + // Legacy CDS archive support (to be deprecated): + // Load IntegerCache.archivedCache from archive, if possible + CDS.initializeFromArchive(IntegerCache.class); + precomputed = archivedCache; } - cache = archivedCache; + + cache = loadOrInitializeCache(precomputed); + archivedCache = cache; // Legacy CDS archive support (to be deprecated) // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } + private static Integer[] loadOrInitializeCache(Integer[] precomputed) { + int size = (high - low) + 1; + + // Use the precomputed cache if it exists and is large enough + if (precomputed != null && size <= precomputed.length) { + return precomputed; + } + + Integer[] c = new Integer[size]; + int j = low; + // If we loading a precomputed cache (from AOT cache or CDS archive), + // we must use all instances from it. + // Otherwise, the Integers from the AOT cache (or CDS archive) will not + // have the same object identity as items in IntegerCache.cache[]. + int precomputedSize = (precomputed == null) ? 0 : precomputed.length; + for (int i = 0; i < precomputedSize; i++) { + c[i] = precomputed[i]; + assert j == precomputed[i]; + j++; + } + // Fill the rest of the cache. + for (int i = precomputedSize; i < size; i++) { + c[i] = new Integer(j++); + } + return c; + } + private IntegerCache() {} } diff --git a/src/java.base/share/classes/java/lang/Long.java b/src/java.base/share/classes/java/lang/Long.java index 3077e7c0a38..c5cd9650f2d 100644 --- a/src/java.base/share/classes/java/lang/Long.java +++ b/src/java.base/share/classes/java/lang/Long.java @@ -35,6 +35,7 @@ import java.util.Optional; import jdk.internal.misc.CDS; import jdk.internal.util.DecimalDigits; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.IntrinsicCandidate; import jdk.internal.vm.annotation.Stable; @@ -911,6 +912,7 @@ public final class Long extends Number return Long.valueOf(parseLong(s, 10)); } + @AOTSafeClassInitializer private static final class LongCache { private LongCache() {} diff --git a/src/java.base/share/classes/java/lang/Module.java b/src/java.base/share/classes/java/lang/Module.java index cd2b8095ee4..bd04345554b 100644 --- a/src/java.base/share/classes/java/lang/Module.java +++ b/src/java.base/share/classes/java/lang/Module.java @@ -69,6 +69,7 @@ import jdk.internal.module.ServicesCatalog; import jdk.internal.module.Resources; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; import jdk.internal.vm.annotation.Stable; /** @@ -391,6 +392,7 @@ public final class Module implements AnnotatedElement { private static final Module EVERYONE_MODULE; private static final Set EVERYONE_SET; + @AOTSafeClassInitializer private static class ArchivedData { private static ArchivedData archivedData; private final Module allUnnamedModule; diff --git a/src/java.base/share/classes/java/lang/ModuleLayer.java b/src/java.base/share/classes/java/lang/ModuleLayer.java index 9d922f787a6..a073de6b14a 100644 --- a/src/java.base/share/classes/java/lang/ModuleLayer.java +++ b/src/java.base/share/classes/java/lang/ModuleLayer.java @@ -53,6 +53,7 @@ import jdk.internal.module.ServicesCatalog; import jdk.internal.misc.CDS; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; import jdk.internal.vm.annotation.Stable; /** @@ -145,6 +146,7 @@ import jdk.internal.vm.annotation.Stable; * @see Module#getLayer() */ +@AOTSafeClassInitializer public final class ModuleLayer { // the empty layer (may be initialized from the CDS archive) diff --git a/src/java.base/share/classes/java/lang/Short.java b/src/java.base/share/classes/java/lang/Short.java index 4c64427b6df..920500a7fa3 100644 --- a/src/java.base/share/classes/java/lang/Short.java +++ b/src/java.base/share/classes/java/lang/Short.java @@ -26,6 +26,7 @@ package java.lang; import jdk.internal.misc.CDS; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; import jdk.internal.vm.annotation.IntrinsicCandidate; import jdk.internal.vm.annotation.Stable; @@ -230,6 +231,7 @@ public final class Short extends Number implements Comparable, Constable return Optional.of(DynamicConstantDesc.ofNamed(BSM_EXPLICIT_CAST, DEFAULT_NAME, CD_short, intValue())); } + @AOTSafeClassInitializer private static final class ShortCache { private ShortCache() {} diff --git a/src/java.base/share/classes/java/lang/module/Configuration.java b/src/java.base/share/classes/java/lang/module/Configuration.java index a76a32cfb28..40eeddc3f0b 100644 --- a/src/java.base/share/classes/java/lang/module/Configuration.java +++ b/src/java.base/share/classes/java/lang/module/Configuration.java @@ -44,6 +44,7 @@ import java.util.stream.Stream; import jdk.internal.misc.CDS; import jdk.internal.module.ModuleReferenceImpl; import jdk.internal.module.ModuleTarget; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; import jdk.internal.vm.annotation.Stable; /** @@ -155,6 +156,7 @@ import jdk.internal.vm.annotation.Stable; * @since 9 * @see java.lang.ModuleLayer */ +@AOTSafeClassInitializer public final class Configuration { // @see Configuration#empty() diff --git a/src/java.base/share/classes/java/util/ImmutableCollections.java b/src/java.base/share/classes/java/util/ImmutableCollections.java index abc48ff5ed9..e7fe22490da 100644 --- a/src/java.base/share/classes/java/util/ImmutableCollections.java +++ b/src/java.base/share/classes/java/util/ImmutableCollections.java @@ -42,6 +42,9 @@ import java.util.function.UnaryOperator; import jdk.internal.access.JavaUtilCollectionAccess; import jdk.internal.access.SharedSecrets; import jdk.internal.misc.CDS; +import jdk.internal.vm.annotation.AOTRuntimeSetup; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; +import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.Stable; /** @@ -52,6 +55,7 @@ import jdk.internal.vm.annotation.Stable; * classes use a serial proxy and thus have no need to declare serialVersionUID. */ @SuppressWarnings("serial") +@AOTSafeClassInitializer class ImmutableCollections { /** * A "salt" value used for randomizing iteration order. This is initialized once @@ -59,14 +63,20 @@ class ImmutableCollections { * it needs to vary sufficiently from one run to the next so that iteration order * will vary between JVM runs. */ - private static final long SALT32L; + @Stable private static long SALT32L; /** * For set and map iteration, we will iterate in "reverse" stochastically, * decided at bootstrap time. */ - private static final boolean REVERSE; + @Stable private static boolean REVERSE; + static { + runtimeSetup(); + } + + @AOTRuntimeSetup + private static void runtimeSetup() { // to generate a reasonably random and well-mixed SALT, use an arbitrary // value (a slice of pi), multiply with a random seed, then pick // the mid 32-bits from the product. By picking a SALT value in the @@ -102,6 +112,7 @@ class ImmutableCollections { static final MapN EMPTY_MAP; static { + // Legacy CDS archive support (to be deprecated) CDS.initializeFromArchive(ImmutableCollections.class); if (archivedObjects == null) { EMPTY = new Object(); diff --git a/src/java.base/share/classes/java/util/jar/Attributes.java b/src/java.base/share/classes/java/util/jar/Attributes.java index 9322bb9acac..20ff81676c9 100644 --- a/src/java.base/share/classes/java/util/jar/Attributes.java +++ b/src/java.base/share/classes/java/util/jar/Attributes.java @@ -36,6 +36,7 @@ import java.util.Objects; import java.util.Set; import jdk.internal.misc.CDS; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; import jdk.internal.vm.annotation.Stable; import sun.nio.cs.UTF_8; @@ -60,6 +61,7 @@ import sun.util.logging.PlatformLogger; * @see Manifest * @since 1.2 */ +@AOTSafeClassInitializer public class Attributes implements Map, Cloneable { /** * The attribute name-value mappings. @@ -450,6 +452,7 @@ public class Attributes implements Map, Cloneable { * * @spec jar/jar.html JAR File Specification */ + @AOTSafeClassInitializer public static class Name { private final String name; private final int hashCode; @@ -669,6 +672,7 @@ public class Attributes implements Map, Cloneable { static { + // Legacy CDS archive support (to be deprecated) CDS.initializeFromArchive(Attributes.Name.class); if (KNOWN_NAMES == null) { diff --git a/src/java.base/share/classes/jdk/internal/loader/ArchivedClassLoaders.java b/src/java.base/share/classes/jdk/internal/loader/ArchivedClassLoaders.java index be3425590fc..439772a8789 100644 --- a/src/java.base/share/classes/jdk/internal/loader/ArchivedClassLoaders.java +++ b/src/java.base/share/classes/jdk/internal/loader/ArchivedClassLoaders.java @@ -27,11 +27,13 @@ package jdk.internal.loader; import java.util.Map; import jdk.internal.misc.CDS; import jdk.internal.module.ServicesCatalog; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; /** * Used to archive the built-in class loaders, their services catalogs, and the * package-to-module map used by the built-in class loaders. */ +@AOTSafeClassInitializer class ArchivedClassLoaders { private static ArchivedClassLoaders archivedClassLoaders; diff --git a/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java b/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java index 1ef9dee3a8a..5413226c112 100644 --- a/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java +++ b/src/java.base/share/classes/jdk/internal/math/FDBigInteger.java @@ -26,6 +26,7 @@ package jdk.internal.math; import jdk.internal.misc.CDS; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; import jdk.internal.vm.annotation.Stable; import java.util.Arrays; @@ -33,6 +34,7 @@ import java.util.Arrays; /** * A simple big integer class specifically for floating point base conversion. */ +@AOTSafeClassInitializer final class FDBigInteger { @Stable @@ -53,6 +55,7 @@ final class FDBigInteger { // Initialize FDBigInteger cache of powers of 5. static { + // Legacy CDS archive support (to be deprecated) CDS.initializeFromArchive(FDBigInteger.class); Object[] caches = archivedCaches; if (caches == null) { diff --git a/src/java.base/share/classes/jdk/internal/module/ArchivedBootLayer.java b/src/java.base/share/classes/jdk/internal/module/ArchivedBootLayer.java index 5c806f81dcd..425238dd521 100644 --- a/src/java.base/share/classes/jdk/internal/module/ArchivedBootLayer.java +++ b/src/java.base/share/classes/jdk/internal/module/ArchivedBootLayer.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 @@ -25,10 +25,12 @@ package jdk.internal.module; import jdk.internal.misc.CDS; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; /** * Used by ModuleBootstrap for archiving the boot layer. */ +@AOTSafeClassInitializer class ArchivedBootLayer { private static ArchivedBootLayer archivedBootLayer; diff --git a/src/java.base/share/classes/jdk/internal/module/ArchivedModuleGraph.java b/src/java.base/share/classes/jdk/internal/module/ArchivedModuleGraph.java index 4f9223d0171..deb280c878d 100644 --- a/src/java.base/share/classes/jdk/internal/module/ArchivedModuleGraph.java +++ b/src/java.base/share/classes/jdk/internal/module/ArchivedModuleGraph.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 @@ -30,11 +30,13 @@ import java.util.function.Function; import java.lang.module.Configuration; import java.lang.module.ModuleFinder; import jdk.internal.misc.CDS; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; /** * Used by ModuleBootstrap for archiving the configuration for the boot layer, * and the system module finder. */ +@AOTSafeClassInitializer class ArchivedModuleGraph { private static ArchivedModuleGraph archivedModuleGraph; @@ -126,6 +128,7 @@ class ArchivedModuleGraph { } static { + // Legacy CDS archive support (to be deprecated) CDS.initializeFromArchive(ArchivedModuleGraph.class); } } diff --git a/src/java.base/share/classes/sun/util/locale/BaseLocale.java b/src/java.base/share/classes/sun/util/locale/BaseLocale.java index 58ec6d76aa5..31078720ddc 100644 --- a/src/java.base/share/classes/sun/util/locale/BaseLocale.java +++ b/src/java.base/share/classes/sun/util/locale/BaseLocale.java @@ -34,11 +34,14 @@ package sun.util.locale; import jdk.internal.misc.CDS; import jdk.internal.util.ReferencedKeySet; +import jdk.internal.vm.annotation.AOTRuntimeSetup; +import jdk.internal.vm.annotation.AOTSafeClassInitializer; import jdk.internal.vm.annotation.Stable; import java.util.StringJoiner; import java.util.function.Supplier; +@AOTSafeClassInitializer public final class BaseLocale { public static @Stable BaseLocale[] constantBaseLocales; @@ -63,6 +66,7 @@ public final class BaseLocale { CANADA_FRENCH = 18, NUM_CONSTANTS = 19; static { + // Legacy CDS archive support (to be deprecated) CDS.initializeFromArchive(BaseLocale.class); BaseLocale[] baseLocales = constantBaseLocales; if (baseLocales == null) { @@ -91,13 +95,21 @@ public final class BaseLocale { } // Interned BaseLocale cache - private static final LazyConstant> CACHE = + @Stable private static LazyConstant> CACHE; + static { + runtimeSetup(); + } + + @AOTRuntimeSetup + private static void runtimeSetup() { + CACHE = LazyConstant.of(new Supplier<>() { @Override public ReferencedKeySet get() { return ReferencedKeySet.create(true, ReferencedKeySet.concurrentHashMapSupplier()); } }); + } public static final String SEP = "_"; diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index d4f1470aea5..2288e8f8876 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -522,6 +522,7 @@ hotspot_aot_classlinking = \ -runtime/cds/appcds/aotFlags \ -runtime/cds/appcds/aotProfile \ -runtime/cds/appcds/BadBSM.java \ + -runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java \ -runtime/cds/appcds/cacheObject/ArchivedIntegerCacheTest.java \ -runtime/cds/appcds/cacheObject/ArchivedModuleCompareTest.java \ -runtime/cds/appcds/CDSandJFR.java \ diff --git a/test/hotspot/jtreg/runtime/cds/SharedSymbolTableBucketSize.java b/test/hotspot/jtreg/runtime/cds/SharedSymbolTableBucketSize.java index 2db4ab2df23..070384a2703 100644 --- a/test/hotspot/jtreg/runtime/cds/SharedSymbolTableBucketSize.java +++ b/test/hotspot/jtreg/runtime/cds/SharedSymbolTableBucketSize.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -31,6 +31,8 @@ * java.management */ +import java.util.regex.Matcher; +import java.util.regex.Pattern; import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.process.OutputAnalyzer; @@ -43,8 +45,44 @@ public class SharedSymbolTableBucketSize { + Integer.valueOf(bucket_size)); CDSTestUtils.checkMappingFailure(output); - String regex = "Average bucket size : ([0-9]+\\.[0-9]+).*"; - String s = output.firstMatch(regex, 1); + /* [1] There may be other table stats that precede the symbol tabble. + Skip all thse until we find this: + + [0.677s][info][aot,hashtables] Shared symbol table stats -------- base: 0x0000000800000000 + [0.677s][info][aot,hashtables] Number of entries : 46244 + [0.677s][info][aot,hashtables] Total bytes used : 393792 + [0.677s][info][aot,hashtables] Average bytes per entry : 8.516 + [0.677s][info][aot,hashtables] Average bucket size : 7.734 + [0.677s][info][aot,hashtables] Variance of bucket size : 7.513 + [0.677s][info][aot,hashtables] Std. dev. of bucket size: 2.741 + [0.677s][info][aot,hashtables] Maximum bucket size : 20 + [0.677s][info][aot,hashtables] Empty buckets : 2 + [0.677s][info][aot,hashtables] Value_Only buckets : 24 + [0.677s][info][aot,hashtables] Other buckets : 5953 + .... + */ + Pattern pattern0 = Pattern.compile("Shared symbol table stats.*", Pattern.DOTALL); + Matcher matcher0 = pattern0.matcher(output.getStdout()); + String stat = null; + if (matcher0.find()) { + stat = matcher0.group(0); + } + if (stat == null) { + throw new Exception("FAILED: pattern \"" + pattern0 + "\" not found"); + } + + /* (2) The first "Average bucket size" line in the remaining output is for the + shared symbol table */ + Pattern pattern = Pattern.compile("Average bucket size *: *([0-9]+\\.[0-9]+).*", Pattern.MULTILINE); + Matcher matcher = pattern.matcher(stat); + String s = null; + if (matcher.find()) { + s = matcher.group(1); + } + if (s == null) { + throw new Exception("FAILED: pattern \"" + pattern + "\" not found"); + } + Float f = Float.parseFloat(s); int size = Math.round(f); if (size != bucket_size) { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java index 896df7ca496..4cc6ef81c45 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTLoggingTag.java @@ -83,17 +83,6 @@ public class AOTLoggingTag { out.shouldContain("[aot] Opened AOT cache hello.aot"); out.shouldHaveExitValue(0); - //---------------------------------------------------------------------- - printTestCase("All old -Xlog:cds+heap logs have been changed to -Xlog:aot+heap should alias to -Xlog:cds+heap"); - pb = ProcessTools.createLimitedTestJavaProcessBuilder( - "-XX:AOTCache=" + aotCacheFile, - "-Xlog:aot+heap", - "-cp", appJar, helloClass); - out = CDSTestUtils.executeAndLog(pb, "prod"); - out.shouldNotContain("No tag set matches selection: aot+heap"); - out.shouldContain("[aot,heap] resolve subgraph java.lang.Integer$IntegerCache"); - out.shouldHaveExitValue(0); - //---------------------------------------------------------------------- printTestCase("Production Run: errors should be printed with [aot] decoration"); pb = ProcessTools.createLimitedTestJavaProcessBuilder( diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/HeapObjectIdentity.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/HeapObjectIdentity.java new file mode 100644 index 00000000000..cdd0921627a --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/HeapObjectIdentity.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @test AOT cache should preserve heap object identity when required by JLS. For example, Enums and Integers. + * @requires vm.cds + * @requires vm.cds.supports.aot.class.linking + * @requires vm.debug + * @library /test/lib + * @build HeapObjectIdentity + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar dummy.jar + * Dummy + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar boot.jar + * HeapObjectIdentityApp + * MyAOTInitedClass + * MyAOTInitedClass$MyEnum + * MyAOTInitedClass$Wrapper + * @run driver HeapObjectIdentity AOT --two-step-training + */ + +import jdk.test.lib.cds.CDSAppTester; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.helpers.ClassFileInstaller; + +public class HeapObjectIdentity { + static final String appJar = ClassFileInstaller.getJarPath("dummy.jar"); + static final String bootJar = ClassFileInstaller.getJarPath("boot.jar"); + static final String mainClass = "HeapObjectIdentityApp"; // Loaded from boot.jar + + public static void main(String[] args) throws Exception { + Tester t = new Tester(); + t.run(args); + + // Integer$IntegerCache should preserve the object identity of cached Integer objects, + // even when the cache size is different between assembly and production. + t.productionRun(new String[] { + "-XX:AutoBoxCacheMax=2048" + }); + } + + static class Tester extends CDSAppTester { + public Tester() { + super(mainClass); + } + + @Override + public String classpath(RunMode runMode) { + return appJar; + } + + @Override + public String[] vmArgs(RunMode runMode) { + String bootcp = "-Xbootclasspath/a:" + bootJar; + if (runMode == RunMode.ASSEMBLY) { + return new String[] { + "-Xlog:aot+class=debug", + "-XX:AOTInitTestClass=MyAOTInitedClass", + bootcp + }; + } else { + return new String[] {bootcp}; + } + } + + @Override + public String[] appCommandLine(RunMode runMode) { + return new String[] { + mainClass, + runMode.toString(), + }; + } + + @Override + public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception { + if (runMode == RunMode.ASSEMBLY) { + out.shouldContain("MyAOTInitedClass aot-linked inited"); + } + } + } +} + +class HeapObjectIdentityApp { + public static void main(String... args) { + MyAOTInitedClass.test(); + } +} + +// This class is loaded by the boot loader, as -XX:AOTInitTestClass is not too friendly +// with classes by other loaders. +class MyAOTInitedClass { + static Object[] archivedObjects; + static { + if (archivedObjects == null) { + archivedObjects = new Object[14]; + archivedObjects[0] = Wrapper.BOOLEAN; + archivedObjects[1] = Wrapper.INT.zero(); + archivedObjects[2] = Wrapper.DOUBLE.zero(); + archivedObjects[3] = MyEnum.DUMMY1; + + archivedObjects[4] = Boolean.class; + archivedObjects[5] = Byte.class; + archivedObjects[6] = Character.class; + archivedObjects[7] = Short.class; + archivedObjects[8] = Integer.class; + archivedObjects[9] = Long.class; + archivedObjects[10] = Float.class; + archivedObjects[11] = Double.class; + archivedObjects[12] = Void.class; + + archivedObjects[13] = Integer.valueOf(1); + } else { + System.out.println("Initialized from CDS"); + } + } + + public static void test() { + if (archivedObjects[0] != Wrapper.BOOLEAN) { + throw new RuntimeException("Huh 0"); + } + + if (archivedObjects[1] != Wrapper.INT.zero()) { + throw new RuntimeException("Huh 1"); + } + + if (archivedObjects[2] != Wrapper.DOUBLE.zero()) { + throw new RuntimeException("Huh 2"); + } + + if (archivedObjects[3] != MyEnum.DUMMY1) { + throw new RuntimeException("Huh 3"); + } + + if (MyEnum.BOOLEAN != true) { + throw new RuntimeException("Huh 10.1"); + } + if (MyEnum.BYTE != -128) { + throw new RuntimeException("Huh 10.2"); + } + if (MyEnum.CHAR != 'c') { + throw new RuntimeException("Huh 10.3"); + } + if (MyEnum.SHORT != -12345) { + throw new RuntimeException("Huh 10.4"); + } + if (MyEnum.INT != -123456) { + throw new RuntimeException("Huh 10.5"); + } + if (MyEnum.LONG != 0x1234567890L) { + throw new RuntimeException("Huh 10.6"); + } + if (MyEnum.LONG2 != -0x1234567890L) { + throw new RuntimeException("Huh 10.7"); + } + if (MyEnum.FLOAT != 567891.0f) { + throw new RuntimeException("Huh 10.8"); + } + if (MyEnum.DOUBLE != 12345678905678.890) { + throw new RuntimeException("Huh 10.9"); + } + + checkClass(4, Boolean.class); + checkClass(5, Byte.class); + checkClass(6, Character.class); + checkClass(7, Short.class); + checkClass(8, Integer.class); + checkClass(9, Long.class); + checkClass(10, Float.class); + checkClass(11, Double.class); + checkClass(12, Void.class); + + if (archivedObjects[13] != Integer.valueOf(1)) { + throw new RuntimeException("Integer cache identity test failed"); + } + + System.out.println("Success!"); + } + + static void checkClass(int index, Class c) { + if (archivedObjects[index] != c) { + throw new RuntimeException("archivedObjects[" + index + "] should be " + c); + } + } + + // Simplified version of sun.invoke.util.Wrapper + public enum Wrapper { + // wrapperType simple primitiveType simple char emptyArray + BOOLEAN( Boolean.class, "Boolean", boolean.class, "boolean", 'Z', new boolean[0]), + INT ( Integer.class, "Integer", int.class, "int", 'I', new int[0]), + DOUBLE ( Double.class, "Double", double.class, "double", 'D', new double[0]) + ; + + public static final int COUNT = 10; + private static final Object DOUBLE_ZERO = (Double)(double)0; + + private final Class wrapperType; + private final Class primitiveType; + private final char basicTypeChar; + private final String basicTypeString; + private final Object emptyArray; + + Wrapper(Class wtype, + String wtypeName, + Class ptype, + String ptypeName, + char tchar, + Object emptyArray) { + this.wrapperType = wtype; + this.primitiveType = ptype; + this.basicTypeChar = tchar; + this.basicTypeString = String.valueOf(this.basicTypeChar); + this.emptyArray = emptyArray; + } + + public Object zero() { + return switch (this) { + case BOOLEAN -> Boolean.FALSE; + case INT -> (Integer)0; + case DOUBLE -> DOUBLE_ZERO; + default -> null; + }; + } + } + + enum MyEnum { + DUMMY1, + DUMMY2; + + static final boolean BOOLEAN = true; + static final byte BYTE = -128; + static final short SHORT = -12345; + static final char CHAR = 'c'; + static final int INT = -123456; + static final long LONG = 0x1234567890L; + static final long LONG2 = -0x1234567890L; + static final float FLOAT = 567891.0f; + static final double DOUBLE = 12345678905678.890; + } +} + +class Dummy {} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java index fed56937f2f..3b1ccff1bfa 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java @@ -36,7 +36,7 @@ * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar boot.jar * CDSTestClassA CDSTestClassA$XX CDSTestClassA$YY * CDSTestClassB CDSTestClassC CDSTestClassD - * CDSTestClassE CDSTestClassF CDSTestClassG CDSTestClassG$MyEnum CDSTestClassG$Wrapper + * CDSTestClassE CDSTestClassF * pkg.ClassInPackage * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar Hello * @run driver ArchiveHeapTestClass @@ -58,7 +58,6 @@ public class ArchiveHeapTestClass { static final String CDSTestClassD_name = CDSTestClassD.class.getName(); static final String CDSTestClassE_name = CDSTestClassE.class.getName(); static final String CDSTestClassF_name = CDSTestClassF.class.getName(); - static final String CDSTestClassG_name = CDSTestClassG.class.getName(); static final String ClassInPackage_name = pkg.ClassInPackage.class.getName().replace('.', '/'); static final String ARCHIVE_TEST_FIELD_NAME = "archivedObjects"; @@ -162,15 +161,6 @@ public class ArchiveHeapTestClass { output = dumpBootAndHello(CDSTestClassF_name); mustFail(output, "Class java.util.logging.Level not allowed in archive heap"); } - - testCase("Complex enums"); - output = dumpBootAndHello(CDSTestClassG_name, "-XX:+AOTClassLinking", "-Xlog:cds+class=debug"); - mustSucceed(output); - - TestCommon.run("-Xbootclasspath/a:" + bootJar, "-cp", appJar, "-Xlog:aot+heap,cds+init", - CDSTestClassG_name) - .assertNormalExit("init subgraph " + CDSTestClassG_name, - "Initialized from CDS"); } } @@ -287,147 +277,3 @@ class CDSTestClassF { archivedObjects[0] = java.util.logging.Level.OFF; } } - -class CDSTestClassG { - static Object[] archivedObjects; - static { - if (archivedObjects == null) { - archivedObjects = new Object[13]; - archivedObjects[0] = Wrapper.BOOLEAN; - archivedObjects[1] = Wrapper.INT.zero(); - archivedObjects[2] = Wrapper.DOUBLE.zero(); - archivedObjects[3] = MyEnum.DUMMY1; - - archivedObjects[4] = Boolean.class; - archivedObjects[5] = Byte.class; - archivedObjects[6] = Character.class; - archivedObjects[7] = Short.class; - archivedObjects[8] = Integer.class; - archivedObjects[9] = Long.class; - archivedObjects[10] = Float.class; - archivedObjects[11] = Double.class; - archivedObjects[12] = Void.class; - } else { - System.out.println("Initialized from CDS"); - } - } - - public static void main(String args[]) { - if (archivedObjects[0] != Wrapper.BOOLEAN) { - throw new RuntimeException("Huh 0"); - } - - if (archivedObjects[1] != Wrapper.INT.zero()) { - throw new RuntimeException("Huh 1"); - } - - if (archivedObjects[2] != Wrapper.DOUBLE.zero()) { - throw new RuntimeException("Huh 2"); - } - - if (archivedObjects[3] != MyEnum.DUMMY1) { - throw new RuntimeException("Huh 3"); - } - - if (MyEnum.BOOLEAN != true) { - throw new RuntimeException("Huh 10.1"); - } - if (MyEnum.BYTE != -128) { - throw new RuntimeException("Huh 10.2"); - } - if (MyEnum.CHAR != 'c') { - throw new RuntimeException("Huh 10.3"); - } - if (MyEnum.SHORT != -12345) { - throw new RuntimeException("Huh 10.4"); - } - if (MyEnum.INT != -123456) { - throw new RuntimeException("Huh 10.5"); - } - if (MyEnum.LONG != 0x1234567890L) { - throw new RuntimeException("Huh 10.6"); - } - if (MyEnum.LONG2 != -0x1234567890L) { - throw new RuntimeException("Huh 10.7"); - } - if (MyEnum.FLOAT != 567891.0f) { - throw new RuntimeException("Huh 10.8"); - } - if (MyEnum.DOUBLE != 12345678905678.890) { - throw new RuntimeException("Huh 10.9"); - } - - checkClass(4, Boolean.class); - checkClass(5, Byte.class); - checkClass(6, Character.class); - checkClass(7, Short.class); - checkClass(8, Integer.class); - checkClass(9, Long.class); - checkClass(10, Float.class); - checkClass(11, Double.class); - checkClass(12, Void.class); - - System.out.println("Success!"); - } - - static void checkClass(int index, Class c) { - if (archivedObjects[index] != c) { - throw new RuntimeException("archivedObjects[" + index + "] should be " + c); - } - } - - // Simplified version of sun.invoke.util.Wrapper - public enum Wrapper { - // wrapperType simple primitiveType simple char emptyArray - BOOLEAN( Boolean.class, "Boolean", boolean.class, "boolean", 'Z', new boolean[0]), - INT ( Integer.class, "Integer", int.class, "int", 'I', new int[0]), - DOUBLE ( Double.class, "Double", double.class, "double", 'D', new double[0]) - ; - - public static final int COUNT = 10; - private static final Object DOUBLE_ZERO = (Double)(double)0; - - private final Class wrapperType; - private final Class primitiveType; - private final char basicTypeChar; - private final String basicTypeString; - private final Object emptyArray; - - Wrapper(Class wtype, - String wtypeName, - Class ptype, - String ptypeName, - char tchar, - Object emptyArray) { - this.wrapperType = wtype; - this.primitiveType = ptype; - this.basicTypeChar = tchar; - this.basicTypeString = String.valueOf(this.basicTypeChar); - this.emptyArray = emptyArray; - } - - public Object zero() { - return switch (this) { - case BOOLEAN -> Boolean.FALSE; - case INT -> (Integer)0; - case DOUBLE -> DOUBLE_ZERO; - default -> null; - }; - } - } - - enum MyEnum { - DUMMY1, - DUMMY2; - - static final boolean BOOLEAN = true; - static final byte BYTE = -128; - static final short SHORT = -12345; - static final char CHAR = 'c'; - static final int INT = -123456; - static final long LONG = 0x1234567890L; - static final long LONG2 = -0x1234567890L; - static final float FLOAT = 567891.0f; - static final double DOUBLE = 12345678905678.890; - } -} From 17d633a8ee7538625501a90469cb6a68b9ba4820 Mon Sep 17 00:00:00 2001 From: Kelvin Nilsen Date: Wed, 17 Dec 2025 22:21:24 +0000 Subject: [PATCH 050/390] 8373720: GenShen: Count live-at-old mark using Snapshot at Beginning Reviewed-by: ysr --- .../heuristics/shenandoahOldHeuristics.cpp | 9 +++++++-- .../shenandoahGenerationalEvacuationTask.cpp | 3 ++- .../share/gc/shenandoah/shenandoahHeapRegion.hpp | 16 ++++++++++++++++ .../shenandoah/shenandoahHeapRegion.inline.hpp | 1 + 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp index 1f257560bcb..8bf068df0a8 100644 --- a/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp +++ b/src/hotspot/share/gc/shenandoah/heuristics/shenandoahOldHeuristics.cpp @@ -335,7 +335,13 @@ void ShenandoahOldHeuristics::prepare_for_old_collections() { size_t garbage = region->garbage(); size_t live_bytes = region->get_live_data_bytes(); - live_data += live_bytes; + if (!region->was_promoted_in_place()) { + // As currently implemented, region->get_live_data_bytes() represents bytes concurrently marked. + // Expansion of the region by promotion during concurrent marking is above TAMS, and is not included + // as live-data at [start of] old marking. + live_data += live_bytes; + } + // else, regions that were promoted in place had 0 old live data at mark start if (region->is_regular() || region->is_regular_pinned()) { // Only place regular or pinned regions with live data into the candidate set. @@ -374,7 +380,6 @@ void ShenandoahOldHeuristics::prepare_for_old_collections() { } } - // TODO: subtract from live_data bytes promoted during concurrent GC. _old_generation->set_live_bytes_at_last_mark(live_data); // Unlike young, we are more interested in efficiently packing OLD-gen than in reclaiming garbage first. We sort by live-data. diff --git a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp index de45877994c..c9b956f9c2f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahGenerationalEvacuationTask.cpp @@ -223,7 +223,6 @@ void ShenandoahGenerationalEvacuationTask::promote_in_place(ShenandoahHeapRegion // We do not need to scan above TAMS because restored top equals tams assert(obj_addr == tams, "Expect loop to terminate when obj_addr equals tams"); - { ShenandoahHeapLocker locker(_heap->lock()); @@ -251,6 +250,7 @@ void ShenandoahGenerationalEvacuationTask::promote_in_place(ShenandoahHeapRegion // Transfer this region from young to old, increasing promoted_reserve if available space exceeds plab_min_size() _heap->free_set()->add_promoted_in_place_region_to_old_collector(region); region->set_affiliation(OLD_GENERATION); + region->set_promoted_in_place(); } } @@ -289,6 +289,7 @@ void ShenandoahGenerationalEvacuationTask::promote_humongous(ShenandoahHeapRegio r->index(), p2i(r->bottom()), p2i(r->top())); // We mark the entire humongous object's range as dirty after loop terminates, so no need to dirty the range here r->set_affiliation(OLD_GENERATION); + r->set_promoted_in_place(); } ShenandoahFreeSet* freeset = _heap->free_set(); diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp index 2ed5614c698..cf0dc5476d0 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.hpp @@ -262,6 +262,7 @@ private: HeapWord* volatile _update_watermark; uint _age; + bool _promoted_in_place; CENSUS_NOISE(uint _youth;) // tracks epochs of retrograde ageing (rejuvenation) ShenandoahSharedFlag _recycling; // Used to indicate that the region is being recycled; see try_recycle*(). @@ -354,6 +355,15 @@ public: inline void save_top_before_promote(); inline HeapWord* get_top_before_promote() const { return _top_before_promoted; } + + inline void set_promoted_in_place() { + _promoted_in_place = true; + } + + // Returns true iff this region was promoted in place subsequent to the most recent start of concurrent old marking. + inline bool was_promoted_in_place() { + return _promoted_in_place; + } inline void restore_top_before_promote(); inline size_t garbage_before_padded_for_promote() const; @@ -379,7 +389,13 @@ public: inline void increase_live_data_gc_words(size_t s); inline bool has_live() const; + + // Represents the number of live bytes identified by most recent marking effort. Does not include the bytes + // above TAMS. inline size_t get_live_data_bytes() const; + + // Represents the number of live words identified by most recent marking effort. Does not include the words + // above TAMS. inline size_t get_live_data_words() const; inline size_t garbage() const; diff --git a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp index 69673eb7a60..b9304ee9daa 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahHeapRegion.inline.hpp @@ -152,6 +152,7 @@ inline void ShenandoahHeapRegion::internal_increase_live_data(size_t s) { inline void ShenandoahHeapRegion::clear_live_data() { AtomicAccess::store(&_live_data, (size_t)0); + _promoted_in_place = false; } inline size_t ShenandoahHeapRegion::get_live_data_words() const { From c16ce929c7bc127fe18d3faa037d81c2760a44a2 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Wed, 17 Dec 2025 22:38:50 +0000 Subject: [PATCH 051/390] 8370970: DocCheck failure in jdkDoctypeBadcharsCheck.java and jdkCheckHtml.java Reviewed-by: liach --- test/docs/ProblemList.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/docs/ProblemList.txt b/test/docs/ProblemList.txt index 4df8bbcc53c..83693eacbd1 100644 --- a/test/docs/ProblemList.txt +++ b/test/docs/ProblemList.txt @@ -41,5 +41,3 @@ ############################################################################# jdk/javadoc/doccheck/checks/jdkCheckLinks.java 8370249 generic-all -jdk/javadoc/doccheck/checks/jdkCheckHtml.java 8370970 generic-all -jdk/javadoc/doccheck/checks/jdkDoctypeBadcharsCheck.java 8370970 generic-all From ea5834415db6410c73271c496811ff6b5dcc87ef Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Thu, 18 Dec 2025 01:46:45 +0000 Subject: [PATCH 052/390] 8373887: jpackage tests may potentially deadlock Reviewed-by: almatvee --- .../jdk/jpackage/test/ExecutorTest.java | 8 +++- .../helpers/jdk/jpackage/test/Executor.java | 38 +++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/ExecutorTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/ExecutorTest.java index c5d8aed845c..2b075e0f13c 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/ExecutorTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/ExecutorTest.java @@ -210,7 +210,13 @@ public class ExecutorTest extends JUnitAdapter { assertEquals(0, result[0].getExitCode()); - assertEquals(expectedCapturedSystemOut(commandWithDiscardedStreams), outputCapture.outLines()); + // If we dump the subprocesses's output, and the command produced both STDOUT and STDERR, + // then the captured STDOUT may contain interleaved command's STDOUT and STDERR, + // not in sequential order (STDOUT followed by STDERR). + // In this case don't check the contents of the captured command's STDOUT. + if (toolProvider || outputCapture.outLines().isEmpty() || (command.stdout().isEmpty() || command.stderr().isEmpty())) { + assertEquals(expectedCapturedSystemOut(commandWithDiscardedStreams), outputCapture.outLines()); + } assertEquals(expectedCapturedSystemErr(commandWithDiscardedStreams), outputCapture.errLines()); assertEquals(expectedResultStdout(commandWithDiscardedStreams), result[0].stdout().getOutput()); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java index 91625603a2b..ef118e525c5 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java @@ -32,6 +32,7 @@ import java.io.InputStreamReader; import java.io.OutputStream; import java.io.PrintStream; import java.io.StringReader; +import java.io.UncheckedIOException; import java.io.Writer; import java.nio.file.Path; import java.util.ArrayList; @@ -42,12 +43,15 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.CompletionException; import java.util.function.Supplier; import java.util.regex.Pattern; import java.util.spi.ToolProvider; import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.jpackage.internal.util.function.ThrowingSupplier; +import jdk.jpackage.internal.util.function.ExceptionBox; public final class Executor extends CommandArguments { @@ -465,9 +469,37 @@ public final class Executor extends CommandArguments { trace("Execute " + sb.toString() + "..."); Process process = builder.start(); - final var output = combine( - processProcessStream(outputStreamsControl.stdout(), process.getInputStream()), - processProcessStream(outputStreamsControl.stderr(), process.getErrorStream())); + var stdoutGobbler = CompletableFuture.>>supplyAsync(() -> { + try { + return processProcessStream(outputStreamsControl.stdout(), process.getInputStream()); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + }); + + var stderrGobbler = CompletableFuture.>>supplyAsync(() -> { + try { + return processProcessStream(outputStreamsControl.stderr(), process.getErrorStream()); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + }); + + final CommandOutput output; + + try { + output = combine(stdoutGobbler.join(), stderrGobbler.join()); + } catch (CompletionException ex) { + var cause = ex.getCause(); + switch (cause) { + case UncheckedIOException uioex -> { + throw uioex.getCause(); + } + default -> { + throw ExceptionBox.toUnchecked(ExceptionBox.unbox(cause)); + } + } + } final int exitCode = process.waitFor(); trace("Done. Exit code: " + exitCode); From 0146077a51635500de771e9cf2c9788ae931b7a0 Mon Sep 17 00:00:00 2001 From: Leonid Mesnik Date: Thu, 18 Dec 2025 04:27:18 +0000 Subject: [PATCH 053/390] 8373723: Deadlock with JvmtiTagMap::flush_object_free_events() Reviewed-by: dholmes, coleenp --- src/hotspot/share/prims/jvmtiTagMap.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/prims/jvmtiTagMap.cpp b/src/hotspot/share/prims/jvmtiTagMap.cpp index 90a3461f321..04cb70863cd 100644 --- a/src/hotspot/share/prims/jvmtiTagMap.cpp +++ b/src/hotspot/share/prims/jvmtiTagMap.cpp @@ -1204,8 +1204,10 @@ void JvmtiTagMap::flush_object_free_events() { assert_not_at_safepoint(); if (env()->is_enabled(JVMTI_EVENT_OBJECT_FREE)) { { + // The other thread can block for safepoints during event callbacks, so ensure we + // are safepoint-safe while waiting. + ThreadBlockInVM tbivm(JavaThread::current()); MonitorLocker ml(lock(), Mutex::_no_safepoint_check_flag); - // If another thread is posting events, let it finish while (_posting_events) { ml.wait(); } From b4462625413e7c2c12778eaad1f2f21d81f59c52 Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Thu, 18 Dec 2025 07:04:40 +0000 Subject: [PATCH 054/390] 8373682: Test compiler/loopopts/superword/TestReinterpretAndCast.java fails on x86_64 with AVX but without f16c Reviewed-by: kvn, jsikstro, chagedorn --- .../compiler/loopopts/superword/TestReinterpretAndCast.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestReinterpretAndCast.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestReinterpretAndCast.java index ab2801179f2..9c5140d2aaa 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestReinterpretAndCast.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestReinterpretAndCast.java @@ -162,7 +162,7 @@ public class TestReinterpretAndCast { IRNode.STORE_VECTOR, "> 0", IRNode.VECTOR_REINTERPRET, "> 0"}, // We have at least I2F applyIfPlatform = {"64-bit", "true"}, - applyIfCPUFeature = {"avx", "true"}) + applyIfCPUFeatureAnd = {"avx", "true", "f16c", "true"}) @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_float, max_short)", "> 0", IRNode.VECTOR_CAST_F2HF, IRNode.VECTOR_SIZE + "min(max_int, max_float, max_short)", "> 0", IRNode.STORE_VECTOR, "> 0", @@ -208,7 +208,7 @@ public class TestReinterpretAndCast { IRNode.STORE_VECTOR, "> 0", IRNode.VECTOR_REINTERPRET, "> 0"}, // We have at least F2I applyIfPlatform = {"64-bit", "true"}, - applyIfCPUFeature = {"avx", "true"}) + applyIfCPUFeatureAnd = {"avx", "true", "f16c", "true"}) @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE + "min(max_float, max_short, max_long)", "> 0", IRNode.VECTOR_CAST_HF2F, IRNode.VECTOR_SIZE + "min(max_float, max_short, max_long)", "> 0", IRNode.VECTOR_CAST_I2L, IRNode.VECTOR_SIZE + "min(max_float, max_short, max_long)", "> 0", From 00050f84d44f3ec23e9c6da52bffd68770010749 Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Thu, 18 Dec 2025 07:05:05 +0000 Subject: [PATCH 055/390] 8373502: C2 SuperWord: speculative check uses VPointer variable was pinned after speculative check, leading to bad graph Reviewed-by: thartmann, roland --- src/hotspot/share/opto/vectorization.cpp | 25 +++++++ src/hotspot/share/opto/vectorization.hpp | 16 +++++ ...ingCheckVPointerVariablesNotAvailable.java | 71 +++++++++++++++++++ 3 files changed, 112 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/loopopts/superword/TestAliasingCheckVPointerVariablesNotAvailable.java diff --git a/src/hotspot/share/opto/vectorization.cpp b/src/hotspot/share/opto/vectorization.cpp index 15b2df663b6..230ff280f03 100644 --- a/src/hotspot/share/opto/vectorization.cpp +++ b/src/hotspot/share/opto/vectorization.cpp @@ -1060,6 +1060,29 @@ bool VPointer::can_make_speculative_aliasing_check_with(const VPointer& other) c return false; } + // The speculative check also needs to create the pointer expressions for both + // VPointers. We must check that we can do that, i.e. that all variables of the + // VPointers are available at the speculative check (and not just pre-loop invariant). + if (!this->can_make_pointer_expression_at_speculative_check()) { +#ifdef ASSERT + if (_vloop.is_trace_speculative_aliasing_analysis()) { + tty->print_cr("VPointer::can_make_speculative_aliasing_check_with: not all variables of VPointer are avaialbe at speculative check!"); + this->print_on(tty); + } +#endif + return false; + } + + if (!other.can_make_pointer_expression_at_speculative_check()) { +#ifdef ASSERT + if (_vloop.is_trace_speculative_aliasing_analysis()) { + tty->print_cr("VPointer::can_make_speculative_aliasing_check_with: not all variables of VPointer are avaialbe at speculative check!"); + other.print_on(tty); + } +#endif + return false; + } + return true; } @@ -1147,6 +1170,8 @@ BoolNode* VPointer::make_speculative_aliasing_check_with(const VPointer& other, Node* main_init = new ConvL2INode(main_initL); phase->register_new_node_with_ctrl_of(main_init, pre_init); + assert(vp1.can_make_pointer_expression_at_speculative_check(), "variables must be available early enough to avoid cycles"); + assert(vp2.can_make_pointer_expression_at_speculative_check(), "variables must be available early enough to avoid cycles"); Node* p1_init = vp1.make_pointer_expression(main_init, ctrl); Node* p2_init = vp2.make_pointer_expression(main_init, ctrl); Node* size1 = igvn.longcon(vp1.size()); diff --git a/src/hotspot/share/opto/vectorization.hpp b/src/hotspot/share/opto/vectorization.hpp index aacd406f798..9308712f78a 100644 --- a/src/hotspot/share/opto/vectorization.hpp +++ b/src/hotspot/share/opto/vectorization.hpp @@ -1188,6 +1188,22 @@ private: return true; } + // We already know that all non-iv summands are pre loop invariant. + // See init_are_non_iv_summands_pre_loop_invariant + // That is good enough for alignment computations in the pre-loop limit. But it is not + // sufficient if we want to use the variables of the VPointer at the speculative check, + // which is further up before the pre-loop. + bool can_make_pointer_expression_at_speculative_check() const { + bool success = true; + mem_pointer().for_each_non_empty_summand([&] (const MemPointerSummand& s) { + Node* variable = s.variable(); + if (variable != _vloop.iv() && !_vloop.is_available_for_speculative_check(variable)) { + success = false; + } + }); + return success; + } + // In the pointer analysis, and especially the AlignVector analysis, we assume that // stride and scale are not too large. For example, we multiply "iv_scale * iv_stride", // and assume that this does not overflow the int range. We also take "abs(iv_scale)" diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestAliasingCheckVPointerVariablesNotAvailable.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestAliasingCheckVPointerVariablesNotAvailable.java new file mode 100644 index 00000000000..47540da5648 --- /dev/null +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestAliasingCheckVPointerVariablesNotAvailable.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 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. + */ + +/* + * @test id=with-flags + * @bug 8373502 + * @summary Test where a VPointer variable was pinned at the pre-loop, but not available at the + * Auto_Vectorization_Check, and so it should not be used for the auto vectorization + * aliasing check, to avoid a bad (circular) graph. + * @run main/othervm + * -XX:CompileCommand=compileonly,*TestAliasingCheckVPointerVariablesNotAvailable::test + * -XX:-TieredCompilation + * -Xcomp + * ${test.main.class} + */ + +/* + * @test id=vanilla + * @bug 8373502 + * @run main ${test.main.class} + */ + +package compiler.loopopts.superword; + +public class TestAliasingCheckVPointerVariablesNotAvailable { + static int iFld; + + public static void main(String[] strArr) { + test(); + } + + static void test() { + int iArr[] = new int[400]; + boolean flag = false; + for (int i = 6; i < 50000; i++) { // Trigger OSR + try { + int x = 234 / iFld; + iFld = iArr[3]; + } catch (ArithmeticException a_e) { + } + for (int j = i; j < 2; j++) { + if (flag) { + iArr[j] = 117; + } else { + iArr[1] = 34; + } + iArr[1] += i; + } + } + } +} From e67805067a8f537862200e808e20464f12d21c9c Mon Sep 17 00:00:00 2001 From: Quan Anh Mai Date: Thu, 18 Dec 2025 07:31:06 +0000 Subject: [PATCH 056/390] 8367341: C2: apply KnownBits and unsigned bounds to And / Or operations Reviewed-by: hgreule, epeter --- src/hotspot/share/opto/addnode.cpp | 91 +--- src/hotspot/share/opto/mulnode.cpp | 78 +--- src/hotspot/share/opto/rangeinference.cpp | 8 +- src/hotspot/share/opto/rangeinference.hpp | 231 +++++++++- src/hotspot/share/opto/type.hpp | 2 + src/hotspot/share/opto/utilities/xor.hpp | 47 -- src/hotspot/share/utilities/intn_t.hpp | 1 + .../gtest/opto/test_rangeinference.cpp | 425 +++++++++++++++++- test/hotspot/gtest/opto/test_xor_node.cpp | 102 ----- 9 files changed, 651 insertions(+), 334 deletions(-) delete mode 100644 src/hotspot/share/opto/utilities/xor.hpp delete mode 100644 test/hotspot/gtest/opto/test_xor_node.cpp diff --git a/src/hotspot/share/opto/addnode.cpp b/src/hotspot/share/opto/addnode.cpp index 6075317d86e..accb3d32b67 100644 --- a/src/hotspot/share/opto/addnode.cpp +++ b/src/hotspot/share/opto/addnode.cpp @@ -31,8 +31,8 @@ #include "opto/movenode.hpp" #include "opto/mulnode.hpp" #include "opto/phaseX.hpp" +#include "opto/rangeinference.hpp" #include "opto/subnode.hpp" -#include "opto/utilities/xor.hpp" #include "runtime/stubRoutines.hpp" // Portions of code courtesy of Clifford Click @@ -1011,35 +1011,8 @@ Node* OrINode::Ideal(PhaseGVN* phase, bool can_reshape) { // the logical operations the ring's ADD is really a logical OR function. // This also type-checks the inputs for sanity. Guaranteed never to // be passed a TOP or BOTTOM type, these are filtered out by pre-check. -const Type *OrINode::add_ring( const Type *t0, const Type *t1 ) const { - const TypeInt *r0 = t0->is_int(); // Handy access - const TypeInt *r1 = t1->is_int(); - - // If both args are bool, can figure out better types - if ( r0 == TypeInt::BOOL ) { - if ( r1 == TypeInt::ONE) { - return TypeInt::ONE; - } else if ( r1 == TypeInt::BOOL ) { - return TypeInt::BOOL; - } - } else if ( r0 == TypeInt::ONE ) { - if ( r1 == TypeInt::BOOL ) { - return TypeInt::ONE; - } - } - - // If either input is all ones, the output is all ones. - // x | ~0 == ~0 <==> x | -1 == -1 - if (r0 == TypeInt::MINUS_1 || r1 == TypeInt::MINUS_1) { - return TypeInt::MINUS_1; - } - - // If either input is not a constant, just return all integers. - if( !r0->is_con() || !r1->is_con() ) - return TypeInt::INT; // Any integer, but still no symbols. - - // Otherwise just OR them bits. - return TypeInt::make( r0->get_con() | r1->get_con() ); +const Type* OrINode::add_ring(const Type* t1, const Type* t2) const { + return RangeInference::infer_or(t1->is_int(), t2->is_int()); } //============================================================================= @@ -1087,22 +1060,8 @@ Node* OrLNode::Ideal(PhaseGVN* phase, bool can_reshape) { } //------------------------------add_ring--------------------------------------- -const Type *OrLNode::add_ring( const Type *t0, const Type *t1 ) const { - const TypeLong *r0 = t0->is_long(); // Handy access - const TypeLong *r1 = t1->is_long(); - - // If either input is all ones, the output is all ones. - // x | ~0 == ~0 <==> x | -1 == -1 - if (r0 == TypeLong::MINUS_1 || r1 == TypeLong::MINUS_1) { - return TypeLong::MINUS_1; - } - - // If either input is not a constant, just return all integers. - if( !r0->is_con() || !r1->is_con() ) - return TypeLong::LONG; // Any integer, but still no symbols. - - // Otherwise just OR them bits. - return TypeLong::make( r0->get_con() | r1->get_con() ); +const Type* OrLNode::add_ring(const Type* t1, const Type* t2) const { + return RangeInference::infer_or(t1->is_long(), t2->is_long()); } //---------------------------Helper ------------------------------------------- @@ -1189,46 +1148,14 @@ const Type* XorINode::Value(PhaseGVN* phase) const { // the logical operations the ring's ADD is really a logical OR function. // This also type-checks the inputs for sanity. Guaranteed never to // be passed a TOP or BOTTOM type, these are filtered out by pre-check. -const Type *XorINode::add_ring( const Type *t0, const Type *t1 ) const { - const TypeInt *r0 = t0->is_int(); // Handy access - const TypeInt *r1 = t1->is_int(); - - if (r0->is_con() && r1->is_con()) { - // compute constant result - return TypeInt::make(r0->get_con() ^ r1->get_con()); - } - - // At least one of the arguments is not constant - - if (r0->_lo >= 0 && r1->_lo >= 0) { - // Combine [r0->_lo, r0->_hi] ^ [r0->_lo, r1->_hi] -> [0, upper_bound] - jint upper_bound = xor_upper_bound_for_ranges(r0->_hi, r1->_hi); - return TypeInt::make(0, upper_bound, MAX2(r0->_widen, r1->_widen)); - } - - return TypeInt::INT; +const Type* XorINode::add_ring(const Type* t1, const Type* t2) const { + return RangeInference::infer_xor(t1->is_int(), t2->is_int()); } //============================================================================= //------------------------------add_ring--------------------------------------- -const Type *XorLNode::add_ring( const Type *t0, const Type *t1 ) const { - const TypeLong *r0 = t0->is_long(); // Handy access - const TypeLong *r1 = t1->is_long(); - - if (r0->is_con() && r1->is_con()) { - // compute constant result - return TypeLong::make(r0->get_con() ^ r1->get_con()); - } - - // At least one of the arguments is not constant - - if (r0->_lo >= 0 && r1->_lo >= 0) { - // Combine [r0->_lo, r0->_hi] ^ [r0->_lo, r1->_hi] -> [0, upper_bound] - julong upper_bound = xor_upper_bound_for_ranges(r0->_hi, r1->_hi); - return TypeLong::make(0, upper_bound, MAX2(r0->_widen, r1->_widen)); - } - - return TypeLong::LONG; +const Type* XorLNode::add_ring(const Type* t1, const Type* t2) const { + return RangeInference::infer_xor(t1->is_long(), t2->is_long()); } Node* XorLNode::Ideal(PhaseGVN* phase, bool can_reshape) { diff --git a/src/hotspot/share/opto/mulnode.cpp b/src/hotspot/share/opto/mulnode.cpp index 280781f686b..aa8d6cfce2e 100644 --- a/src/hotspot/share/opto/mulnode.cpp +++ b/src/hotspot/share/opto/mulnode.cpp @@ -29,6 +29,7 @@ #include "opto/memnode.hpp" #include "opto/mulnode.hpp" #include "opto/phaseX.hpp" +#include "opto/rangeinference.hpp" #include "opto/subnode.hpp" #include "utilities/powerOfTwo.hpp" @@ -620,80 +621,14 @@ const Type* MulHiValue(const Type *t1, const Type *t2, const Type *bot) { return TypeLong::LONG; } -template -static const IntegerType* and_value(const IntegerType* r0, const IntegerType* r1) { - typedef typename IntegerType::NativeType NativeType; - static_assert(std::is_signed::value, "Native type of IntegerType must be signed!"); - - int widen = MAX2(r0->_widen, r1->_widen); - - // If both types are constants, we can calculate a constant result. - if (r0->is_con() && r1->is_con()) { - return IntegerType::make(r0->get_con() & r1->get_con()); - } - - // If both ranges are positive, the result will range from 0 up to the hi value of the smaller range. The minimum - // of the two constrains the upper bound because any higher value in the other range will see all zeroes, so it will be masked out. - if (r0->_lo >= 0 && r1->_lo >= 0) { - return IntegerType::make(0, MIN2(r0->_hi, r1->_hi), widen); - } - - // If only one range is positive, the result will range from 0 up to that range's maximum value. - // For the operation 'x & C' where C is a positive constant, the result will be in the range [0..C]. With that observation, - // we can say that for any integer c such that 0 <= c <= C will also be in the range [0..C]. Therefore, 'x & [c..C]' - // where c >= 0 will be in the range [0..C]. - if (r0->_lo >= 0) { - return IntegerType::make(0, r0->_hi, widen); - } - - if (r1->_lo >= 0) { - return IntegerType::make(0, r1->_hi, widen); - } - - // At this point, all positive ranges will have already been handled, so the only remaining cases will be negative ranges - // and constants. - - assert(r0->_lo < 0 && r1->_lo < 0, "positive ranges should already be handled!"); - - // As two's complement means that both numbers will start with leading 1s, the lower bound of both ranges will contain - // the common leading 1s of both minimum values. In order to count them with count_leading_zeros, the bits are inverted. - NativeType sel_val = ~MIN2(r0->_lo, r1->_lo); - - NativeType min; - if (sel_val == 0) { - // Since count_leading_zeros is undefined at 0, we short-circuit the condition where both ranges have a minimum of -1. - min = -1; - } else { - // To get the number of bits to shift, we count the leading 0-bits and then subtract one, as the sign bit is already set. - int shift_bits = count_leading_zeros(sel_val) - 1; - min = std::numeric_limits::min() >> shift_bits; - } - - NativeType max; - if (r0->_hi < 0 && r1->_hi < 0) { - // If both ranges are negative, then the same optimization as both positive ranges will apply, and the smaller hi - // value will mask off any bits set by higher values. - max = MIN2(r0->_hi, r1->_hi); - } else { - // In the case of ranges that cross zero, negative values can cause the higher order bits to be set, so the maximum - // positive value can be as high as the larger hi value. - max = MAX2(r0->_hi, r1->_hi); - } - - return IntegerType::make(min, max, widen); -} - //============================================================================= //------------------------------mul_ring--------------------------------------- // Supplied function returns the product of the inputs IN THE CURRENT RING. // For the logical operations the ring's MUL is really a logical AND function. // This also type-checks the inputs for sanity. Guaranteed never to // be passed a TOP or BOTTOM type, these are filtered out by pre-check. -const Type *AndINode::mul_ring( const Type *t0, const Type *t1 ) const { - const TypeInt* r0 = t0->is_int(); - const TypeInt* r1 = t1->is_int(); - - return and_value(r0, r1); +const Type* AndINode::mul_ring(const Type* t1, const Type* t2) const { + return RangeInference::infer_and(t1->is_int(), t2->is_int()); } static bool AndIL_is_zero_element_under_mask(const PhaseGVN* phase, const Node* expr, const Node* mask, BasicType bt); @@ -822,11 +757,8 @@ Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) { // For the logical operations the ring's MUL is really a logical AND function. // This also type-checks the inputs for sanity. Guaranteed never to // be passed a TOP or BOTTOM type, these are filtered out by pre-check. -const Type *AndLNode::mul_ring( const Type *t0, const Type *t1 ) const { - const TypeLong* r0 = t0->is_long(); - const TypeLong* r1 = t1->is_long(); - - return and_value(r0, r1); +const Type* AndLNode::mul_ring(const Type* t1, const Type* t2) const { + return RangeInference::infer_and(t1->is_long(), t2->is_long()); } const Type* AndLNode::Value(PhaseGVN* phase) const { diff --git a/src/hotspot/share/opto/rangeinference.cpp b/src/hotspot/share/opto/rangeinference.cpp index 40b9da4bde5..cb26e68ef58 100644 --- a/src/hotspot/share/opto/rangeinference.cpp +++ b/src/hotspot/share/opto/rangeinference.cpp @@ -25,7 +25,6 @@ #include "opto/rangeinference.hpp" #include "opto/type.hpp" #include "utilities/intn_t.hpp" -#include "utilities/tuple.hpp" // If the cardinality of a TypeInt is below this threshold, use min widen, see // TypeIntPrototype::normalize_widen @@ -688,6 +687,8 @@ template class TypeIntPrototype, uintn_t<1>>; template class TypeIntPrototype, uintn_t<2>>; template class TypeIntPrototype, uintn_t<3>>; template class TypeIntPrototype, uintn_t<4>>; +template class TypeIntPrototype, uintn_t<5>>; +template class TypeIntPrototype, uintn_t<6>>; // Compute the meet of 2 types. When dual is true, the subset relation in CT is // reversed. This means that the result of 2 CTs would be the intersection of @@ -709,10 +710,7 @@ const Type* TypeIntHelper::int_type_xmeet(const CT* i1, const Type* t2) { if (!i1->_is_dual) { // meet (a.k.a union) - return CT::make_or_top(TypeIntPrototype{{MIN2(i1->_lo, i2->_lo), MAX2(i1->_hi, i2->_hi)}, - {MIN2(i1->_ulo, i2->_ulo), MAX2(i1->_uhi, i2->_uhi)}, - {i1->_bits._zeros & i2->_bits._zeros, i1->_bits._ones & i2->_bits._ones}}, - MAX2(i1->_widen, i2->_widen), false); + return int_type_union(i1, i2); } else { // join (a.k.a intersection) return CT::make_or_top(TypeIntPrototype{{MAX2(i1->_lo, i2->_lo), MIN2(i1->_hi, i2->_hi)}, diff --git a/src/hotspot/share/opto/rangeinference.hpp b/src/hotspot/share/opto/rangeinference.hpp index 73b8b43bd6e..ebfd98ca4a6 100644 --- a/src/hotspot/share/opto/rangeinference.hpp +++ b/src/hotspot/share/opto/rangeinference.hpp @@ -25,6 +25,7 @@ #ifndef SHARE_OPTO_RANGEINFERENCE_HPP #define SHARE_OPTO_RANGEINFERENCE_HPP +#include "cppstdlib/limits.hpp" #include "cppstdlib/type_traits.hpp" #include "utilities/globalDefinitions.hpp" @@ -92,19 +93,6 @@ public: RangeInt _urange; KnownBits _bits; -private: - friend class TypeInt; - friend class TypeLong; - - template - friend void test_canonicalize_constraints_exhaustive(); - - template - friend void test_canonicalize_constraints_simple(); - - template - friend void test_canonicalize_constraints_random(); - // A canonicalized version of a TypeIntPrototype, if the prototype represents // an empty type, _present is false, otherwise, _data is canonical class CanonicalizedTypeIntPrototype { @@ -158,21 +146,33 @@ public: template static const Type* int_type_xmeet(const CT* i1, const Type* t2); - template - static bool int_type_is_equal(const CT* t1, const CT* t2) { + template + static CTP int_type_union(CTP t1, CTP t2) { + using CT = std::conditional_t, std::remove_pointer_t, CTP>; + using S = std::remove_const_t; + using U = std::remove_const_t; + return CT::make(TypeIntPrototype{{MIN2(t1->_lo, t2->_lo), MAX2(t1->_hi, t2->_hi)}, + {MIN2(t1->_ulo, t2->_ulo), MAX2(t1->_uhi, t2->_uhi)}, + {t1->_bits._zeros & t2->_bits._zeros, t1->_bits._ones & t2->_bits._ones}}, + MAX2(t1->_widen, t2->_widen)); + } + + template + static bool int_type_is_equal(const CTP t1, const CTP t2) { return t1->_lo == t2->_lo && t1->_hi == t2->_hi && t1->_ulo == t2->_ulo && t1->_uhi == t2->_uhi && t1->_bits._zeros == t2->_bits._zeros && t1->_bits._ones == t2->_bits._ones; } - template - static bool int_type_is_subset(const CT* super, const CT* sub) { + template + static bool int_type_is_subset(const CTP super, const CTP sub) { + using U = decltype(super->_ulo); return super->_lo <= sub->_lo && super->_hi >= sub->_hi && super->_ulo <= sub->_ulo && super->_uhi >= sub->_uhi && // All bits that are known in super must also be known to be the same // value in sub, &~ (and not) is the same as a set subtraction on bit // sets - (super->_bits._zeros &~ sub->_bits._zeros) == 0 && (super->_bits._ones &~ sub->_bits._ones) == 0; + (super->_bits._zeros &~ sub->_bits._zeros) == U(0) && (super->_bits._ones &~ sub->_bits._ones) == U(0); } template @@ -195,4 +195,199 @@ public: #endif // PRODUCT }; +// A TypeIntMirror is structurally similar to a TypeInt or a TypeLong but it decouples the range +// inference from the Type infrastructure of the compiler. It also allows more flexibility with the +// bit width of the integer type. As a result, it is more efficient to use for intermediate steps +// of inference, as well as more flexible to perform testing on different integer types. +template +class TypeIntMirror { +public: + S _lo; + S _hi; + U _ulo; + U _uhi; + KnownBits _bits; + int _widen = 0; // dummy field to mimic the same field in TypeInt, useful in testing + + static TypeIntMirror make(const TypeIntPrototype& t, int widen) { + auto canonicalized_t = t.canonicalize_constraints(); + assert(!canonicalized_t.empty(), "must not be empty"); + return TypeIntMirror{canonicalized_t._data._srange._lo, canonicalized_t._data._srange._hi, + canonicalized_t._data._urange._lo, canonicalized_t._data._urange._hi, + canonicalized_t._data._bits}; + } + + // These allow TypeIntMirror to mimick the behaviors of TypeInt* and TypeLong*, so they can be + // passed into RangeInference methods. These are only used in testing, so they are implemented in + // the test file. + const TypeIntMirror* operator->() const; + TypeIntMirror meet(const TypeIntMirror& o) const; + bool contains(U u) const; + bool contains(const TypeIntMirror& o) const; + bool operator==(const TypeIntMirror& o) const; + + template + TypeIntMirror cast() const; +}; + +// This class contains methods for inferring the Type of the result of several arithmetic +// operations from those of the corresponding inputs. For example, given a, b such that the Type of +// a is [0, 1] and the Type of b is [-1, 3], then the Type of the sum a + b is [-1, 4]. +// The methods in this class receive one or more template parameters which are often TypeInt* or +// TypeLong*, or they can be TypeIntMirror which behave similar to TypeInt* and TypeLong* during +// testing. This allows us to verify the correctness of the implementation without coupling with +// the hotspot compiler allocation infrastructure. +class RangeInference { +private: + // If CTP is a pointer, get the underlying type. For the test helper classes, using the struct + // directly allows straightfoward equality comparison. + template + using CT = std::remove_const_t, std::remove_pointer_t, CTP>>; + + // The type of CT::_lo, should be jint for TypeInt* and jlong for TypeLong* + template + using S = std::remove_const_t::_lo)>; + + // The type of CT::_ulo, should be juint for TypeInt* and julong for TypeLong* + template + using U = std::remove_const_t::_ulo)>; + + // A TypeInt consists of 1 or 2 simple intervals, each of which will lie either in the interval + // [0, max_signed] or [min_signed, -1]. It is more optimal to analyze each simple interval + // separately when doing inference. For example, consider a, b whose Types are both [-2, 2]. By + // analyzing the interval [-2, -1] and [0, 2] separately, we can easily see that the result of + // a & b must also be in the interval [-2, 2]. This is much harder if we want to work with the + // whole value range at the same time. + // This class offers a convenient way to traverse all the simple interval of a TypeInt. + template + class SimpleIntervalIterable { + private: + TypeIntMirror, U> _first_interval; + TypeIntMirror, U> _second_interval; + int _interval_num; + + public: + SimpleIntervalIterable(CTP t) { + if (U(t->_lo) <= U(t->_hi)) { + _interval_num = 1; + _first_interval = TypeIntMirror, U>{t->_lo, t->_hi, t->_ulo, t->_uhi, t->_bits}; + } else { + _interval_num = 2; + _first_interval = TypeIntMirror, U>::make(TypeIntPrototype, U>{{t->_lo, S(t->_uhi)}, {U(t->_lo), t->_uhi}, t->_bits}, 0); + _second_interval = TypeIntMirror, U>::make(TypeIntPrototype, U>{{S(t->_ulo), t->_hi}, {t->_ulo, U(t->_hi)}, t->_bits}, 0); + } + } + + class Iterator { + private: + const SimpleIntervalIterable& _iterable; + int _current_interval; + + Iterator(const SimpleIntervalIterable& iterable) : _iterable(iterable), _current_interval(0) {} + + friend class SimpleIntervalIterable; + public: + const TypeIntMirror, U>& operator*() const { + assert(_current_interval < _iterable._interval_num, "out of bounds, %d - %d", _current_interval, _iterable._interval_num); + if (_current_interval == 0) { + return _iterable._first_interval; + } else { + return _iterable._second_interval; + } + } + + Iterator& operator++() { + assert(_current_interval < _iterable._interval_num, "out of bounds, %d - %d", _current_interval, _iterable._interval_num); + _current_interval++; + return *this; + } + + bool operator!=(const Iterator& o) const { + assert(&_iterable == &o._iterable, "not on the same iterable"); + return _current_interval != o._current_interval; + } + }; + + Iterator begin() const { + return Iterator(*this); + } + + Iterator end() const { + Iterator res(*this); + res._current_interval = _interval_num; + return res; + } + }; + + // Infer a result given the input types of a binary operation + template + static CTP infer_binary(CTP t1, CTP t2, Inference infer) { + CTP res; + bool is_init = false; + + SimpleIntervalIterable t1_simple_intervals(t1); + SimpleIntervalIterable t2_simple_intervals(t2); + + for (auto& st1 : t1_simple_intervals) { + for (auto& st2 : t2_simple_intervals) { + CTP current = infer(st1, st2); + + if (is_init) { + res = res->meet(current)->template cast>(); + } else { + is_init = true; + res = current; + } + } + } + + assert(is_init, "must be initialized"); + return res; + } + +public: + template + static CTP infer_and(CTP t1, CTP t2) { + return infer_binary(t1, t2, [&](const TypeIntMirror, U>& st1, const TypeIntMirror, U>& st2) { + S lo = std::numeric_limits>::min(); + S hi = std::numeric_limits>::max(); + U ulo = std::numeric_limits>::min(); + // The unsigned value of the result of 'and' is always not greater than both of its inputs + // since there is no position at which the bit is 1 in the result and 0 in either input + U uhi = MIN2(st1._uhi, st2._uhi); + U zeros = st1._bits._zeros | st2._bits._zeros; + U ones = st1._bits._ones & st2._bits._ones; + return CT::make(TypeIntPrototype, U>{{lo, hi}, {ulo, uhi}, {zeros, ones}}, MAX2(t1->_widen, t2->_widen)); + }); + } + + template + static CTP infer_or(CTP t1, CTP t2) { + return infer_binary(t1, t2, [&](const TypeIntMirror, U>& st1, const TypeIntMirror, U>& st2) { + S lo = std::numeric_limits>::min(); + S hi = std::numeric_limits>::max(); + // The unsigned value of the result of 'or' is always not less than both of its inputs since + // there is no position at which the bit is 0 in the result and 1 in either input + U ulo = MAX2(st1._ulo, st2._ulo); + U uhi = std::numeric_limits>::max(); + U zeros = st1._bits._zeros & st2._bits._zeros; + U ones = st1._bits._ones | st2._bits._ones; + return CT::make(TypeIntPrototype, U>{{lo, hi}, {ulo, uhi}, {zeros, ones}}, MAX2(t1->_widen, t2->_widen)); + }); + } + + template + static CTP infer_xor(CTP t1, CTP t2) { + return infer_binary(t1, t2, [&](const TypeIntMirror, U>& st1, const TypeIntMirror, U>& st2) { + S lo = std::numeric_limits>::min(); + S hi = std::numeric_limits>::max(); + U ulo = std::numeric_limits>::min(); + U uhi = std::numeric_limits>::max(); + U zeros = (st1._bits._zeros & st2._bits._zeros) | (st1._bits._ones & st2._bits._ones); + U ones = (st1._bits._zeros & st2._bits._ones) | (st1._bits._ones & st2._bits._zeros); + return CT::make(TypeIntPrototype, U>{{lo, hi}, {ulo, uhi}, {zeros, ones}}, MAX2(t1->_widen, t2->_widen)); + }); + } +}; + #endif // SHARE_OPTO_RANGEINFERENCE_HPP diff --git a/src/hotspot/share/opto/type.hpp b/src/hotspot/share/opto/type.hpp index 4666cfbcf2d..73e2ba0045a 100644 --- a/src/hotspot/share/opto/type.hpp +++ b/src/hotspot/share/opto/type.hpp @@ -798,6 +798,7 @@ public: // must always specify w static const TypeInt* make(jint lo, jint hi, int widen); static const Type* make_or_top(const TypeIntPrototype& t, int widen); + static const TypeInt* make(const TypeIntPrototype& t, int widen) { return make_or_top(t, widen)->is_int(); } // Check for single integer bool is_con() const { return _lo == _hi; } @@ -879,6 +880,7 @@ public: // must always specify w static const TypeLong* make(jlong lo, jlong hi, int widen); static const Type* make_or_top(const TypeIntPrototype& t, int widen); + static const TypeLong* make(const TypeIntPrototype& t, int widen) { return make_or_top(t, widen)->is_long(); } // Check for single integer bool is_con() const { return _lo == _hi; } diff --git a/src/hotspot/share/opto/utilities/xor.hpp b/src/hotspot/share/opto/utilities/xor.hpp deleted file mode 100644 index 20edaf0d017..00000000000 --- a/src/hotspot/share/opto/utilities/xor.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef SHARE_OPTO_UTILITIES_XOR_HPP -#define SHARE_OPTO_UTILITIES_XOR_HPP - -#include "utilities/powerOfTwo.hpp" -// Code separated into its own header to allow access from GTEST - -// Given 2 non-negative values in the ranges [0, hi_0] and [0, hi_1], respectively. The bitwise -// xor of these values should also be non-negative. This method calculates an upper bound. - -// S and U type parameters correspond to the signed and unsigned -// variants of an integer to operate on. -template -static S xor_upper_bound_for_ranges(const S hi_0, const S hi_1) { - static_assert(S(-1) < S(0), "S must be signed"); - static_assert(U(-1) > U(0), "U must be unsigned"); - - assert(hi_0 >= 0, "must be non-negative"); - assert(hi_1 >= 0, "must be non-negative"); - - // x ^ y cannot have any bit set that is higher than both the highest bits set in x and y - // x cannot have any bit set that is higher than the highest bit set in hi_0 - // y cannot have any bit set that is higher than the highest bit set in hi_1 - - // We want to find a value that has all 1 bits everywhere up to and including - // the highest bits set in hi_0 as well as hi_1. For this, we can take the next - // power of 2 strictly greater than both hi values and subtract 1 from it. - - // Example 1: - // hi_0 = 5 (0b0101) hi_1=1 (0b0001) - // (5|1)+1 = 0b0110 - // round_up_pow2 = 0b1000 - // -1 = 0b0111 = max - - // Example 2 - this demonstrates need for the +1: - // hi_0 = 4 (0b0100) hi_1=4 (0b0100) - // (4|4)+1 = 0b0101 - // round_up_pow2 = 0b1000 - // -1 = 0b0111 = max - // Without the +1, round_up_pow2 would be 0b0100, resulting in 0b0011 as max - - // Note: cast to unsigned happens before +1 to avoid signed overflow, and - // round_up is safe because high bit is unset (0 <= lo <= hi) - - return round_up_power_of_2(U(hi_0 | hi_1) + 1) - 1; -} - -#endif // SHARE_OPTO_UTILITIES_XOR_HPP diff --git a/src/hotspot/share/utilities/intn_t.hpp b/src/hotspot/share/utilities/intn_t.hpp index 6f43f5c2556..594e62a1694 100644 --- a/src/hotspot/share/utilities/intn_t.hpp +++ b/src/hotspot/share/utilities/intn_t.hpp @@ -79,6 +79,7 @@ public: static_assert(min < max, ""); constexpr bool operator==(intn_t o) const { return (_v & _mask) == (o._v & _mask); } + constexpr bool operator!=(intn_t o) const { return !(*this == o); } constexpr bool operator<(intn_t o) const { return int(*this) < int(o); } constexpr bool operator>(intn_t o) const { return int(*this) > int(o); } constexpr bool operator<=(intn_t o) const { return int(*this) <= int(o); } diff --git a/test/hotspot/gtest/opto/test_rangeinference.cpp b/test/hotspot/gtest/opto/test_rangeinference.cpp index 1a62941a486..61a9ff7fb70 100644 --- a/test/hotspot/gtest/opto/test_rangeinference.cpp +++ b/test/hotspot/gtest/opto/test_rangeinference.cpp @@ -25,15 +25,16 @@ #include "opto/rangeinference.hpp" #include "opto/type.hpp" #include "runtime/os.hpp" -#include "utilities/intn_t.hpp" #include "unittest.hpp" +#include "utilities/intn_t.hpp" +#include "utilities/rbTree.hpp" +#include +#include +#include template -static U uniform_random(); - -template <> -juint uniform_random() { - return os::random(); +static U uniform_random() { + return U(juint(os::random())); } template <> @@ -201,7 +202,7 @@ static void test_canonicalize_constraints_random() { } } -TEST_VM(opto, canonicalize_constraints) { +TEST(opto, canonicalize_constraints) { test_canonicalize_constraints_trivial(); test_canonicalize_constraints_exhaustive, uintn_t<1>>(); test_canonicalize_constraints_exhaustive, uintn_t<2>>(); @@ -212,3 +213,413 @@ TEST_VM(opto, canonicalize_constraints) { test_canonicalize_constraints_random(); test_canonicalize_constraints_random(); } + +// Implementations of TypeIntMirror methods for testing purposes +template +const TypeIntMirror* TypeIntMirror::operator->() const { + return this; +} + +template +TypeIntMirror TypeIntMirror::meet(const TypeIntMirror& o) const { + return TypeIntHelper::int_type_union(*this, o); +} + +template +bool TypeIntMirror::contains(U u) const { + S s = S(u); + return s >= _lo && s <= _hi && u >= _ulo && u <= _uhi && _bits.is_satisfied_by(u); +} + +template +bool TypeIntMirror::contains(const TypeIntMirror& o) const { + return TypeIntHelper::int_type_is_subset(*this, o); +} + +template +bool TypeIntMirror::operator==(const TypeIntMirror& o) const { + return TypeIntHelper::int_type_is_equal(*this, o); +} + +template +template +TypeIntMirror TypeIntMirror::cast() const { + static_assert(std::is_same_v); + return *this; +} + +// The number of TypeIntMirror instances for integral types with a few bits. These values are +// calculated once and written down for usage in constexpr contexts. +template +static constexpr size_t all_instances_size() { + using U = decltype(CTP::_ulo); + constexpr juint max_unsigned = juint(std::numeric_limits::max()); + if constexpr (max_unsigned == 1U) { + // 1 bit + return 3; + } else if constexpr (max_unsigned == 3U) { + // 2 bits + return 15; + } else if constexpr (max_unsigned == 7U) { + // 3 bits + return 134; + } else { + // 4 bits + static_assert(max_unsigned == 15U); + // For more than 4 bits, the number of instances is too large and it is not realistic to + // compute all of them. + return 1732; + } +} + +template +static std::array()> compute_all_instances() { + using S = decltype(CTP::_lo); + using U = decltype(CTP::_ulo); + + class CTPComparator { + public: + static RBTreeOrdering cmp(const CTP& x, const RBNode* node) { + // Quick helper for the tediousness below + auto f = [](auto x, auto y) { + assert(x != y, "we only handle lt and gt cases"); + return x < y ? RBTreeOrdering::LT : RBTreeOrdering::GT; + }; + + const CTP& y = node->key(); + if (x._lo != y._lo) { + return f(x._lo, y._lo); + } else if (x._hi != y._hi) { + return f(x._hi, y._hi); + } else if (x._ulo != y._ulo) { + return f(x._ulo, y._ulo); + } else if (x._uhi != y._uhi) { + return f(x._uhi, y._uhi); + } else if (x._bits._zeros != y._bits._zeros) { + return f(x._bits._zeros, y._bits._zeros); + } else if (x._bits._ones != y._bits._ones) { + return f(x._bits._ones, y._bits._ones); + } else { + return RBTreeOrdering::EQ; + } + } + }; + + RBTreeCHeap collector; + for (jint lo = jint(std::numeric_limits::min()); lo <= jint(std::numeric_limits::max()); lo++) { + for (jint hi = lo; hi <= jint(std::numeric_limits::max()); hi++) { + for (juint ulo = 0; ulo <= juint(std::numeric_limits::max()); ulo++) { + for (juint uhi = ulo; uhi <= juint(std::numeric_limits::max()); uhi++) { + for (juint zeros = 0; zeros <= juint(std::numeric_limits::max()); zeros++) { + for (juint ones = 0; ones <= juint(std::numeric_limits::max()); ones++) { + TypeIntPrototype t{{S(lo), S(hi)}, {U(ulo), U(uhi)}, {U(zeros), U(ones)}}; + auto canonicalized_t = t.canonicalize_constraints(); + if (canonicalized_t.empty()) { + continue; + } + + TypeIntPrototype ct = canonicalized_t._data; + collector.upsert(CTP{ct._srange._lo, ct._srange._hi, ct._urange._lo, ct._urange._hi, ct._bits}, 0); + } + } + } + } + } + } + + assert(collector.size() == all_instances_size(), "unexpected size of all_instance, expected %d, actual %d", jint(all_instances_size()), jint(collector.size())); + std::array()> res; + size_t idx = 0; + collector.visit_in_order([&](RBNode* node) { + res[idx] = node->key(); + idx++; + return true; + }); + return res; +} + +template +static const std::array()>& all_instances() { + static std::array()> res = compute_all_instances(); + static_assert(std::is_trivially_destructible_v); + return res; +} + +// Check the correctness, that is, if v1 is an element of input1, v2 is an element of input2, then +// op(v1, v2) must be an element of infer(input1, input2). This version does the check exhaustively +// on all elements of input1 and input2. +template +static void test_binary_instance_correctness_exhaustive(Operation op, Inference infer, const InputType& input1, const InputType& input2) { + using S = std::remove_const_t_lo)>; + using U = std::remove_const_t_ulo)>; + InputType result = infer(input1, input2); + + for (juint v1 = juint(std::numeric_limits::min()); v1 <= juint(std::numeric_limits::max()); v1++) { + if (!input1.contains(U(v1))) { + continue; + } + + for (juint v2 = juint(std::numeric_limits::min()); v2 <= juint(std::numeric_limits::max()); v2++) { + if (!input2.contains(U(v2))) { + continue; + } + + U r = op(U(v1), U(v2)); + ASSERT_TRUE(result.contains(r)); + } + } +} + +// Check the correctness, that is, if v1 is an element of input1, v2 is an element of input2, then +// op(v1, v2) must be an element of infer(input1, input2). This version does the check randomly on +// a number of elements in input1 and input2. +template +static void test_binary_instance_correctness_samples(Operation op, Inference infer, const InputType& input1, const InputType& input2) { + using U = std::remove_const_t_ulo)>; + auto result = infer(input1, input2); + + constexpr size_t sample_count = 6; + U input1_samples[sample_count] {U(input1._lo), U(input1._hi), input1._ulo, input1._uhi, input1._ulo, input1._ulo}; + U input2_samples[sample_count] {U(input2._lo), U(input2._hi), input2._ulo, input2._uhi, input2._ulo, input2._ulo}; + + auto random_sample = [](U* samples, const InputType& input) { + constexpr size_t max_tries = 100; + constexpr size_t start_random_idx = 4; + for (size_t tries = 0, idx = start_random_idx; tries < max_tries && idx < sample_count; tries++) { + U n = uniform_random(); + if (input.contains(n)) { + samples[idx] = n; + idx++; + } + } + }; + random_sample(input1_samples, input1); + random_sample(input2_samples, input2); + + for (size_t i = 0; i < sample_count; i++) { + for (size_t j = 0; j < sample_count; j++) { + U r = op(input1_samples[i], input2_samples[j]); + ASSERT_TRUE(result.contains(r)); + } + } +} + +// Check the monotonicity, that is, if input1 is a subset of super1, input2 is a subset of super2, +// then infer(input1, input2) must be a subset of infer(super1, super2). This version does the +// check exhaustively on all supersets of input1 and input2. +template +static void test_binary_instance_monotonicity_exhaustive(Inference infer, const InputType& input1, const InputType& input2) { + InputType result = infer(input1, input2); + + for (const InputType& super1 : all_instances()) { + if (!super1.contains(input1) || super1 == input1) { + continue; + } + + for (const InputType& super2 : all_instances()) { + if (!super2.contains(input2) || super2 == input2) { + continue; + } + + ASSERT_TRUE(infer(input1, super2).contains(result)); + ASSERT_TRUE(infer(super1, input2).contains(result)); + ASSERT_TRUE(infer(super1, super2).contains(result)); + } + } +} + +// Check the monotonicity, that is, if input1 is a subset of super1, input2 is a subset of super2, +// then infer(input1, input2) must be a subset of infer(super1, super2). This version does the +// check randomly on a number of supersets of input1 and input2. +template +static void test_binary_instance_monotonicity_samples(Inference infer, const InputType& input1, const InputType& input2) { + using S = std::remove_const_t_lo)>; + using U = std::remove_const_t_ulo)>; + auto result = infer(input1, input2); + + // The set that is a superset of all other sets + InputType universe = InputType{std::numeric_limits::min(), std::numeric_limits::max(), U(0), U(-1), {U(0), U(0)}}; + ASSERT_TRUE(infer(universe, input2).contains(result)); + ASSERT_TRUE(infer(input1, universe).contains(result)); + ASSERT_TRUE(infer(universe, universe).contains(result)); + + auto random_superset = [](const InputType& input) { + S lo = MIN2(input->_lo, S(uniform_random())); + S hi = MAX2(input->_hi, S(uniform_random())); + U ulo = MIN2(input->_ulo, uniform_random()); + U uhi = MAX2(input->_uhi, uniform_random()); + U zeros = input->_bits._zeros & uniform_random(); + U ones = input->_bits._ones & uniform_random(); + InputType super = InputType::make(TypeIntPrototype{{lo, hi}, {ulo, uhi}, {zeros, ones}}, 0); + assert(super.contains(input), "impossible"); + return super; + }; + + InputType super1 = random_superset(input1); + InputType super2 = random_superset(input2); + ASSERT_TRUE(infer(super1, input2).contains(result)); + ASSERT_TRUE(infer(input1, super2).contains(result)); + ASSERT_TRUE(infer(super1, super2).contains(result)); +} + +// Verify the correctness and monotonicity of an inference function by exhautively analyzing all +// instances of InputType +template +static void test_binary_exhaustive(Operation op, Inference infer) { + for (const InputType& input1 : all_instances()) { + for (const InputType& input2 : all_instances()) { + test_binary_instance_correctness_exhaustive(op, infer, input1, input2); + if (all_instances().size() < 100) { + // This effectively covers the cases up to uintn_t<2> + test_binary_instance_monotonicity_exhaustive(infer, input1, input2); + } else { + // This effectively covers the cases of uintn_t<3> + test_binary_instance_monotonicity_samples(infer, input1, input2); + } + } + } +} + +// Verify the correctness and monotonicity of an inference function by randomly sampling instances +// of InputType +template +static void test_binary_random(Operation op, Inference infer) { + using S = std::remove_const_t; + using U = std::remove_const_t; + + constexpr size_t sample_count = 100; + InputType samples[sample_count]; + + // Fill with {0} + for (size_t i = 0; i < sample_count; i++) { + samples[i] = InputType::make(TypeIntPrototype{{S(0), S(0)}, {U(0), U(0)}, {U(0), U(0)}}, 0); + } + + // {1} + samples[1] = InputType::make(TypeIntPrototype{{S(1), S(1)}, {U(1), U(1)}, {U(0), U(0)}}, 0); + // {-1} + samples[2] = InputType::make(TypeIntPrototype{{S(-1), S(-1)}, {U(-1), U(-1)}, {U(0), U(0)}}, 0); + // {0, 1} + samples[3] = InputType::make(TypeIntPrototype{{S(0), S(1)}, {U(0), U(1)}, {U(0), U(0)}}, 0); + // {-1, 0, 1} + samples[4] = InputType::make(TypeIntPrototype{{S(-1), S(1)}, {U(0), U(-1)}, {U(0), U(0)}}, 0); + // {-1, 1} + samples[5] = InputType::make(TypeIntPrototype{{S(-1), S(1)}, {U(1), U(-1)}, {U(0), U(0)}}, 0); + // {0, 1, 2} + samples[6] = InputType::make(TypeIntPrototype{{S(0), S(2)}, {U(0), U(2)}, {U(0), U(0)}}, 0); + // {0, 2} + samples[7] = InputType::make(TypeIntPrototype{{S(0), S(2)}, {U(0), U(2)}, {U(1), U(0)}}, 0); + // [min_signed, max_signed] + samples[8] = InputType::make(TypeIntPrototype{{std::numeric_limits::min(), std::numeric_limits::max()}, {U(0), U(-1)}, {U(0), U(0)}}, 0); + // [0, max_signed] + samples[9] = InputType::make(TypeIntPrototype{{S(0), std::numeric_limits::max()}, {U(0), U(-1)}, {U(0), U(0)}}, 0); + // [min_signed, 0) + samples[10] = InputType::make(TypeIntPrototype{{std::numeric_limits::min(), S(-1)}, {U(0), U(-1)}, {U(0), U(0)}}, 0); + + constexpr size_t max_tries = 1000; + constexpr size_t start_random_idx = 11; + for (size_t tries = 0, idx = start_random_idx; tries < max_tries && idx < sample_count; tries++) { + // Try to have lo < hi + S signed_bound1 = S(uniform_random()); + S signed_bound2 = S(uniform_random()); + S lo = MIN2(signed_bound1, signed_bound2); + S hi = MAX2(signed_bound1, signed_bound2); + + // Try to have ulo < uhi + U unsigned_bound1 = uniform_random(); + U unsigned_bound2 = uniform_random(); + U ulo = MIN2(unsigned_bound1, unsigned_bound2); + U uhi = MAX2(unsigned_bound1, unsigned_bound2); + + // Try to have (zeros & ones) == 0 + U zeros = uniform_random(); + U ones = uniform_random(); + U common = zeros & ones; + zeros = zeros ^ common; + ones = ones ^ common; + + TypeIntPrototype t{{lo, hi}, {ulo, uhi}, {zeros, ones}}; + auto canonicalized_t = t.canonicalize_constraints(); + if (canonicalized_t.empty()) { + continue; + } + + samples[idx] = TypeIntMirror{canonicalized_t._data._srange._lo, canonicalized_t._data._srange._hi, + canonicalized_t._data._urange._lo, canonicalized_t._data._urange._hi, + canonicalized_t._data._bits}; + idx++; + } + + for (size_t i = 0; i < sample_count; i++) { + for (size_t j = 0; j < sample_count; j++) { + test_binary_instance_correctness_samples(op, infer, samples[i], samples[j]); + test_binary_instance_monotonicity_samples(infer, samples[i], samples[j]); + } + } +} + +template