*/
+@SuppressWarnings("restricted")
public class BsdDebuggerLocal extends DebuggerBase implements BsdDebugger {
private boolean useGCC32ABI;
private boolean attached;
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java
index 5a91c06e83ea4..5bab3d252d03a 100644
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/linux/LinuxDebuggerLocal.java
@@ -67,6 +67,7 @@ can be fetched. The readJ(Type) routines here will throw a
RuntimeException if they are called before the debugger is
configured with the Java primitive type sizes. */
+@SuppressWarnings("restricted")
public class LinuxDebuggerLocal extends DebuggerBase implements LinuxDebugger {
private boolean useGCC32ABI;
private boolean attached;
diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java
index fa00159f6a86c..f082b7e52c639 100644
--- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java
+++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java
@@ -54,6 +54,7 @@ can be fetched. The readJ(Type) routines here will throw a
RuntimeException if they are called before the debugger is
configured with the Java primitive type sizes. */
+@SuppressWarnings("restricted")
public class WindbgDebuggerLocal extends DebuggerBase implements WindbgDebugger {
private PageCache cache;
private boolean attached;
diff --git a/src/jdk.hotspot.agent/share/native/libsaproc/sadis.c b/src/jdk.hotspot.agent/share/native/libsaproc/sadis.c
index 62f6303c32b68..cf66b7184e3ac 100644
--- a/src/jdk.hotspot.agent/share/native/libsaproc/sadis.c
+++ b/src/jdk.hotspot.agent/share/native/libsaproc/sadis.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,12 +33,6 @@
*/
#ifdef _WINDOWS
-// Disable CRT security warning against _snprintf
-#pragma warning (disable : 4996)
-
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-
#include
#include
#include
diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties
index ecff358ce22c6..6141ce46fe8fc 100644
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/standard.properties
@@ -478,7 +478,8 @@ doclet.usage.author.description=\
Include @author paragraphs
doclet.usage.docfilessubdirs.description=\
- Recursively copy doc-file subdirectories
+ Enables deep copying of 'doc-files' directories. Subdirectories and all\n\
+ contents are recursively copied to the destination
doclet.usage.splitindex.description=\
Split index into one file per letter
@@ -515,7 +516,7 @@ doclet.usage.html5.description=\
doclet.usage.footer.parameters=\
doclet.usage.footer.description=\
- Include footer text for each page
+ This option is no longer supported and reports a warning
doclet.usage.top.parameters=\
@@ -553,7 +554,7 @@ doclet.usage.link-platform-properties.description=\
doclet.usage.excludedocfilessubdir.parameters=\
,,...
doclet.usage.excludedocfilessubdir.description=\
- Exclude any doc-files subdirectories with given name.\n\
+ Exclude any 'doc-files' subdirectories with given name.\n\
':' can also be used anywhere in the argument as a separator.
doclet.usage.group.parameters=\
@@ -614,7 +615,7 @@ doclet.usage.nooverview.description=\
Do not generate overview pages
doclet.usage.serialwarn.description=\
- Generate warning about @serial tag
+ Reports compile-time warnings for missing '@serial' tags
doclet.usage.since.parameters=\
(,)*
@@ -629,7 +630,7 @@ doclet.usage.since-label.description=\
doclet.usage.tag.parameters=\
::
doclet.usage.tag.description=\
- Specify single argument custom tags
+ Specifies a custom tag with a single argument
doclet.usage.taglet.description=\
The fully qualified name of Taglet to register
@@ -654,7 +655,8 @@ doclet.usage.javafx.description=\
doclet.usage.helpfile.parameters=\
doclet.usage.helpfile.description=\
- Include file that help link links to
+ Specifies a file containing the text that will be displayed when the\n\
+ help link in the navigation bar is clicked
doclet.usage.linksource.description=\
Generate source in HTML
@@ -691,7 +693,8 @@ doclet.usage.override-methods.description=\
The default is 'detail'.
doclet.usage.allow-script-in-comments.description=\
- Allow JavaScript in options and comments
+ Allow JavaScript in documentation comments, and options\n\
+ whose value is html-code
doclet.usage.xdocrootparent.parameters=\
diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOptions.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOptions.java
index 17bf628114a67..39d9f2834e183 100644
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOptions.java
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOptions.java
@@ -678,7 +678,7 @@ interface ShowHelper {
/**
* Show command-line help for the extended options, as requested by
- * the {@code --help-extended} option and its aliases.
+ * the {@code --help-extra} option and its aliases.
*/
void Xusage();
diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties
index 7db420e46d587..8178380972509 100644
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties
@@ -67,7 +67,7 @@ main.opt.private.desc=\
main.opt.show.members.arg=\
main.opt.show.members.desc=\
- Specifies which members (fields, methods, etc.) will be\n\
+ Specifies which members (fields, methods, or constructors) will be\n\
documented, where value can be one of "public", "protected",\n\
"package" or "private". The default is "protected", which will\n\
show public and protected members, "public" will show only\n\
@@ -87,7 +87,7 @@ main.opt.show.types.desc=\
main.opt.show.packages.arg=\
main.opt.show.packages.desc=\
- Specifies which module's packages will be documented. Possible\n\
+ Specifies which module packages will be documented. Possible\n\
values are "exported" or "all" packages.
main.opt.show.module.contents.arg=\
@@ -97,7 +97,7 @@ main.opt.show.module.contents.desc=\
declarations. Possible values are "api" or "all".
main.opt.expand.requires.arg=\
-
+ (transitive|all)
main.opt.expand.requires.desc=\
Instructs the tool to expand the set of modules to be\n\
documented. By default, only the modules given explicitly on\n\
diff --git a/src/jdk.jdi/windows/classes/com/sun/tools/jdi/SharedMemoryTransportService.java b/src/jdk.jdi/windows/classes/com/sun/tools/jdi/SharedMemoryTransportService.java
index d16ee6e1dd546..ae3ccf7f14921 100644
--- a/src/jdk.jdi/windows/classes/com/sun/tools/jdi/SharedMemoryTransportService.java
+++ b/src/jdk.jdi/windows/classes/com/sun/tools/jdi/SharedMemoryTransportService.java
@@ -65,6 +65,7 @@ public String toString() {
}
}
+ @SuppressWarnings("restricted")
SharedMemoryTransportService() {
System.loadLibrary("dt_shmem");
initialize();
diff --git a/src/jdk.jdwp.agent/windows/native/libjdwp/linker_md.c b/src/jdk.jdwp.agent/windows/native/libjdwp/linker_md.c
index 97eb1498f5873..a2cc952db815d 100644
--- a/src/jdk.jdwp.agent/windows/native/libjdwp/linker_md.c
+++ b/src/jdk.jdwp.agent/windows/native/libjdwp/linker_md.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -56,7 +56,7 @@ static void dll_build_name(char* buffer, size_t buflen,
path = strtok_s(paths_copy, PATH_SEPARATOR, &next_token);
while (path != NULL) {
- size_t result_len = (size_t)_snprintf(buffer, buflen, "%s\\%s.dll", path, fname);
+ size_t result_len = (size_t) snprintf(buffer, buflen, "%s\\%s.dll", path, fname);
if (result_len >= buflen) {
EXIT_ERROR(JVMTI_ERROR_INVALID_LOCATION, "One or more of the library paths supplied to jdwp, "
"likely by sun.boot.library.path, is too long.");
diff --git a/src/jdk.jdwp.agent/windows/native/libjdwp/util_md.h b/src/jdk.jdwp.agent/windows/native/libjdwp/util_md.h
index 4af5aced1143d..cefb301e09503 100644
--- a/src/jdk.jdwp.agent/windows/native/libjdwp/util_md.h
+++ b/src/jdk.jdwp.agent/windows/native/libjdwp/util_md.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -34,11 +34,6 @@ typedef unsigned long UNSIGNED_JINT;
#define MAXPATHLEN _MAX_PATH
-/* Needed on Windows because names seem to be hidden in stdio.h. */
-
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-
/* On little endian machines, convert java big endian numbers. */
#define HOST_TO_JAVA_CHAR(x) (((x & 0xff) << 8) | ((x >> 8) & (0xff)))
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java
index 05c75a0e48e9b..8f246948710fc 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/Control.java
@@ -141,7 +141,7 @@ public String combine(Set values) {
@Override
public String run() {
try {
- delegate.combine(Collections.unmodifiableSet(values));
+ return delegate.combine(Collections.unmodifiableSet(values));
} catch (Throwable t) {
// Prevent malicious user to propagate exception callback in the wrong context
Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when combining " + values + " for " + getClass());
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/StringPool.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/StringPool.java
index 6513895069e17..c0dc4e6ba5884 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/StringPool.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/StringPool.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,11 +26,12 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
+import jdk.internal.vm.Continuation;
public final class StringPool {
public static final int MIN_LIMIT = 16;
- public static final int MAX_LIMIT = 128; /* 0 MAX means disabled */
-
+ public static final int MAX_LIMIT = 131072; /* 0 MAX means disabled */
+ private static final int PRECACHE_THRESHOLD = 128;
private static final long DO_NOT_POOL = -1;
/* max size */
private static final int MAX_SIZE = 32 * 1024;
@@ -71,33 +72,49 @@ private static long externalSid(long internalSid) {
return internalSid >> 16;
}
- /* synchronized because of writing the string to the JVM. */
- private static synchronized long storeString(String s) {
- Long lsid = cache.get(s);
- long internalSid;
- if (lsid != null) {
- internalSid = lsid.longValue();
- if (isCurrentGeneration(internalSid)) {
- // Someone already updated the cache.
- return externalSid(internalSid);
+ /* Explicitly pin a virtual thread before acquiring the string pool monitor
+ * because migrating the EventWriter onto another carrier thread is impossible.
+ */
+ private static long storeString(String s, boolean pinVirtualThread) {
+ if (pinVirtualThread) {
+ assert(Thread.currentThread().isVirtual());
+ Continuation.pin();
+ }
+ try {
+ /* synchronized because of writing the string to the JVM. */
+ synchronized (StringPool.class) {
+ Long lsid = cache.get(s);
+ long internalSid;
+ if (lsid != null) {
+ internalSid = lsid.longValue();
+ if (isCurrentGeneration(internalSid)) {
+ // Someone already updated the cache.
+ return externalSid(internalSid);
+ }
+ internalSid = updateInternalSid(internalSid);
+ } else {
+ // Not yet added or the cache was cleared.
+ internalSid = nextInternalSid();
+ currentSizeUTF16 += s.length();
+ }
+ long extSid = externalSid(internalSid);
+ // Write the string to the JVM before publishing to the cache.
+ JVM.addStringConstant(extSid, s);
+ cache.put(s, internalSid);
+ return extSid;
+ }
+ } finally {
+ if (pinVirtualThread) {
+ assert(Thread.currentThread().isVirtual());
+ Continuation.unpin();
}
- internalSid = updateInternalSid(internalSid);
- } else {
- // Not yet added or the cache was cleared.
- internalSid = nextInternalSid();
- currentSizeUTF16 += s.length();
}
- long extSid = externalSid(internalSid);
- // Write the string to the JVM before publishing to the cache.
- JVM.addStringConstant(extSid, s);
- cache.put(s, internalSid);
- return extSid;
}
/* a string fetched from the string pool must be of the current generation */
- private static long ensureCurrentGeneration(String s, Long lsid) {
+ private static long ensureCurrentGeneration(String s, Long lsid, boolean pinVirtualThread) {
long internalSid = lsid.longValue();
- return isCurrentGeneration(internalSid) ? externalSid(internalSid) : storeString(s);
+ return isCurrentGeneration(internalSid) ? externalSid(internalSid) : storeString(s, pinVirtualThread);
}
/*
@@ -109,20 +126,20 @@ private static long ensureCurrentGeneration(String s, Long lsid) {
* effectively invalidating the fetched string id. The event restart mechanism
* of the EventWriter ensures that committed strings are in the correct generation.
*/
- public static long addString(String s) {
+ public static long addString(String s, boolean pinVirtualThread) {
Long lsid = cache.get(s);
if (lsid != null) {
- return ensureCurrentGeneration(s, lsid);
+ return ensureCurrentGeneration(s, lsid, pinVirtualThread);
}
- if (!preCache(s)) {
+ if (s.length() <= PRECACHE_THRESHOLD && !preCache(s)) {
/* we should not pool this string */
return DO_NOT_POOL;
}
if (cache.size() > MAX_SIZE || currentSizeUTF16 > MAX_SIZE_UTF16) {
/* pool was full */
- reset();
+ reset(pinVirtualThread);
}
- return storeString(s);
+ return storeString(s, pinVirtualThread);
}
private static boolean preCache(String s) {
@@ -143,8 +160,21 @@ private static boolean preCache(String s) {
return false;
}
- private static synchronized void reset() {
- cache.clear();
- currentSizeUTF16 = 0;
+ private static void reset(boolean pinVirtualThread) {
+ if (pinVirtualThread) {
+ assert(Thread.currentThread().isVirtual());
+ Continuation.pin();
+ }
+ try {
+ synchronized (StringPool.class) {
+ cache.clear();
+ currentSizeUTF16 = 0;
+ }
+ } finally {
+ if (pinVirtualThread) {
+ assert(Thread.currentThread().isVirtual());
+ Continuation.unpin();
+ }
+ }
}
}
diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventWriter.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventWriter.java
index 833fb087e2420..970365ef73dfe 100644
--- a/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventWriter.java
+++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/event/EventWriter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -65,6 +65,7 @@ public final class EventWriter {
private long currentPosition;
private long maxPosition;
private boolean valid;
+ private boolean pinVirtualThread;
boolean excluded;
private PlatformEventType eventType;
@@ -144,7 +145,7 @@ public void putString(String s) {
return;
}
if (length > StringPool.MIN_LIMIT && length < StringPool.MAX_LIMIT) {
- long l = StringPool.addString(s);
+ long l = StringPool.addString(s, pinVirtualThread);
if (l > 0) {
putByte(StringParser.Encoding.CONSTANT_POOL.byteValue());
putLong(l);
@@ -296,11 +297,12 @@ public boolean endEvent() {
return false;
}
- private EventWriter(long startPos, long maxPos, long threadID, boolean valid, boolean excluded) {
+ private EventWriter(long startPos, long maxPos, long threadID, boolean valid, boolean pinVirtualThread, boolean excluded) {
startPosition = currentPosition = startPos;
maxPosition = maxPos;
this.threadID = threadID;
this.valid = valid;
+ this.pinVirtualThread = pinVirtualThread;
this.excluded = excluded;
}
diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ExecutableRebrander.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ExecutableRebrander.java
index 060c94b12cf8a..a297f507da84a 100644
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ExecutableRebrander.java
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ExecutableRebrander.java
@@ -48,7 +48,7 @@
import static jdk.jpackage.internal.StandardBundlerParam.VERSION;
import static jdk.jpackage.internal.WindowsAppImageBuilder.ICON_ICO;
-
+@SuppressWarnings("restricted")
final class ExecutableRebrander {
private static final ResourceBundle I18N = ResourceBundle.getBundle(
"jdk.jpackage.internal.resources.WinResources");
diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java
index c8aae5922873a..fa81b4278b06a 100644
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java
@@ -31,6 +31,7 @@
import java.text.MessageFormat;
import java.util.Map;
+@SuppressWarnings("restricted")
public class WinExeBundler extends AbstractBundler {
static {
diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsRegistry.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsRegistry.java
index a62d9c3b68775..7c4b6092901b4 100644
--- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsRegistry.java
+++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WindowsRegistry.java
@@ -28,6 +28,7 @@
import java.util.ArrayList;
import java.util.List;
+@SuppressWarnings("restricted")
final class WindowsRegistry {
// Currently we only support HKEY_LOCAL_MACHINE. Native implementation will
diff --git a/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java b/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java
index 9582a97cb8f79..a11b580d443d8 100644
--- a/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java
+++ b/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java
@@ -31,7 +31,7 @@
/*
* Linux implementation of jdk.internal.agent.FileSystem
*/
-@SuppressWarnings("removal")
+@SuppressWarnings({"removal", "restricted"})
public class FileSystemImpl extends FileSystem {
public boolean supportsFileSecurity(File f) throws IOException {
diff --git a/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java b/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java
index f0fd31c0f9e52..5a913f9c0aa01 100644
--- a/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java
+++ b/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java
@@ -31,7 +31,7 @@
/*
* Windows implementation of sun.management.FileSystem
*/
-@SuppressWarnings("removal")
+@SuppressWarnings({"removal", "restricted"})
public class FileSystemImpl extends FileSystem {
public boolean supportsFileSecurity(File f) throws IOException {
diff --git a/src/jdk.management/share/classes/com/sun/management/internal/Flag.java b/src/jdk.management/share/classes/com/sun/management/internal/Flag.java
index 6fb2c80247dcc..bf83f40f722c1 100644
--- a/src/jdk.management/share/classes/com/sun/management/internal/Flag.java
+++ b/src/jdk.management/share/classes/com/sun/management/internal/Flag.java
@@ -36,7 +36,7 @@
* corresponds to one VMOption.
*
*/
-@SuppressWarnings("removal")
+@SuppressWarnings({"removal", "restricted"})
class Flag {
private String name;
private Object value;
diff --git a/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java b/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java
index cddb9127d2e9b..cdc5998426d9a 100644
--- a/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java
+++ b/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java
@@ -44,7 +44,7 @@
import sun.management.ManagementFactoryHelper;
import sun.management.spi.PlatformMBeanProvider;
-@SuppressWarnings("removal")
+@SuppressWarnings({"removal", "restricted"})
public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider {
static final String DIAGNOSTIC_COMMAND_MBEAN_NAME =
"com.sun.management:type=DiagnosticCommand";
diff --git a/src/jdk.management/windows/native/libmanagement_ext/OperatingSystemImpl.c b/src/jdk.management/windows/native/libmanagement_ext/OperatingSystemImpl.c
index 746bd97c7ff42..3cfd46791343d 100644
--- a/src/jdk.management/windows/native/libmanagement_ext/OperatingSystemImpl.c
+++ b/src/jdk.management/windows/native/libmanagement_ext/OperatingSystemImpl.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -436,13 +436,13 @@ makeFullCounterPath(const char* const objectName,
return NULL;
}
- _snprintf(fullCounterPath,
- fullCounterPathLen,
- PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
- objectName,
- imageName,
- instance,
- counterName);
+ snprintf(fullCounterPath,
+ fullCounterPathLen,
+ PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
+ objectName,
+ imageName,
+ instance,
+ counterName);
} else {
if (instance) {
/*
@@ -472,18 +472,18 @@ makeFullCounterPath(const char* const objectName,
}
if (instance) {
- _snprintf(fullCounterPath,
- fullCounterPathLen,
- OBJECT_WITH_INSTANCES_COUNTER_FMT,
- objectName,
- instance,
- counterName);
+ snprintf(fullCounterPath,
+ fullCounterPathLen,
+ OBJECT_WITH_INSTANCES_COUNTER_FMT,
+ objectName,
+ instance,
+ counterName);
} else {
- _snprintf(fullCounterPath,
- fullCounterPathLen,
- OBJECT_COUNTER_FMT,
- objectName,
- counterName);
+ snprintf(fullCounterPath,
+ fullCounterPathLen,
+ OBJECT_COUNTER_FMT,
+ objectName,
+ counterName);
}
}
@@ -719,10 +719,10 @@ currentQueryIndexForProcess(void) {
PDH_FMT_COUNTERVALUE counterValue;
PDH_STATUS res;
- _snprintf(fullIDProcessCounterPath,
- MAX_PATH,
- pdhIDProcessCounterFmt,
- index);
+ snprintf(fullIDProcessCounterPath,
+ MAX_PATH,
+ pdhIDProcessCounterFmt,
+ index);
if (addCounter(tmpQuery, fullIDProcessCounterPath, &handleCounter) != 0) {
break;
@@ -1059,13 +1059,13 @@ allocateAndInitializePdhConstants() {
}
/* "\Process(java#%d)\ID Process" */
- _snprintf(pdhIDProcessCounterFmt,
- pdhIDProcessCounterFmtLen,
- PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
- pdhLocalizedProcessObject,
- pdhProcessImageName,
- "%d",
- pdhLocalizedIDProcessCounter);
+ snprintf(pdhIDProcessCounterFmt,
+ pdhIDProcessCounterFmtLen,
+ PROCESS_OBJECT_INSTANCE_COUNTER_FMT,
+ pdhLocalizedProcessObject,
+ pdhProcessImageName,
+ "%d",
+ pdhLocalizedIDProcessCounter);
pdhIDProcessCounterFmt[pdhIDProcessCounterFmtLen] = '\0';
diff --git a/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java b/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java
index 9ace5aa33f2e0..086c346ff8f97 100644
--- a/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java
+++ b/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java
@@ -32,7 +32,7 @@
import jdk.net.ExtendedSocketOptions.PlatformSocketOptions;
import sun.nio.fs.UnixUserPrincipals;
-@SuppressWarnings("removal")
+@SuppressWarnings({"removal", "restricted"})
class AIXSocketOptions extends PlatformSocketOptions {
public AIXSocketOptions() {
diff --git a/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java b/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java
index 20241bc5f334d..8d3ceeebfa9a3 100644
--- a/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java
+++ b/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java
@@ -32,7 +32,7 @@
import jdk.net.ExtendedSocketOptions.PlatformSocketOptions;
import sun.nio.fs.UnixUserPrincipals;
-@SuppressWarnings("removal")
+@SuppressWarnings({"removal", "restricted"})
class LinuxSocketOptions extends PlatformSocketOptions {
public LinuxSocketOptions() {
diff --git a/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java b/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java
index 7ad4bc7650ae7..c2912e8b80808 100644
--- a/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java
+++ b/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java
@@ -32,7 +32,7 @@
import jdk.net.ExtendedSocketOptions.PlatformSocketOptions;
import sun.nio.fs.UnixUserPrincipals;
-@SuppressWarnings("removal")
+@SuppressWarnings({"removal", "restricted"})
class MacOSXSocketOptions extends PlatformSocketOptions {
public MacOSXSocketOptions() {
diff --git a/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java b/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java
index 543d584bfe5a1..f5f69e205176f 100644
--- a/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java
+++ b/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java
@@ -30,7 +30,7 @@
import jdk.net.ExtendedSocketOptions.PlatformSocketOptions;
-@SuppressWarnings("removal")
+@SuppressWarnings({"removal", "restricted"})
class WindowsSocketOptions extends PlatformSocketOptions {
public WindowsSocketOptions() {
diff --git a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java
index 4355605e25815..2e12e67c6c72c 100644
--- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java
+++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java
@@ -1094,7 +1094,7 @@ static native int send0(int fd, long address, int length,
loadSctpLibrary();
}
- @SuppressWarnings("removal")
+ @SuppressWarnings({"removal", "restricted"})
private static void loadSctpLibrary() {
IOUtil.load(); /* loads nio & net native libraries */
AccessController.doPrivileged(
diff --git a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java
index 239e09837f7a9..decf964c6cb72 100644
--- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java
+++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java
@@ -333,7 +333,7 @@ static native void setInitMsgOption0(int fd, int arg1, int arg2)
loadSctpLibrary();
}
- @SuppressWarnings("removal")
+ @SuppressWarnings({"removal", "restricted"})
private static void loadSctpLibrary() {
IOUtil.load(); // loads nio & net native libraries
java.security.AccessController.doPrivileged(
diff --git a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/NTSystem.java b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/NTSystem.java
index 0814f0f733282..677d4aefc8663 100644
--- a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/NTSystem.java
+++ b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/NTSystem.java
@@ -129,7 +129,7 @@ public synchronized long getImpersonationToken() {
return impersonationToken;
}
-
+ @SuppressWarnings("restricted")
private void loadNative() {
System.loadLibrary("jaas");
}
diff --git a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/UnixSystem.java b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/UnixSystem.java
index 96bc1fb32fce4..f3741c1040401 100644
--- a/src/jdk.security.auth/share/classes/com/sun/security/auth/module/UnixSystem.java
+++ b/src/jdk.security.auth/share/classes/com/sun/security/auth/module/UnixSystem.java
@@ -53,6 +53,7 @@ public class UnixSystem {
* Instantiate a {@code UnixSystem} and load
* the native library to access the underlying system information.
*/
+ @SuppressWarnings("restricted")
public UnixSystem() {
System.loadLibrary("jaas");
getUnixInfo();
diff --git a/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp b/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp
index b38586a89753b..06874ee0698e5 100644
--- a/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp
+++ b/test/hotspot/gtest/gc/shared/test_collectorPolicy.cpp
@@ -67,7 +67,7 @@ class TestGenCollectorPolicy {
MinHeapSize = 40 * M;
FLAG_SET_ERGO(InitialHeapSize, 100 * M);
FLAG_SET_ERGO(NewSize, 1 * M);
- FLAG_SET_ERGO(MaxNewSize, 80 * M);
+ FLAG_SET_ERGO(MaxNewSize, 40 * M);
ASSERT_NO_FATAL_FAILURE(setter1->execute());
@@ -159,10 +159,16 @@ class TestGenCollectorPolicy {
// depends on so many other configurable variables. These tests only try to
// verify that there are some basic rules for NewSize honored by the policies.
+// Tests require at least 128M of MaxHeap
+// otherwise ergonomic is different and generation sizes might be changed.
+
// If NewSize has been ergonomically set, the collector policy
// should use it for min but calculate the initial young size
// using NewRatio.
TEST_VM(CollectorPolicy, young_scaled_initial_ergo) {
+ if (MaxHeapSize < 128 * M) {
+ return;
+ }
TestGenCollectorPolicy::SetNewSizeErgo setter(20 * M);
TestGenCollectorPolicy::CheckScaledYoungInitial checker;
@@ -175,6 +181,9 @@ TEST_VM(CollectorPolicy, young_scaled_initial_ergo) {
// the rest of the VM lifetime. This is an irreversible change and
// could impact other tests so we use TEST_OTHER_VM
TEST_OTHER_VM(CollectorPolicy, young_cmd) {
+ if (MaxHeapSize < 128 * M) {
+ return;
+ }
// If NewSize is set on the command line, it should be used
// for both min and initial young size if less than min heap.
TestGenCollectorPolicy::SetNewSizeCmd setter(20 * M);
@@ -187,7 +196,7 @@ TEST_OTHER_VM(CollectorPolicy, young_cmd) {
// If NewSize is set on command line, but is larger than the min
// heap size, it should only be used for initial young size.
- TestGenCollectorPolicy::SetNewSizeCmd setter_large(80 * M);
- TestGenCollectorPolicy::CheckYoungInitial checker_large(80 * M);
+ TestGenCollectorPolicy::SetNewSizeCmd setter_large(40 * M);
+ TestGenCollectorPolicy::CheckYoungInitial checker_large(40 * M);
TestGenCollectorPolicy::TestWrapper::test(&setter_large, &checker_large);
}
diff --git a/test/hotspot/gtest/metaspace/test_metaspace_misc.cpp b/test/hotspot/gtest/metaspace/test_metaspace_misc.cpp
index 6a2282960e6f6..4d0a3e0774f50 100644
--- a/test/hotspot/gtest/metaspace/test_metaspace_misc.cpp
+++ b/test/hotspot/gtest/metaspace/test_metaspace_misc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020 SAP SE. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@@ -67,7 +67,7 @@ TEST_VM(metaspace, misc_max_alloc_size) {
ASSERT_NOT_NULL(p);
}
// And also, successfully deallocate it.
- cld->metaspace_non_null()->deallocate(p, sz, in_class_space);
+ cld->metaspace_non_null()->deallocate(p, sz);
}
}
diff --git a/test/hotspot/jtreg/ProblemList-Xcomp.txt b/test/hotspot/jtreg/ProblemList-Xcomp.txt
index 9d91cad1ddeae..8d6b74c8132b6 100644
--- a/test/hotspot/jtreg/ProblemList-Xcomp.txt
+++ b/test/hotspot/jtreg/ProblemList-Xcomp.txt
@@ -51,3 +51,5 @@ vmTestbase/nsk/jvmti/scenarios/capability/CM03/cm03t001/TestDescription.java 829
vmTestbase/nsk/stress/thread/thread006.java 8321476 linux-all
gc/arguments/TestNewSizeFlags.java 8299116 macosx-aarch64
+
+runtime/interpreter/LastJsrTest.java 8338924 generic-all
diff --git a/test/hotspot/jtreg/compiler/c2/gvn/TestBoolNodeGVN.java b/test/hotspot/jtreg/compiler/c2/gvn/TestBoolNodeGVN.java
new file mode 100644
index 0000000000000..3f2fe7ecf053b
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/c2/gvn/TestBoolNodeGVN.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2024 Red Hat 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.c2.gvn;
+
+import compiler.lib.ir_framework.*;
+
+import java.util.Random;
+
+/**
+ * @test
+ * @bug 8327381
+ * @summary Refactor boolean node tautology transformations
+ * @library /test/lib /
+ * @run driver compiler.c2.gvn.TestBoolNodeGVN
+ */
+public class TestBoolNodeGVN {
+ public static void main(String[] args) {
+ TestFramework.run();
+ testCorrectness();
+ }
+
+ /**
+ * Test changing ((x & m) u<= m) or ((m & x) u<= m) to always true, same with ((x & m) u< m+1) and ((m & x) u< m+1)
+ * The test is only applicable to x64, aarch64 and riscv64 for having Integer.compareUnsigned
+ * intrinsified.
+ */
+ @Test
+ @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
+ @IR(failOn = IRNode.CMP_U,
+ phase = CompilePhase.AFTER_PARSING,
+ applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
+ public static boolean testShouldReplaceCpmUCase1(int x, int m) {
+ return !(Integer.compareUnsigned((x & m), m) > 0); // assert in inversions to generates the pattern looking for
+ }
+ @Test
+ @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
+ @IR(failOn = IRNode.CMP_U,
+ phase = CompilePhase.AFTER_PARSING,
+ applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
+ public static boolean testShouldReplaceCpmUCase2(int x, int m) {
+ return !(Integer.compareUnsigned((m & x), m) > 0);
+ }
+
+ @Test
+ @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
+ @IR(failOn = IRNode.CMP_U,
+ phase = CompilePhase.AFTER_PARSING,
+ applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
+ public static boolean testShouldReplaceCpmUCase3(int x, int m) {
+ return Integer.compareUnsigned((x & m), m + 1) < 0;
+ }
+
+ @Test
+ @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
+ @IR(failOn = IRNode.CMP_U,
+ phase = CompilePhase.AFTER_PARSING,
+ applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
+ public static boolean testShouldReplaceCpmUCase4(int x, int m) {
+ return Integer.compareUnsigned((m & x), m + 1) < 0;
+ }
+
+ @Test
+ @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
+ @IR(counts = {IRNode.CMP_U, "1"},
+ phase = CompilePhase.AFTER_PARSING,
+ applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
+ public static boolean testShouldHaveCpmUCase1(int x, int m) {
+ return !(Integer.compareUnsigned((x & m), m - 1) > 0);
+ }
+
+ @Test
+ @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
+ @IR(counts = {IRNode.CMP_U, "1"},
+ phase = CompilePhase.AFTER_PARSING,
+ applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
+ public static boolean testShouldHaveCpmUCase2(int x, int m) {
+ return !(Integer.compareUnsigned((m & x), m - 1) > 0);
+ }
+
+ @Test
+ @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
+ @IR(counts = {IRNode.CMP_U, "1"},
+ phase = CompilePhase.AFTER_PARSING,
+ applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
+ public static boolean testShouldHaveCpmUCase3(int x, int m) {
+ return Integer.compareUnsigned((x & m), m + 2) < 0;
+ }
+
+ @Test
+ @Arguments(values = {Argument.DEFAULT, Argument.DEFAULT})
+ @IR(counts = {IRNode.CMP_U, "1"},
+ phase = CompilePhase.AFTER_PARSING,
+ applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"})
+ public static boolean testShouldHaveCpmUCase4(int x, int m) {
+ return Integer.compareUnsigned((m & x), m + 2) < 0;
+ }
+
+ private static void testCorrectness() {
+ int[] values = {
+ 0, 1, 5, 8, 16, 42, 100, new Random().nextInt(0, Integer.MAX_VALUE), Integer.MAX_VALUE
+ };
+
+ for (int x : values) {
+ for (int m : values) {
+ if (!testShouldReplaceCpmUCase1(x, m) |
+ !testShouldReplaceCpmUCase2(x, m) |
+ !testShouldReplaceCpmUCase3(x, m) |
+ !testShouldReplaceCpmUCase4(x, m)) {
+ throw new RuntimeException("Bad result for x = " + x + " and m = " + m + ", expected always true");
+ }
+ }
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/compiler/c2/irTests/scalarReplacement/ScalarReplacementWithGCBarrierTests.java b/test/hotspot/jtreg/compiler/c2/irTests/scalarReplacement/ScalarReplacementWithGCBarrierTests.java
new file mode 100644
index 0000000000000..fbf5cdd61cc03
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/c2/irTests/scalarReplacement/ScalarReplacementWithGCBarrierTests.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2024 Alibaba Group Holding Limited. 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.c2.irTests.scalarReplacement;
+
+import compiler.lib.ir_framework.*;
+
+/*
+ * @test
+ * @bug 8333334
+ * @summary Tests that dead barrier control flows do not affect the scalar replacement.
+ * @library /test/lib /
+ * @requires vm.compiler2.enabled
+ * @requires vm.gc.G1
+ * @run driver compiler.c2.irTests.scalarReplacement.ScalarReplacementWithGCBarrierTests
+ */
+public class ScalarReplacementWithGCBarrierTests {
+ static class List {
+ public Node head;
+
+ public void push(int value) {
+ Node n = new Node();
+ n.value = value;
+ n.next = head;
+ head = n;
+ }
+
+ @ForceInline
+ public Iter iter() {
+ Iter iter = new Iter();
+ iter.list = this;
+ iter.n = head;
+ iter.sum = 0;
+ return iter;
+ }
+ }
+
+ static class Node {
+ public int value;
+ public Node next;
+ }
+
+ static class Iter {
+ public List list;
+ public Node n;
+ public Integer sum;
+
+ @ForceInline
+ public boolean next() {
+ int lastSum = sum;
+ while (sum - lastSum < 1000) {
+ while (n != null && n.value < 30) n = n.next;
+ if (n == null) return false;
+ sum += n.value;
+ n = n.next;
+ }
+ return true;
+ }
+ }
+
+ private static final int SIZE = 1000;
+
+ public static void main(String[] args) {
+ // Must use G1 GC to ensure there is a pre-barrier
+ // before the first field write.
+ TestFramework.runWithFlags("-XX:+UseG1GC");
+ }
+
+ @Run(test = "testScalarReplacementWithGCBarrier")
+ private void runner() {
+ List list = new List();
+ for (int i = 0; i < SIZE; i++) {
+ list.push(i);
+ }
+ testScalarReplacementWithGCBarrier(list);
+ }
+
+ // Allocation of `Iter iter` should be eliminated by scalar replacement, and
+ // the allocation of `Integer sum` can not be eliminated, so there should be
+ // 1 allocation after allocations and locks elimination.
+ //
+ // Before the patch of JDK-8333334, both allocations of `Iter` and `Integer`
+ // could not be eliminated.
+ @Test
+ @IR(phase = { CompilePhase.AFTER_PARSING }, counts = { IRNode.ALLOC, "1" })
+ @IR(phase = { CompilePhase.INCREMENTAL_BOXING_INLINE }, counts = { IRNode.ALLOC, "2" })
+ @IR(phase = { CompilePhase.ITER_GVN_AFTER_ELIMINATION }, counts = { IRNode.ALLOC, "1" })
+ private int testScalarReplacementWithGCBarrier(List list) {
+ Iter iter = list.iter();
+ while (true) {
+ while (iter.next()) {}
+ if (list.head == null) break;
+ list.head = list.head.next;
+ iter.n = list.head;
+ }
+ return iter.sum;
+ }
+}
diff --git a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
index 9fe3f42f61afb..7055e001118dc 100644
--- a/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
+++ b/test/hotspot/jtreg/compiler/lib/ir_framework/IRNode.java
@@ -445,7 +445,7 @@ public class IRNode {
public static final String CMP_U = PREFIX + "CMP_U" + POSTFIX;
static {
- beforeMatchingNameRegex(CMP_U, "CmpU");
+ beforeMatchingNameRegex(CMP_U, "CmpU\\b");
}
public static final String CMP_U3 = PREFIX + "CMP_U3" + POSTFIX;
diff --git a/test/hotspot/jtreg/compiler/loopopts/TestSunkNodeInInfiniteLoop.java b/test/hotspot/jtreg/compiler/loopopts/TestSunkNodeInInfiniteLoop.java
new file mode 100644
index 0000000000000..7ab05cca242d6
--- /dev/null
+++ b/test/hotspot/jtreg/compiler/loopopts/TestSunkNodeInInfiniteLoop.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8336830
+ * @summary C2: assert(get_loop(lca)->_nest < n_loop->_nest || lca->in(0)->is_NeverBranch()) failed: must not be moved into inner loop
+ * @library /test/lib
+ * @run main/othervm -XX:CompileCommand=compileonly,TestSunkNodeInInfiniteLoop::* -Xcomp TestSunkNodeInInfiniteLoop
+ *
+ */
+
+import jdk.test.lib.Utils;
+
+public class TestSunkNodeInInfiniteLoop {
+ public static void main(String[] args) throws InterruptedException {
+ byte[] a = new byte[1];
+ Thread thread = new Thread(() -> test(a));
+ thread.setDaemon(true);
+ thread.start();
+ Thread.sleep(Utils.adjustTimeout(4000));
+ }
+
+ static void test(byte[] a) {
+ // L0:
+ while(true) {
+ int i1 = a.length;
+ // L3:
+ while(true) {
+ int i2 = 0;
+ if ((i1--) <= 0) { break; /* ifle L0 */}
+ a[i2++] = -1;
+ // goto L3
+ }
+ }
+ }
+}
diff --git a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java
index 4e6252ae20510..96bc22dfb1d05 100644
--- a/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java
+++ b/test/hotspot/jtreg/runtime/CommandLine/VMDeprecatedOptions.java
@@ -70,6 +70,9 @@ public class VMDeprecatedOptions {
})
);
}
+ if (Platform.isLinux()) {
+ deprecated.add(new String[] { "UseLinuxPosixThreadCPUClocks", "true" });
+ }
if (wb.isJFRIncluded()) {
deprecated.add(new String[] {"FlightRecorder", "false"});
}
diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java b/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java
index 3f759d13a4ca9..691c87fef360c 100644
--- a/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java
+++ b/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java
@@ -116,8 +116,9 @@ static void test(boolean dumpWithParallel, boolean execWithParallel, boolean use
} else {
String pattern = "((Too small maximum heap)" +
"|(GC triggered before VM initialization completed)" +
- "|(java.lang.OutOfMemoryError: Java heap space)" +
- "|(Initial heap size set to a larger value than the maximum heap size))";
+ "|(Initial heap size set to a larger value than the maximum heap size)" +
+ "|(java.lang.OutOfMemoryError)" +
+ "|(Error: A JNI error has occurred, please check your installation and try again))";
out.shouldMatch(pattern);
out.shouldNotHaveFatalError();
}
diff --git a/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/NoClassDefFoundErrorTest.java b/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/NoClassDefFoundErrorTest.java
index d369f77f32433..b03d627485014 100644
--- a/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/NoClassDefFoundErrorTest.java
+++ b/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/NoClassDefFoundErrorTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,12 @@
/*
* @test
- * @bug 8056900
+ * @bug 8056900 8338888
* @summary Verifies message returned with NoClassDefFoundError exception.
* @library /test/lib
* @modules java.base/jdk.internal.misc
* java.compiler
- * @run main/native NoClassDefFoundErrorTest
+ * @run main/native/othervm -Xlog:exceptions=info NoClassDefFoundErrorTest
*/
import jdk.test.lib.compiler.InMemoryJavaCompiler;
@@ -36,8 +36,14 @@
public class NoClassDefFoundErrorTest {
+ // Use the specified name
static native void callDefineClass(String className);
static native void callFindClass(String className);
+ // Use a name longer than a Java string - returns false
+ // if native allocation failed.
+ static native boolean tryCallDefineClass();
+ static native boolean tryCallFindClass();
+
static {
System.loadLibrary("NoClassDefFoundErrorTest");
}
@@ -54,7 +60,7 @@ public static void main(String args[]) throws Exception {
tooBigClassName = tooBigClassName.append(tooBigClassName);
}
- // Test JVM_DefineClass() with long name.
+ System.out.println("Test JVM_DefineClass() with long name");
try {
unsafe.defineClass(tooBigClassName.toString(), klassbuf, 4, klassbuf.length - 4, null, null);
throw new RuntimeException("defineClass did not throw expected NoClassDefFoundError");
@@ -64,7 +70,7 @@ public static void main(String args[]) throws Exception {
}
}
- // Test JNI_DefineClass() with long name.
+ System.out.println("Test JNI_DefineClass() with long name");
try {
callDefineClass(tooBigClassName.toString());
throw new RuntimeException("DefineClass did not throw expected NoClassDefFoundError");
@@ -74,17 +80,17 @@ public static void main(String args[]) throws Exception {
}
}
- // Test JNI_FindClass() with long name.
+ System.out.println("Test JNI_FindClass() with long name");
try {
callFindClass(tooBigClassName.toString());
- throw new RuntimeException("DefineClass did not throw expected NoClassDefFoundError");
+ throw new RuntimeException("FindClass did not throw expected NoClassDefFoundError");
} catch (NoClassDefFoundError e) {
if (!e.getMessage().contains("Class name exceeds maximum length of ")) {
throw new RuntimeException("Wrong NoClassDefFoundError: " + e.getMessage());
}
}
- // Test JNI_FindClass() with null name.
+ System.out.println("Test JNI_FindClass() with null name");
try {
callFindClass(null);
throw new RuntimeException("FindClass did not throw expected NoClassDefFoundError");
@@ -93,5 +99,31 @@ public static void main(String args[]) throws Exception {
throw new RuntimeException("Wrong NoClassDefFoundError: " + e.getMessage());
}
}
+
+ System.out.println("Test JNI_DefineClass() with giant name");
+ try {
+ if (tryCallDefineClass()) {
+ throw new RuntimeException("DefineClass did not throw expected NoClassDefFoundError");
+ } else {
+ System.out.println("Test skipped due to native allocation failure");
+ }
+ } catch (NoClassDefFoundError e) {
+ if (!e.getMessage().contains("Class name exceeds maximum length of ")) {
+ throw new RuntimeException("Wrong NoClassDefFoundError: " + e.getMessage());
+ }
+ }
+
+ System.out.println("Test JNI_FindClass() with giant name");
+ try {
+ if (tryCallFindClass()) {
+ throw new RuntimeException("FindClass did not throw expected NoClassDefFoundError");
+ } else {
+ System.out.println("Test skipped due to native allocation failure");
+ }
+ } catch (NoClassDefFoundError e) {
+ if (!e.getMessage().contains("Class name exceeds maximum length of ")) {
+ throw new RuntimeException("Wrong NoClassDefFoundError: " + e.getMessage());
+ }
+ }
}
}
diff --git a/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c b/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c
index 607d2541a8994..023f299a5d404 100644
--- a/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c
+++ b/test/hotspot/jtreg/runtime/exceptionMsgs/NoClassDefFoundError/libNoClassDefFoundErrorTest.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,10 @@
*/
#include
+#include
+#include
+#include
+
JNIEXPORT void JNICALL
Java_NoClassDefFoundErrorTest_callDefineClass(JNIEnv *env, jclass klass, jstring className) {
@@ -42,3 +46,34 @@ Java_NoClassDefFoundErrorTest_callFindClass(JNIEnv *env, jclass klass, jstring c
}
+static char* giant_string() {
+ size_t len = ((size_t)INT_MAX) + 3;
+ char* c_name = malloc(len * sizeof(char));
+ if (c_name != NULL) {
+ memset(c_name, 'Y', len - 1);
+ c_name[len - 1] = '\0';
+ }
+ return c_name;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_NoClassDefFoundErrorTest_tryCallDefineClass(JNIEnv *env, jclass klass) {
+ char* c_name = giant_string();
+ if (c_name != NULL) {
+ (*env)->DefineClass(env, c_name, NULL, NULL, 0);
+ free(c_name);
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
+}
+
+JNIEXPORT jboolean JNICALL
+Java_NoClassDefFoundErrorTest_tryCallFindClass(JNIEnv *env, jclass klass) {
+ char* c_name = giant_string();
+ if (c_name != NULL) {
+ jclass cls = (*env)->FindClass(env, c_name);
+ free(c_name);
+ return JNI_TRUE;
+ }
+ return JNI_FALSE;
+}
diff --git a/test/hotspot/jtreg/runtime/interpreter/LastJsr.jasm b/test/hotspot/jtreg/runtime/interpreter/LastJsr.jasm
new file mode 100644
index 0000000000000..4f53cbc18ad7b
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/interpreter/LastJsr.jasm
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+super public class LastJsr
+{
+ public static Method test:"()V"
+ stack 100 locals 100
+ {
+ return;
+ LABEL:
+ nop;
+ jsr LABEL; // bci=2. Compute bci + length(jsr) -> bci = 5 accessed, out of bounds.
+ }
+}
diff --git a/test/hotspot/jtreg/runtime/interpreter/LastJsrReachable.jasm b/test/hotspot/jtreg/runtime/interpreter/LastJsrReachable.jasm
new file mode 100644
index 0000000000000..5bcc3ffd382a8
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/interpreter/LastJsrReachable.jasm
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+super public class LastJsrReachable
+{
+ public static Method test:"()V"
+ stack 100 locals 100
+ {
+ goto LB2;
+ LABEL:
+ return;
+ LB2:
+ nop;
+ jsr LABEL;
+ }
+}
diff --git a/test/hotspot/jtreg/runtime/interpreter/LastJsrTest.java b/test/hotspot/jtreg/runtime/interpreter/LastJsrTest.java
new file mode 100644
index 0000000000000..913a304ae38a3
--- /dev/null
+++ b/test/hotspot/jtreg/runtime/interpreter/LastJsrTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8335664
+ * @summary Ensure a program that ends with a JSR does not crash
+ * @library /test/lib
+ * @compile LastJsr.jasm
+ * @compile LastJsrReachable.jasm
+ * @run main/othervm LastJsrTest
+ */
+
+public class LastJsrTest {
+ public static void main(String[] args) {
+ LastJsr.test();
+ LastJsrReachable.test();
+ System.out.println("PASSED");
+ }
+}
diff --git a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java
index 6bc09b8a03451..07e46a1dfcac0 100644
--- a/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java
+++ b/test/hotspot/jtreg/runtime/jni/checked/TestCheckedReleaseArrayElements.java
@@ -49,6 +49,7 @@ public static void main(String[] args) throws Throwable {
// that might generate output on stderr (which should be empty for this test).
ProcessBuilder pb =
ProcessTools.createLimitedTestJavaProcessBuilder("-Xcheck:jni",
+ "--enable-native-access=ALL-UNNAMED",
"-Djava.library.path=" + Utils.TEST_NATIVE_PATH,
"TestCheckedReleaseArrayElements");
OutputAnalyzer output = ProcessTools.executeProcess(pb);
diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt
index bbf594f3bc70b..697fe82187ca3 100644
--- a/test/jdk/ProblemList.txt
+++ b/test/jdk/ProblemList.txt
@@ -375,7 +375,7 @@ java/awt/Modal/MultipleDialogs/MultipleDialogs3Test.java 8198665 macosx-all
java/awt/Modal/MultipleDialogs/MultipleDialogs4Test.java 8198665 macosx-all
java/awt/Modal/MultipleDialogs/MultipleDialogs5Test.java 8198665 macosx-all
java/awt/Mouse/EnterExitEvents/DragWindowOutOfFrameTest.java 8177326 macosx-all
-java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java 8005021,8332158 macosx-all,linux-x64
+java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java 8005021 macosx-all
java/awt/Mouse/EnterExitEvents/FullscreenEnterEventTest.java 8051455 macosx-all
java/awt/Mouse/MouseModifiersUnitTest/MouseModifiersUnitTest_Standard.java 7124407,8302787 macosx-all,windows-all
java/awt/Mouse/RemovedComponentMouseListener/RemovedComponentMouseListener.java 8157170 macosx-all
diff --git a/test/jdk/java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java b/test/jdk/java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java
index 51e5dd353a98d..2918a6a5e0a89 100644
--- a/test/jdk/java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java
+++ b/test/jdk/java/awt/Mouse/EnterExitEvents/ResizingFrameTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,12 +27,19 @@
* @bug 7154048
* @summary Programmatically resized window does not receive mouse entered/exited events
* @author alexandr.scherbatiy area=awt.event
+ * @library /test/lib
+ * @build jdk.test.lib.Platform
* @run main ResizingFrameTest
*/
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
+import java.awt.Frame;
+import java.awt.Robot;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import jdk.test.lib.Platform;
public class ResizingFrameTest {
@@ -41,6 +48,9 @@ public class ResizingFrameTest {
private static JFrame frame;
public static void main(String[] args) throws Exception {
+ if (Platform.isOnWayland()) {
+ return;
+ }
Robot robot = new Robot();
robot.setAutoDelay(50);
diff --git a/test/jdk/java/foreign/TestDereferencePath.java b/test/jdk/java/foreign/TestDereferencePath.java
index 1b26cce9c6fcf..116f2d318fc6f 100644
--- a/test/jdk/java/foreign/TestDereferencePath.java
+++ b/test/jdk/java/foreign/TestDereferencePath.java
@@ -119,6 +119,30 @@ public void testMulti() {
}
}
+ static final MemoryLayout A_VALUE = MemoryLayout.structLayout(
+ ValueLayout.ADDRESS.withName("b")
+ .withTargetLayout(ValueLayout.JAVA_INT)
+ );
+
+ static final VarHandle a_value = A_VALUE.varHandle(
+ PathElement.groupElement("b"), PathElement.dereferenceElement());
+
+ @Test
+ public void testDerefValue() {
+ try (Arena arena = Arena.ofConfined()) {
+ // init structs
+ MemorySegment a = arena.allocate(A);
+ MemorySegment b = arena.allocate(ValueLayout.JAVA_INT);
+ // init struct fields
+ a.set(ValueLayout.ADDRESS, 0, b);
+ b.set(ValueLayout.JAVA_INT, 0, 42);
+ // dereference
+ int val = (int) a_value.get(a, 0L);
+ assertEquals(val, 42);
+ }
+ }
+
+
@Test(expectedExceptions = IllegalArgumentException.class)
void testBadDerefInSelect() {
A.select(PathElement.groupElement("b"), PathElement.dereferenceElement());
diff --git a/test/jdk/java/foreign/TestLayoutPaths.java b/test/jdk/java/foreign/TestLayoutPaths.java
index 414eb4117ced7..6729fbf823682 100644
--- a/test/jdk/java/foreign/TestLayoutPaths.java
+++ b/test/jdk/java/foreign/TestLayoutPaths.java
@@ -332,6 +332,14 @@ public void testOffsetHandleOOBIndex(MemoryLayout layout, PathElement[] pathElem
}
}
+ @Test(dataProvider = "testLayouts", expectedExceptions = ArithmeticException.class)
+ public void testOffsetHandleOverflow(MemoryLayout layout, PathElement[] pathElements, long[] indexes,
+ long expectedByteOffset) throws Throwable {
+ MethodHandle byteOffsetHandle = layout.byteOffsetHandle(pathElements);
+ byteOffsetHandle = byteOffsetHandle.asSpreader(long[].class, indexes.length);
+ byteOffsetHandle.invoke(Long.MAX_VALUE, indexes);
+ }
+
@Test(dataProvider = "testLayouts")
public void testVarHandleBadSegment(MemoryLayout layout, PathElement[] pathElements, long[] indexes,
long expectedByteOffset) throws Throwable {
diff --git a/test/jdk/java/foreign/TestRestricted.java b/test/jdk/java/foreign/TestRestricted.java
index beccd89582978..b5b0974e57ab2 100644
--- a/test/jdk/java/foreign/TestRestricted.java
+++ b/test/jdk/java/foreign/TestRestricted.java
@@ -88,7 +88,11 @@ static RestrictedMethod of(Class> owner, String name, Class> returnType, Cla
RestrictedMethod.of(MemorySegment.class, "reinterpret", MemorySegment.class, Arena.class, Consumer.class),
RestrictedMethod.of(MemorySegment.class, "reinterpret", MemorySegment.class, long.class, Arena.class, Consumer.class),
RestrictedMethod.of(AddressLayout.class, "withTargetLayout", AddressLayout.class, MemoryLayout.class),
- RestrictedMethod.of(ModuleLayer.Controller.class, "enableNativeAccess", ModuleLayer.Controller.class, Module.class)
+ RestrictedMethod.of(ModuleLayer.Controller.class, "enableNativeAccess", ModuleLayer.Controller.class, Module.class),
+ RestrictedMethod.of(System.class, "load", void.class, String.class),
+ RestrictedMethod.of(System.class, "loadLibrary", void.class, String.class),
+ RestrictedMethod.of(Runtime.class, "load", void.class, String.class),
+ RestrictedMethod.of(Runtime.class, "loadLibrary", void.class, String.class)
);
@Test
diff --git a/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccess.java b/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccess.java
index 9dd228f5152b6..230b32968da0a 100644
--- a/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccess.java
+++ b/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccess.java
@@ -28,6 +28,10 @@
* @library /test/lib
* @build TestEnableNativeAccess
* panama_module/*
+ * panama_jni_load_module/*
+ * panama_jni_def_module/*
+ * panama_jni_use_module/*
+ *
* org.openjdk.foreigntest.unnamed.PanamaMainUnnamedModule
* @run testng/othervm/timeout=180 TestEnableNativeAccess
* @summary Basic test for java --enable-native-access
@@ -62,20 +66,25 @@ public Object[][] succeedCases() {
{ "panama_enable_native_access", PANAMA_MAIN, successNoWarning(), new String[]{"--enable-native-access=panama_module"} },
{ "panama_enable_native_access_reflection", PANAMA_REFLECTION, successNoWarning(), new String[]{"--enable-native-access=panama_module"} },
{ "panama_enable_native_access_invoke", PANAMA_INVOKE, successNoWarning(), new String[]{"--enable-native-access=panama_module"} },
- { "panama_enable_native_access_jni", PANAMA_JNI, successNoWarning(), new String[]{"--enable-native-access=ALL-UNNAMED"} },
{ "panama_comma_separated_enable", PANAMA_MAIN, successNoWarning(), new String[]{"--enable-native-access=java.base,panama_module"} },
{ "panama_comma_separated_enable_reflection", PANAMA_REFLECTION, successNoWarning(), new String[]{"--enable-native-access=java.base,panama_module"} },
{ "panama_comma_separated_enable_invoke", PANAMA_INVOKE, successNoWarning(), new String[]{"--enable-native-access=java.base,panama_module"} },
- { "panama_comma_separated_enable_jni", PANAMA_JNI, successNoWarning(), new String[]{"--enable-native-access=java.base,ALL-UNNAMED"} },
+ { "panama_comma_separated_enable_jni", PANAMA_JNI, successNoWarning(), new String[]{"--enable-native-access=panama_jni_load_module,panama_jni_def_module,ALL-UNNAMED"} },
{ "panama_enable_native_access_warn", PANAMA_MAIN, successWithWarning("panama"), new String[]{} },
{ "panama_enable_native_access_warn_reflection", PANAMA_REFLECTION, successWithWarning("panama"), new String[]{} },
{ "panama_enable_native_access_warn_invoke", PANAMA_INVOKE, successWithWarning("panama"), new String[]{} },
- { "panama_enable_native_access_warn_jni", PANAMA_JNI, successWithWarning("ALL-UNNAMED"), new String[]{} },
+ { "panama_enable_native_access_warn_jni", PANAMA_JNI, successWithWarnings("panama_jni_load_module", "panama_jni_def_module", "ALL-UNNAMED"), new String[]{} },
+
+ { "panama_enable_native_access_allow", PANAMA_MAIN, successNoWarning(), new String[]{"--illegal-native-access=allow"} },
+ { "panama_enable_native_access_allow_reflection", PANAMA_REFLECTION, successNoWarning(), new String[]{"--illegal-native-access=allow"} },
+ { "panama_enable_native_access_allow_invoke", PANAMA_INVOKE, successNoWarning(), new String[]{"--illegal-native-access=allow"} },
+ { "panama_enable_native_access_allow_jni", PANAMA_JNI, successNoWarning(), new String[]{"--illegal-native-access=allow"} },
{ "panama_no_unnamed_module_native_access", UNNAMED, successWithWarning("ALL-UNNAMED"), new String[]{} },
{ "panama_all_unnamed_module_native_access", UNNAMED, successNoWarning(), new String[]{"--enable-native-access=ALL-UNNAMED"} },
+ { "panama_allow_unnamed_module_native_access", UNNAMED, successNoWarning(), new String[]{"--illegal-native-access=allow"} },
};
}
@@ -131,12 +140,38 @@ public void testRepeatedOption() throws Exception {
* Specifies bad value to --enable-native-access.
*/
public void testBadValue() throws Exception {
- run("panama_enable_native_access_warn_unknown_module", PANAMA_MAIN,
+ run("panama_deny_bad_unknown_module", PANAMA_MAIN,
failWithWarning("WARNING: Unknown module: BAD specified to --enable-native-access"),
- "--enable-native-access=BAD");
- run("panama_no_all_module_path_blanket_native_access", PANAMA_MAIN,
+ "--illegal-native-access=deny", "--enable-native-access=BAD");
+ run("panama_deny_bad_all_module_path_module", PANAMA_MAIN,
failWithWarning("WARNING: Unknown module: ALL-MODULE-PATH specified to --enable-native-access"),
- "--enable-native-access=ALL-MODULE-PATH" );
+ "--illegal-native-access=deny", "--enable-native-access=ALL-MODULE-PATH" );
+ run("panama_deny_no_module_main", PANAMA_MAIN,
+ failWithError("module panama_module"),
+ "--illegal-native-access=deny");
+ run("panama_deny_no_module_invoke", PANAMA_INVOKE,
+ failWithError("module panama_module"),
+ "--illegal-native-access=deny");
+ run("panama_deny_no_module_reflection", PANAMA_REFLECTION,
+ failWithError("module panama_module"),
+ "--illegal-native-access=deny");
+ run("panama_deny_no_module_jni", PANAMA_JNI,
+ failWithError("module panama_jni_load_module"),
+ "--illegal-native-access=deny");
+ }
+
+ public void testDetailedWarningMessage() throws Exception {
+ run("panama_enable_native_access_warn_jni", PANAMA_JNI,
+ success()
+ // call to System::loadLibrary from panama_jni_load_module
+ .expect("WARNING: A restricted method in java.lang.System has been called")
+ .expect("WARNING: java.lang.System::loadLibrary has been called by org.openjdk.jni.PanamaMainJNI in module panama_jni_load_module")
+ // JNI native method binding in panama_jni_def_module
+ .expect("WARNING: A native method in org.openjdk.jni.def.PanamaJNIDef has been bound")
+ .expect("WARNING: org.openjdk.jni.def.PanamaJNIDef::nativeLinker0 is declared in module panama_jni_def_module")
+ // upcall to Linker::downcallHandle from JNI code
+ .expect("WARNING: A restricted method in java.lang.foreign.Linker has been called")
+ .expect("WARNING: java.lang.foreign.Linker::downcallHandle has been called by code in an unnamed module"));
}
private int count(Iterable lines, CharSequence cs) {
diff --git a/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessBase.java b/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessBase.java
index b5afb727997ba..5f02e7cc4ace7 100644
--- a/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessBase.java
+++ b/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessBase.java
@@ -38,8 +38,8 @@ public class TestEnableNativeAccessBase {
static final String PANAMA_REFLECTION = "panama_module/" + PANAMA_REFLECTION_CLS;
static final String PANAMA_INVOKE_CLS = "org.openjdk.foreigntest.PanamaMainInvoke";
static final String PANAMA_INVOKE = "panama_module/" + PANAMA_INVOKE_CLS;
- static final String PANAMA_JNI_CLS = "org.openjdk.foreigntest.PanamaMainJNI";
- static final String PANAMA_JNI = "panama_module/" + PANAMA_JNI_CLS;
+ static final String PANAMA_JNI_CLS = "org.openjdk.jni.PanamaMainJNI";
+ static final String PANAMA_JNI = "panama_jni_load_module/" + PANAMA_JNI_CLS;
static final String UNNAMED = "org.openjdk.foreigntest.unnamed.PanamaMainUnnamedModule";
/**
@@ -99,6 +99,14 @@ static Result successWithWarning(String moduleName) {
return success().expect("WARNING").expect("--enable-native-access=" + moduleName);
}
+ static Result successWithWarnings(String... moduleNames) {
+ Result result = success();
+ for (String moduleName : moduleNames) {
+ result = result.expect("WARNING").expect("--enable-native-access=" + moduleName);
+ }
+ return result;
+ }
+
static Result failWithWarning(String expectedOutput) {
return new Result(false).expect(expectedOutput).expect("WARNING");
}
diff --git a/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessDynamic.java b/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessDynamic.java
index fa09b0eb41454..f0a8d463a7fc0 100644
--- a/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessDynamic.java
+++ b/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessDynamic.java
@@ -56,7 +56,7 @@ public Object[][] succeedCases() {
@DataProvider(name = "failureCases")
public Object[][] failureCases() {
- String errMsg = "Illegal native access from: module panama_module";
+ String errMsg = "Illegal native access from module panama_module";
return new Object[][] {
{ "panama_enable_native_access_fail", PANAMA_MAIN, failWithError(errMsg) },
{ "panama_enable_native_access_fail_reflection", PANAMA_REFLECTION, failWithError(errMsg) },
@@ -73,6 +73,7 @@ OutputAnalyzer run(String action, String moduleAndCls, boolean enableNativeAcces
Result expectedResult, boolean panamaModuleInBootLayer) throws Exception
{
List list = new ArrayList<>();
+ list.add("--illegal-native-access=deny");
if (panamaModuleInBootLayer) {
list.addAll(List.of("-p", MODULE_PATH));
list.add("--add-modules=panama_module");
diff --git a/test/jdk/java/foreign/enablenativeaccess/panama_jni_def_module/module-info.java b/test/jdk/java/foreign/enablenativeaccess/panama_jni_def_module/module-info.java
new file mode 100644
index 0000000000000..85c00ce5daec3
--- /dev/null
+++ b/test/jdk/java/foreign/enablenativeaccess/panama_jni_def_module/module-info.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module panama_jni_def_module {
+ exports org.openjdk.jni.def;
+}
diff --git a/test/jdk/java/foreign/enablenativeaccess/panama_jni_def_module/org/openjdk/jni/def/PanamaJNIDef.java b/test/jdk/java/foreign/enablenativeaccess/panama_jni_def_module/org/openjdk/jni/def/PanamaJNIDef.java
new file mode 100644
index 0000000000000..402ce9278e9ee
--- /dev/null
+++ b/test/jdk/java/foreign/enablenativeaccess/panama_jni_def_module/org/openjdk/jni/def/PanamaJNIDef.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.jni.def;
+
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.Linker;
+
+public class PanamaJNIDef {
+
+ public static native void nativeLinker0(Linker linker, FunctionDescriptor desc, Linker.Option[] options);
+}
diff --git a/test/jdk/java/foreign/enablenativeaccess/panama_module/org/openjdk/foreigntest/libLinkerInvokerModule.cpp b/test/jdk/java/foreign/enablenativeaccess/panama_jni_def_module/org/openjdk/jni/def/libLinkerInvokerModule.cpp
similarity index 94%
rename from test/jdk/java/foreign/enablenativeaccess/panama_module/org/openjdk/foreigntest/libLinkerInvokerModule.cpp
rename to test/jdk/java/foreign/enablenativeaccess/panama_jni_def_module/org/openjdk/jni/def/libLinkerInvokerModule.cpp
index 4591d7a506ae3..c46e6e6acdba8 100644
--- a/test/jdk/java/foreign/enablenativeaccess/panama_module/org/openjdk/foreigntest/libLinkerInvokerModule.cpp
+++ b/test/jdk/java/foreign/enablenativeaccess/panama_jni_def_module/org/openjdk/jni/def/libLinkerInvokerModule.cpp
@@ -47,7 +47,7 @@ void call(void* arg) {
extern "C" {
JNIEXPORT void JNICALL
- Java_org_openjdk_foreigntest_PanamaMainJNI_nativeLinker0(JNIEnv *env, jclass cls, jobject linker, jobject desc, jobjectArray opts) {
+ Java_org_openjdk_jni_def_PanamaJNIDef_nativeLinker0(JNIEnv *env, jclass cls, jobject linker, jobject desc, jobjectArray opts) {
Context context;
env->GetJavaVM(&context.jvm);
context.linker = env->NewGlobalRef(linker);
diff --git a/test/jdk/java/foreign/enablenativeaccess/panama_jni_load_module/module-info.java b/test/jdk/java/foreign/enablenativeaccess/panama_jni_load_module/module-info.java
new file mode 100644
index 0000000000000..87e4d8dac050b
--- /dev/null
+++ b/test/jdk/java/foreign/enablenativeaccess/panama_jni_load_module/module-info.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module panama_jni_load_module {
+ exports org.openjdk.jni;
+ requires panama_jni_use_module;
+}
diff --git a/test/jdk/java/foreign/enablenativeaccess/panama_jni_load_module/org/openjdk/jni/PanamaMainJNI.java b/test/jdk/java/foreign/enablenativeaccess/panama_jni_load_module/org/openjdk/jni/PanamaMainJNI.java
new file mode 100644
index 0000000000000..e50dedf181e9b
--- /dev/null
+++ b/test/jdk/java/foreign/enablenativeaccess/panama_jni_load_module/org/openjdk/jni/PanamaMainJNI.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.jni;
+
+import org.openjdk.jni.use.PanamaJNIUse;
+
+public class PanamaMainJNI {
+
+ public static void main(String[] args) {
+ System.loadLibrary("LinkerInvokerModule");
+ PanamaJNIUse.run();
+ }
+}
diff --git a/test/jdk/java/foreign/enablenativeaccess/panama_jni_use_module/module-info.java b/test/jdk/java/foreign/enablenativeaccess/panama_jni_use_module/module-info.java
new file mode 100644
index 0000000000000..daeca16c132fd
--- /dev/null
+++ b/test/jdk/java/foreign/enablenativeaccess/panama_jni_use_module/module-info.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module panama_jni_use_module {
+ exports org.openjdk.jni.use;
+ requires panama_jni_def_module;
+}
diff --git a/test/jdk/java/foreign/enablenativeaccess/panama_jni_use_module/org/openjdk/jni/use/PanamaJNIUse.java b/test/jdk/java/foreign/enablenativeaccess/panama_jni_use_module/org/openjdk/jni/use/PanamaJNIUse.java
new file mode 100644
index 0000000000000..2445b4951dc59
--- /dev/null
+++ b/test/jdk/java/foreign/enablenativeaccess/panama_jni_use_module/org/openjdk/jni/use/PanamaJNIUse.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package org.openjdk.jni.use;
+
+import java.lang.foreign.FunctionDescriptor;
+import java.lang.foreign.Linker;
+
+import org.openjdk.jni.def.PanamaJNIDef;
+
+public class PanamaJNIUse {
+ public static void run() {
+ testDirectAccessCLinker();
+ }
+
+ public static void testDirectAccessCLinker() {
+ System.out.println("Trying to get downcall handle");
+ PanamaJNIDef.nativeLinker0(Linker.nativeLinker(), FunctionDescriptor.ofVoid(), new Linker.Option[0]);
+ System.out.println("Got downcall handle");
+ }
+}
diff --git a/test/jdk/java/foreign/enablenativeaccess/panama_module/org/openjdk/foreigntest/PanamaMainJNI.java b/test/jdk/java/foreign/enablenativeaccess/panama_module/org/openjdk/foreigntest/PanamaMainJNI.java
deleted file mode 100644
index 164ee5852ccfa..0000000000000
--- a/test/jdk/java/foreign/enablenativeaccess/panama_module/org/openjdk/foreigntest/PanamaMainJNI.java
+++ /dev/null
@@ -1,23 +0,0 @@
-package org.openjdk.foreigntest;
-
-import java.lang.foreign.FunctionDescriptor;
-import java.lang.foreign.Linker;
-
-public class PanamaMainJNI {
-
- static {
- System.loadLibrary("LinkerInvokerModule");
- }
-
- public static void main(String[] args) {
- testDirectAccessCLinker();
- }
-
- public static void testDirectAccessCLinker() {
- System.out.println("Trying to get downcall handle");
- nativeLinker0(Linker.nativeLinker(), FunctionDescriptor.ofVoid(), new Linker.Option[0]);
- System.out.println("Got downcall handle");
- }
-
- static native void nativeLinker0(Linker linker, FunctionDescriptor desc, Linker.Option[] options);
-}
diff --git a/test/jdk/java/foreign/handles/Driver.java b/test/jdk/java/foreign/handles/Driver.java
index 1abfa6963fb9a..ca0545e2fd48a 100644
--- a/test/jdk/java/foreign/handles/Driver.java
+++ b/test/jdk/java/foreign/handles/Driver.java
@@ -24,6 +24,6 @@
/*
* @test
* @build invoker_module/* lookup_module/*
- * @run testng/othervm --enable-native-access=invoker_module
+ * @run testng/othervm --illegal-native-access=deny --enable-native-access=invoker_module
* lookup_module/handle.lookup.MethodHandleLookup
*/
diff --git a/test/jdk/java/foreign/handles/invoker_module/handle/invoker/MethodHandleInvoker.java b/test/jdk/java/foreign/handles/invoker_module/handle/invoker/MethodHandleInvoker.java
index 9b696caa82d1e..fbb85cc54dfc5 100644
--- a/test/jdk/java/foreign/handles/invoker_module/handle/invoker/MethodHandleInvoker.java
+++ b/test/jdk/java/foreign/handles/invoker_module/handle/invoker/MethodHandleInvoker.java
@@ -90,6 +90,7 @@ static void addDefaultMapping(Class> carrier, Object value) {
addDefaultMapping(Consumer.class, (Consumer)(Object o) -> {});
addDefaultMapping(FunctionDescriptor.class, FunctionDescriptor.ofVoid());
addDefaultMapping(Linker.Option[].class, null);
+ addDefaultMapping(Runtime.class, Runtime.getRuntime());
addDefaultMapping(byte.class, (byte)0);
addDefaultMapping(boolean.class, true);
addDefaultMapping(char.class, (char)0);
diff --git a/test/jdk/java/foreign/handles/lookup_module/handle/lookup/MethodHandleLookup.java b/test/jdk/java/foreign/handles/lookup_module/handle/lookup/MethodHandleLookup.java
index ed916c1fe2419..42e6d7a7d8403 100644
--- a/test/jdk/java/foreign/handles/lookup_module/handle/lookup/MethodHandleLookup.java
+++ b/test/jdk/java/foreign/handles/lookup_module/handle/lookup/MethodHandleLookup.java
@@ -71,6 +71,18 @@ static Object[][] restrictedMethods() {
{ MethodHandles.lookup().findStatic(SymbolLookup.class, "libraryLookup",
MethodType.methodType(SymbolLookup.class, Path.class, Arena.class)),
"SymbolLookup::libraryLookup(Path)" },
+ { MethodHandles.lookup().findStatic(System.class, "load",
+ MethodType.methodType(void.class, String.class)),
+ "System::load" },
+ { MethodHandles.lookup().findStatic(System.class, "loadLibrary",
+ MethodType.methodType(void.class, String.class)),
+ "System::loadLibrary" },
+ { MethodHandles.lookup().findVirtual(Runtime.class, "load",
+ MethodType.methodType(void.class, String.class)),
+ "Runtime::load" },
+ { MethodHandles.lookup().findVirtual(Runtime.class, "loadLibrary",
+ MethodType.methodType(void.class, String.class)),
+ "Runtime::loadLibrary" }
};
} catch (Throwable ex) {
throw new ExceptionInInitializerError((ex));
diff --git a/test/jdk/java/net/URLClassLoader/JarLoaderCloseTest.java b/test/jdk/java/net/URLClassLoader/JarLoaderCloseTest.java
new file mode 100644
index 0000000000000..469a682e0392a
--- /dev/null
+++ b/test/jdk/java/net/URLClassLoader/JarLoaderCloseTest.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import jdk.test.lib.util.JarUtils;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+import static java.nio.charset.StandardCharsets.US_ASCII;
+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.assertNull;
+
+/*
+ * @test
+ * @bug 8338445
+ * @summary verify that the jdk.internal.loader.URLClassPath closes the JarFile
+ * instances that it no longer uses for loading
+ * @library /test/lib
+ * @build jdk.test.lib.util.JarUtils
+ * @comment This test expects MalformedURLException for some specific URLs.
+ * We use othervm to prevent interference from other tests which
+ * might have installed custom URLStreamHandler(s)
+ * @run junit/othervm JarLoaderCloseTest
+ */
+public class JarLoaderCloseTest {
+
+ private static final String RESOURCE_NAME = "foo-bar.txt";
+ private static final String RESOURCE_CONTENT = "Hello world";
+ private static final Path TEST_SCRATCH_DIR = Path.of(".");
+
+ @BeforeAll
+ static void beforeAll() throws Exception {
+ // create a file which will be added to the JAR file that gets tested
+ Files.writeString(TEST_SCRATCH_DIR.resolve(RESOURCE_NAME), RESOURCE_CONTENT);
+ }
+
+ /*
+ * Creates a JAR file with a manifest which has a Class-Path entry value with malformed URLs.
+ * Then uses a URLClassLoader backed by the JAR file in its classpath, loads some resource,
+ * closes the URLClassLoader and then expects that the underlying JAR file can be deleted
+ * from the filesystem.
+ */
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "C:\\foo\\bar\\hello/world.jar lib2.jar",
+ "C:/hello/world/foo.jar",
+ "lib4.jar C:\\bar\\foo\\world/hello.jar"
+ })
+ public void testMalformedClassPathEntry(final String classPathValue) throws Exception {
+ final Manifest manifest = createManifestWithClassPath(classPathValue);
+ final Path jar = Files.createTempFile(TEST_SCRATCH_DIR, "8338445", ".jar");
+ // create the JAR file with the given manifest and an arbitrary file
+ JarUtils.createJarFile(jar, manifest, TEST_SCRATCH_DIR, Path.of(RESOURCE_NAME));
+ System.out.println("created jar at " + jar + " with manifest:");
+ manifest.write(System.out);
+ final URL[] urlClassPath = new URL[]{jar.toUri().toURL()};
+ // Create a URLClassLoader backed by the JAR file and load a non-existent resource just to
+ // exercise the URLClassPath code of loading the jar and parsing the Class-Path entry.
+ // Then close the classloader. After the classloader is closed
+ // issue a delete on the underlying JAR file on the filesystem. The delete is expected
+ // to succeed.
+ try (final URLClassLoader cl = new URLClassLoader(urlClassPath)) {
+ try (final InputStream is = cl.getResourceAsStream("non-existent.txt")) {
+ assertNull(is, "unexpectedly found a resource in classpath "
+ + Arrays.toString(urlClassPath));
+ }
+ }
+ // now delete the JAR file and verify the delete worked
+ Files.delete(jar);
+ assertFalse(Files.exists(jar), jar + " exists even after being deleted");
+ }
+
+ /*
+ * Creates a JAR file with a manifest which has a Class-Path entry value with URLs
+ * that are parsable but point to files that don't exist on the filesystem.
+ * Then uses a URLClassLoader backed by the JAR file in its classpath, loads some resource,
+ * closes the URLClassLoader and then expects that the underlying JAR file can be deleted
+ * from the filesystem.
+ */
+ @ParameterizedTest
+ @ValueSource(strings = {
+ "/home/me/hello/world.jar lib9.jar",
+ "lib10.jar"
+ })
+ public void testParsableClassPathEntry(final String classPathValue) throws Exception {
+ final Manifest manifest = createManifestWithClassPath(classPathValue);
+ final Path jar = Files.createTempFile(TEST_SCRATCH_DIR, "8338445", ".jar");
+ // create the JAR file with the given manifest and an arbitrary file
+ JarUtils.createJarFile(jar, manifest, TEST_SCRATCH_DIR, Path.of(RESOURCE_NAME));
+ System.out.println("created jar at " + jar + " with manifest:");
+ manifest.write(System.out);
+ final URL[] urlClassPath = new URL[]{jar.toUri().toURL()};
+ // Create a URLClassLoader backed by the JAR file and load a resource
+ // and verify the resource contents.
+ // Then close the classloader. After the classloader is closed
+ // issue a delete on the underlying JAR file on the filesystem. The delete is expected
+ // to succeed.
+ try (final URLClassLoader cl = new URLClassLoader(urlClassPath)) {
+ try (final InputStream is = cl.getResourceAsStream(RESOURCE_NAME)) {
+ assertNotNull(is, RESOURCE_NAME + " not located by classloader in classpath "
+ + Arrays.toString(urlClassPath));
+ final String content = new String(is.readAllBytes(), US_ASCII);
+ assertEquals(RESOURCE_CONTENT, content, "unexpected content in " + RESOURCE_NAME);
+ }
+ }
+ // now delete the JAR file and verify the delete worked
+ Files.delete(jar);
+ assertFalse(Files.exists(jar), jar + " exists even after being deleted");
+ }
+
+ private static Manifest createManifestWithClassPath(final String classPathValue) {
+ final Manifest manifest = new Manifest();
+ final Attributes mainAttributes = manifest.getMainAttributes();
+ mainAttributes.putValue("Manifest-Version", "1.0");
+ mainAttributes.putValue("Class-Path", classPathValue);
+ return manifest;
+ }
+}
diff --git a/test/jdk/java/text/Format/CompactNumberFormat/TestCompactNumber.java b/test/jdk/java/text/Format/CompactNumberFormat/TestCompactNumber.java
index 40da19adfe7b4..16de224777951 100644
--- a/test/jdk/java/text/Format/CompactNumberFormat/TestCompactNumber.java
+++ b/test/jdk/java/text/Format/CompactNumberFormat/TestCompactNumber.java
@@ -22,7 +22,7 @@
*/
/*
* @test
- * @bug 8177552 8217721 8222756 8295372 8306116 8319990
+ * @bug 8177552 8217721 8222756 8295372 8306116 8319990 8338690
* @summary Checks the functioning of compact number format
* @modules jdk.localedata
* @run testng/othervm TestCompactNumber
@@ -60,6 +60,9 @@ public class TestCompactNumber {
private static final NumberFormat FORMAT_IT_SHORT = NumberFormat
.getCompactNumberInstance(Locale.ITALIAN, NumberFormat.Style.SHORT);
+ private static final NumberFormat FORMAT_IT_LONG = NumberFormat
+ .getCompactNumberInstance(Locale.ITALIAN, NumberFormat.Style.LONG);
+
private static final NumberFormat FORMAT_CA_LONG = NumberFormat
.getCompactNumberInstance(Locale.of("ca"), NumberFormat.Style.LONG);
@@ -89,6 +92,13 @@ public class TestCompactNumber {
.getCompactNumberInstance(Locale.ITALIAN, NumberFormat.Style.LONG);
private static final NumberFormat FORMAT_PT_LONG_FD4 = NumberFormat
.getCompactNumberInstance(Locale.of("pt"), NumberFormat.Style.LONG);
+
+ private static final NumberFormat FORMAT_PL_LONG = NumberFormat
+ .getCompactNumberInstance(Locale.of("pl"), NumberFormat.Style.LONG);
+
+ private static final NumberFormat FORMAT_FR_LONG = NumberFormat
+ .getCompactNumberInstance(Locale.FRENCH, NumberFormat.Style.LONG);
+
static {
FORMAT_ES_LONG_FD1.setMaximumFractionDigits(1);
FORMAT_DE_LONG_FD2.setMaximumFractionDigits(2);
@@ -359,6 +369,12 @@ Object[][] compactFormatData() {
{FORMAT_DE_LONG_FD2, 1_234_500, "1,23 Millionen"},
{FORMAT_IT_LONG_FD3, 1_234_500, "1,234 milioni"},
{FORMAT_PT_LONG_FD4, 1_234_500, "1,2345 milh\u00f5es"},
+
+ // 8338690
+ {FORMAT_PL_LONG, 5_000, "5 tysi\u0119cy"},
+ {FORMAT_PL_LONG, 4_949, "5 tysi\u0119cy"},
+ {FORMAT_FR_LONG, 1_949, "2 mille"},
+ {FORMAT_IT_LONG, 1_949, "2 mila"},
};
}
@@ -466,6 +482,10 @@ Object[][] compactParseData() {
{FORMAT_DE_LONG_FD2, "1,23 Millionen", 1_230_000L, Long.class},
{FORMAT_IT_LONG_FD3, "1,234 milioni", 1_234_000L, Long.class},
{FORMAT_PT_LONG_FD4, "1,2345 milh\u00f5es", 1_234_500L, Long.class},
+ // 8338690
+ {FORMAT_PL_LONG, "5 tysi\u0119cy", 5_000L, Long.class},
+ {FORMAT_FR_LONG, "2 mille", 2_000L, Long.class},
+ {FORMAT_IT_LONG, "2 mila", 2_000L, Long.class},
};
}
@@ -514,6 +534,10 @@ Object[][] invalidParseData() {
{FORMAT_SL_LONG, "5 milijon", 5L},
{FORMAT_SL_LONG, "5 milijona", 5L},
{FORMAT_SL_LONG, "5 milijone", 5L},
+ // 8338690
+ {FORMAT_PL_LONG, "5 tysiÄ…ce", 5L},
+ {FORMAT_FR_LONG, "2 millier", 2L},
+ {FORMAT_IT_LONG, "2 mille", 2L},
};
}
diff --git a/test/jdk/java/util/zip/TestZipError.java b/test/jdk/java/util/zip/TestZipError.java
deleted file mode 100644
index 5448add92da78..0000000000000
--- a/test/jdk/java/util/zip/TestZipError.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 2006, 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 4615343
- * @summary Check that ZipError is thrown instead of InternalError when
- * iterating entries of an invalid zip file
- */
-
-import java.io.*;
-import java.util.*;
-import java.util.zip.*;
-
-public class TestZipError {
- public static void realMain(String[] args) throws Throwable {
- // Causing a ZipError is hard, especially on non-Windows systems. See
- // comments below.
- String osName = System.getProperty("os.name");
- if (!System.getProperty("os.name").startsWith("Windows")) {
- return;
- }
-
- String fileName = "error4615343.zip";
- File f = new File(fileName);
- f.delete();
- ZipOutputStream zos;
- ZipEntry ze;
-
- // Create a zip file with two entries.
- zos = new ZipOutputStream(new FileOutputStream(f));
- ze = new ZipEntry("one");
- zos.putNextEntry(ze);
- zos.write("hello".getBytes());
- zos.closeEntry();
- ze = new ZipEntry("two");
- zos.putNextEntry(ze);
- zos.write("world".getBytes());
- zos.closeEntry();
- zos.close();
-
- // Open the ZipFile. This will read the zip file's central
- // directory into in-memory data structures.
- ZipFile zf = new ZipFile(fileName);
-
- // Delete the file; of course this does not change the in-memory data
- // structures that represent the central directory!
- f.delete();
-
- // Re-create zip file, with different entries than earlier. However,
- // recall that we have in-memory information about the central
- // directory of the file at its previous state.
- zos = new ZipOutputStream(new FileOutputStream(f));
- ze = new ZipEntry("uno");
- zos.putNextEntry(ze);
- zos.write("hola".getBytes());
- zos.closeEntry();
- zos.close();
-
- // Iterate zip file's contents. On Windows, this will result in a
- // ZipError, because the data in the file differs from the in-memory
- // central directory information we read earlier.
- Enumeration extends ZipEntry> entries = zf.entries();
- try {
- while (entries.hasMoreElements()) {
- ze = entries.nextElement();
- zf.getInputStream(ze).readAllBytes();
- }
- fail("Did not get expected exception");
- } catch (ZipException e) {
- pass();
- } catch (InternalError e) {
- fail("Caught InternalError instead of expected ZipError");
- } catch (Throwable t) {
- unexpected(t);
- } finally {
- zf.close();
- f.delete();
- }
- }
-
- //--------------------- Infrastructure ---------------------------
- static volatile int passed = 0, failed = 0;
- static void pass() {passed++;}
- static void fail() {failed++; Thread.dumpStack();}
- static void fail(String msg) {System.out.println(msg); fail();}
- static void unexpected(Throwable t) {failed++; t.printStackTrace();}
- static void check(boolean cond) {if (cond) pass(); else fail();}
- static void equal(Object x, Object y) {
- if (x == null ? y == null : x.equals(y)) pass();
- else fail(x + " not equal to " + y);}
- public static void main(String[] args) throws Throwable {
- try {realMain(args);} catch (Throwable t) {unexpected(t);}
- System.out.println("\nPassed = " + passed + " failed = " + failed);
- if (failed > 0) throw new AssertionError("Some tests failed");}
-}
diff --git a/test/jdk/javax/net/ssl/SSLSession/CertMsgCheck.java b/test/jdk/javax/net/ssl/SSLSession/CertMsgCheck.java
index 498c17672b213..2131b314ce0aa 100644
--- a/test/jdk/javax/net/ssl/SSLSession/CertMsgCheck.java
+++ b/test/jdk/javax/net/ssl/SSLSession/CertMsgCheck.java
@@ -39,10 +39,12 @@ public static void main(String[] args) throws Exception {
build();
// Initial client session
- TLSBase.Client client1 = new TLSBase.Client(true, false);
+ TLSBase.Client client = new TLSBase.Client(true, false);
+ client.connect();
- server.getSession(client1).getSessionContext();
- server.done();
+ // Close must be called to gather all the exceptions thrown
+ client.close();
+ server.close();
var eList = server.getExceptionList();
System.out.println("Exception list size is " + eList.size());
diff --git a/test/jdk/javax/net/ssl/SSLSession/CheckSessionContext.java b/test/jdk/javax/net/ssl/SSLSession/CheckSessionContext.java
index 183354ed9db22..a08414b03fd46 100644
--- a/test/jdk/javax/net/ssl/SSLSession/CheckSessionContext.java
+++ b/test/jdk/javax/net/ssl/SSLSession/CheckSessionContext.java
@@ -47,6 +47,7 @@ public static void main(String[] args) throws Exception {
// Initial client session
TLSBase.Client client1 = new TLSBase.Client();
+ client1.connect();
if (server.getSession(client1).getSessionContext() == null) {
throw new Exception("Context was null. Handshake failure.");
} else {
@@ -66,6 +67,7 @@ public static void main(String[] args) throws Exception {
// Resume the client session
TLSBase.Client client2 = new TLSBase.Client();
+ client2.connect();
if (server.getSession(client2).getSessionContext() == null) {
throw new Exception("Context was null on resumption");
} else {
@@ -73,6 +75,5 @@ public static void main(String[] args) throws Exception {
}
server.close(client2);
client2.close();
- server.done();
}
}
diff --git a/test/jdk/javax/net/ssl/TLSCommon/interop/AbstractServer.java b/test/jdk/javax/net/ssl/TLSCommon/interop/AbstractServer.java
index a5f61ce869a0d..03b3aadb0074f 100644
--- a/test/jdk/javax/net/ssl/TLSCommon/interop/AbstractServer.java
+++ b/test/jdk/javax/net/ssl/TLSCommon/interop/AbstractServer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,8 @@
*/
import java.io.IOException;
+import java.net.InetAddress;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -52,11 +54,21 @@ public void signalStop() throws Exception { }
public static abstract class Builder extends AbstractPeer.Builder {
+ private InetAddress listenInterface = InetAddress.getLoopbackAddress();
private int port;
// Indicates if requires client authentication.
private boolean clientAuth = true;
+ public InetAddress getListenInterface() {
+ return listenInterface;
+ }
+
+ public Builder setListenInterface(InetAddress listenInterface) {
+ this.listenInterface = listenInterface;
+ return this;
+ }
+
public int getPort() {
return port;
}
diff --git a/test/jdk/javax/net/ssl/TLSCommon/interop/JdkServer.java b/test/jdk/javax/net/ssl/TLSCommon/interop/JdkServer.java
index 6519e89febb9e..1521325b65ac8 100644
--- a/test/jdk/javax/net/ssl/TLSCommon/interop/JdkServer.java
+++ b/test/jdk/javax/net/ssl/TLSCommon/interop/JdkServer.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,6 +22,7 @@
*/
import java.io.IOException;
+import java.net.InetAddress;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.List;
@@ -53,7 +54,8 @@ public JdkServer(Builder builder) throws Exception {
context = Utilities.createSSLContext(builder.getCertTuple());
SSLServerSocketFactory serverFactory = context.getServerSocketFactory();
serverSocket
- = (SSLServerSocket) serverFactory.createServerSocket(builder.getPort());
+ = (SSLServerSocket) serverFactory.createServerSocket(builder.getPort(),
+ 0, builder.getListenInterface());
configServerSocket(builder);
}
diff --git a/test/jdk/javax/net/ssl/templates/TLSBase.java b/test/jdk/javax/net/ssl/templates/TLSBase.java
index 5c95253e6f024..8ec4e4e3db46f 100644
--- a/test/jdk/javax/net/ssl/templates/TLSBase.java
+++ b/test/jdk/javax/net/ssl/templates/TLSBase.java
@@ -25,13 +25,16 @@
import java.io.*;
import java.net.InetAddress;
import java.net.InetSocketAddress;
+import java.nio.charset.StandardCharsets;
import java.security.KeyStore;
import java.security.cert.PKIXBuilderParameters;
import java.security.cert.X509CertSelector;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
/**
* This is a base setup for creating a server and clients. All clients will
@@ -39,7 +42,7 @@
* first. The idea is for the test code to be minimal as possible without
* this library class being complicated.
*
- * Server.done() must be called or the server will never exit and hang the test.
+ * Server.close() must be called so the server will exit and end threading.
*
* After construction, reading and writing are allowed from either side,
* or a combination write/read from both sides for verifying text.
@@ -52,24 +55,25 @@
*/
abstract public class TLSBase {
- static String pathToStores = "../etc";
+ static String pathToStores = "javax/net/ssl/etc";
static String keyStoreFile = "keystore";
static String trustStoreFile = "truststore";
static String passwd = "passphrase";
+ static final String TESTROOT =
+ System.getProperty("test.root", "../../../..");
+
SSLContext sslContext;
// Server's port
static int serverPort;
// Name shown during read and write ops
- String name;
+ public String name;
TLSBase() {
- String keyFilename =
- System.getProperty("test.src", "./") + "/" + pathToStores +
- "/" + keyStoreFile;
- String trustFilename =
- System.getProperty("test.src", "./") + "/" + pathToStores +
- "/" + trustStoreFile;
+
+ String keyFilename = TESTROOT + "/" + pathToStores + "/" + keyStoreFile;
+ String trustFilename = TESTROOT + "/" + pathToStores + "/" +
+ trustStoreFile;
System.setProperty("javax.net.ssl.keyStore", keyFilename);
System.setProperty("javax.net.ssl.keyStorePassword", passwd);
System.setProperty("javax.net.ssl.trustStore", trustFilename);
@@ -78,26 +82,22 @@ abstract public class TLSBase {
// Base read operation
byte[] read(SSLSocket sock) throws Exception {
- BufferedReader reader = new BufferedReader(
- new InputStreamReader(sock.getInputStream()));
- String s = reader.readLine();
- System.err.println("(read) " + name + ": " + s);
- return s.getBytes();
+ BufferedInputStream is = new BufferedInputStream(sock.getInputStream());
+ byte[] b = is.readNBytes(5);
+ System.err.println("(read) " + Thread.currentThread().getName() + ": " + new String(b));
+ return b;
}
// Base write operation
public void write(SSLSocket sock, byte[] data) throws Exception {
- PrintWriter out = new PrintWriter(
- new OutputStreamWriter(sock.getOutputStream()));
- out.println(new String(data));
- out.flush();
- System.err.println("(write)" + name + ": " + new String(data));
+ sock.getOutputStream().write(data);
+ System.err.println("(write)" + Thread.currentThread().getName() + ": " + new String(data));
}
private static KeyManager[] getKeyManager(boolean empty) throws Exception {
FileInputStream fis = null;
if (!empty) {
- fis = new FileInputStream(System.getProperty("test.src", "./") +
+ fis = new FileInputStream(System.getProperty("test.root", "./") +
"/" + pathToStores + "/" + keyStoreFile);
}
// Load the keystore
@@ -113,7 +113,7 @@ private static KeyManager[] getKeyManager(boolean empty) throws Exception {
private static TrustManager[] getTrustManager(boolean empty) throws Exception {
FileInputStream fis = null;
if (!empty) {
- fis = new FileInputStream(System.getProperty("test.src", "./") +
+ fis = new FileInputStream(System.getProperty("test.root", "./") +
"/" + pathToStores + "/" + trustStoreFile);
}
// Load the keystore
@@ -150,6 +150,11 @@ static class Server extends TLSBase {
new ConcurrentHashMap<>();
Thread t;
List exceptionList = new ArrayList<>();
+ ExecutorService threadPool = Executors.newFixedThreadPool(1,
+ r -> {
+ Thread t = Executors.defaultThreadFactory().newThread(r);
+ return t;
+ });
Server(ServerBuilder builder) {
super();
@@ -160,8 +165,10 @@ static class Server extends TLSBase {
TLSBase.getTrustManager(builder.tm), null);
fac = sslContext.getServerSocketFactory();
ssock = (SSLServerSocket) fac.createServerSocket(0);
+ ssock.setReuseAddress(true);
ssock.setNeedClientAuth(builder.clientauth);
serverPort = ssock.getLocalPort();
+ System.out.println("Server Port: " + serverPort);
} catch (Exception e) {
System.err.println("Failure during server initialization");
e.printStackTrace();
@@ -171,117 +178,67 @@ static class Server extends TLSBase {
t = new Thread(() -> {
try {
while (true) {
- System.err.println("Server ready on port " +
- serverPort);
- SSLSocket c = (SSLSocket)ssock.accept();
- clientMap.put(c.getPort(), c);
- try {
- write(c, read(c));
- } catch (Exception e) {
- System.out.println("Caught " + e.getMessage());
- e.printStackTrace();
- exceptionList.add(e);
- }
+ SSLSocket sock = (SSLSocket)ssock.accept();
+ threadPool.submit(new ServerThread(sock));
}
} catch (Exception ex) {
System.err.println("Server Down");
ex.printStackTrace();
+ } finally {
+ threadPool.close();
}
});
t.start();
}
- Server() {
- this(new ServerBuilder());
- }
+ class ServerThread extends Thread {
+ SSLSocket sock;
- /**
- * @param km - true for an empty key manager
- * @param tm - true for an empty trust manager
- */
- Server(boolean km, boolean tm) {
- super();
- name = "server";
- try {
- sslContext = SSLContext.getInstance("TLS");
- sslContext.init(TLSBase.getKeyManager(km),
- TLSBase.getTrustManager(tm), null);
- fac = sslContext.getServerSocketFactory();
- ssock = (SSLServerSocket) fac.createServerSocket(0);
- ssock.setNeedClientAuth(true);
- serverPort = ssock.getLocalPort();
- } catch (Exception e) {
- System.err.println("Failure during server initialization");
- e.printStackTrace();
- }
-
- // Thread to allow multiple clients to connect
- t = new Thread(() -> {
- try {
- while (true) {
- System.err.println("Server ready on port " +
- serverPort);
- SSLSocket c = (SSLSocket)ssock.accept();
- clientMap.put(c.getPort(), c);
- try {
- write(c, read(c));
- } catch (Exception e) {
- System.out.println("Caught " + e.getMessage());
- e.printStackTrace();
- exceptionList.add(e);
- }
- }
- } catch (Exception ex) {
- System.err.println("Server Down");
- ex.printStackTrace();
- }
- });
- t.start();
+ ServerThread(SSLSocket s) {
+ this.sock = s;
+ System.err.println("ServerThread("+sock.getPort()+")");
+ clientMap.put(sock.getPort(), sock);
}
- // Exit test to quit the test. This must be called at the end of the
- // test or the test will never end.
- void done() {
- try {
- t.join(5000);
- ssock.close();
- } catch (Exception e) {
- System.err.println(e.getMessage());
- e.printStackTrace();
- }
- }
-
- // Read from the client
- byte[] read(Client client) throws Exception {
- SSLSocket s = clientMap.get(Integer.valueOf(client.getPort()));
- if (s == null) {
- System.err.println("No socket found, port " + client.getPort());
+ public void run() {
+ try {
+ write(sock, read(sock));
+ } catch (Exception e) {
+ System.out.println("Caught " + e.getMessage());
+ e.printStackTrace();
+ exceptionList.add(e);
+ }
}
- return read(s);
}
- // Write to the client
- void write(Client client, byte[] data) throws Exception {
- write(clientMap.get(client.getPort()), data);
+ Server() {
+ this(new ServerBuilder());
}
- // Server writes to the client, then reads from the client.
- // Return true if the read & write data match, false if not.
- boolean writeRead(Client client, String s) throws Exception{
- write(client, s.getBytes());
- return (Arrays.compare(s.getBytes(), client.read()) == 0);
+ public SSLSession getSession(Client client) throws Exception {
+ System.err.println("getSession("+client.getPort()+")");
+ SSLSocket clientSocket = clientMap.get(client.getPort());
+ if (clientSocket == null) {
+ throw new Exception("Server can't find client socket");
+ }
+ return clientSocket.getSession();
}
- // Get the SSLSession from the server side socket
- SSLSession getSession(Client c) {
- SSLSocket s = clientMap.get(Integer.valueOf(c.getPort()));
- return s.getSession();
+ void close(Client client) {
+ try {
+ System.err.println("close("+client.getPort()+")");
+ clientMap.remove(client.getPort()).close();
+ } catch (Exception e) {
+ ;
+ }
}
-
- // Close client socket
- void close(Client c) throws IOException {
- SSLSocket s = clientMap.get(Integer.valueOf(c.getPort()));
- s.close();
+ void close() throws InterruptedException {
+ clientMap.values().stream().forEach(s -> {
+ try {
+ s.close();
+ } catch (IOException e) {}
+ });
+ threadPool.awaitTermination(500, TimeUnit.MILLISECONDS);
}
List getExceptionList() {
@@ -312,11 +269,11 @@ Server build() {
}
}
/**
- * Client side will establish a connection from the constructor and wait.
+ * Client side will establish a SSLContext instance.
* It must be run after the Server constructor is called.
*/
static class Client extends TLSBase {
- SSLSocket sock;
+ public SSLSocket socket;
boolean km, tm;
Client() {
this(false, false);
@@ -330,55 +287,66 @@ static class Client extends TLSBase {
super();
this.km = km;
this.tm = tm;
- connect();
- }
-
- // Connect to server. Maybe runnable in the future
- public SSLSocket connect() {
try {
sslContext = SSLContext.getInstance("TLS");
sslContext.init(TLSBase.getKeyManager(km), TLSBase.getTrustManager(tm), null);
- sock = (SSLSocket)sslContext.getSocketFactory().createSocket();
- sock.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), serverPort));
- System.err.println("Client connected using port " +
- sock.getLocalPort());
- name = "client(" + sock.toString() + ")";
- write("Hello");
- read();
+ socket = createSocket();
} catch (Exception ex) {
ex.printStackTrace();
}
- return sock;
}
- // Read from the client socket
- byte[] read() throws Exception {
- return read(sock);
+ Client(Client cl) {
+ sslContext = cl.sslContext;
+ socket = createSocket();
}
- // Write to the client socket
- void write(byte[] data) throws Exception {
- write(sock, data);
+ public SSLSocket createSocket() {
+ try {
+ return (SSLSocket) sslContext.getSocketFactory().createSocket();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return null;
}
- void write(String s) throws Exception {
- write(sock, s.getBytes());
+
+ public SSLSocket connect() {
+ try {
+ socket.connect(new InetSocketAddress(InetAddress.getLoopbackAddress(), serverPort));
+ System.err.println("Client (" + Thread.currentThread().getName() + ") connected using port " +
+ socket.getLocalPort() + " to " + socket.getPort());
+ writeRead();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return null;
+ }
+ return socket;
}
- // Client writes to the server, then reads from the server.
- // Return true if the read & write data match, false if not.
- boolean writeRead(Server server, String s) throws Exception {
- write(s.getBytes());
- return (Arrays.compare(s.getBytes(), server.read(this)) == 0);
+ public SSLSession getSession() {
+ return socket.getSession();
+ }
+ public void close() {
+ try {
+ socket.close();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
}
- // Get port from the socket
- int getPort() {
- return sock.getLocalPort();
+ public int getPort() {
+ return socket.getLocalPort();
}
- // Close socket
- void close() throws IOException {
- sock.close();
+ private SSLSocket writeRead() {
+ try {
+ write(socket, "Hello".getBytes(StandardCharsets.ISO_8859_1));
+ read(socket);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return socket;
}
+
}
}
diff --git a/test/jdk/javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java b/test/jdk/javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java
new file mode 100644
index 0000000000000..96ef9edc57100
--- /dev/null
+++ b/test/jdk/javax/swing/JButton/SwingButtonResizeTestWithOpenGL.java
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.FocusAdapter;
+import java.awt.event.FocusEvent;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.Raster;
+import java.io.File;
+import java.io.IOException;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.imageio.ImageIO;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+/*
+ * @test
+ * @bug 8338103
+ * @key headful
+ * @summary Verifies that the OpenGL pipeline does not create artifacts
+ * with swing components after window is zoomed to maximum size and then
+ * resized back to normal. The test case simulates this operation using
+ * a JButton. A file image of the component will be saved before and after
+ * the window resize if the test fails. The test passes if both the button
+ * images are the same.
+ * @run main/othervm -Dsun.java2d.opengl=true -Dsun.java2d.opengl.fbobject=false SwingButtonResizeTestWithOpenGL
+ * @run main/othervm -Dsun.java2d.opengl=true -Dsun.java2d.opengl.fbobject=true SwingButtonResizeTestWithOpenGL
+ * @run main/othervm -Dsun.java2d.opengl=false SwingButtonResizeTestWithOpenGL
+ * @run main/othervm SwingButtonResizeTestWithOpenGL
+ */
+/*
+ * @test
+ * @key headful
+ * @requires (os.family == "windows")
+ * @run main/othervm -Dsun.java2d.d3d=false SwingButtonResizeTestWithOpenGL
+ * @run main/othervm -Dsun.java2d.d3d=true SwingButtonResizeTestWithOpenGL
+ */
+/*
+ * @test
+ * @key headful
+ * @requires (os.family == "linux")
+ * @run main/othervm -Dsun.java2d.xrender=false SwingButtonResizeTestWithOpenGL
+ * @run main/othervm -Dsun.java2d.xrender=true SwingButtonResizeTestWithOpenGL
+ */
+/*
+ * @test
+ * @key headful
+ * @requires (os.family == "mac")
+ * @run main/othervm -Dsun.java2d.metal=false SwingButtonResizeTestWithOpenGL
+ * @run main/othervm -Dsun.java2d.metal=true SwingButtonResizeTestWithOpenGL
+ */
+public class SwingButtonResizeTestWithOpenGL {
+ private static Robot robot;
+ private static CountDownLatch focusGainedLatch;
+ private JFrame frame;
+ private JButton button;
+
+ public SwingButtonResizeTestWithOpenGL() {
+
+ try {
+ SwingUtilities.invokeAndWait(() -> createGUI());
+ } catch (Exception e) {
+ throw new RuntimeException("Problems creating GUI");
+ }
+ }
+
+ private void createGUI() {
+ frame = new JFrame("SwingButtonResizeTestWithOpenGL");
+ button = new JButton("Button A");
+ frame.setLocation(200, 200);
+ frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+ button.setPreferredSize(new Dimension(300, 300));
+ button.addFocusListener(new FocusAdapter() {
+ public void focusGained(FocusEvent fe) {
+ focusGainedLatch.countDown();
+ }
+ });
+ frame.getContentPane().setLayout(new FlowLayout());
+ frame.getContentPane().add(button);
+ frame.pack();
+ frame.setVisible(true);
+ frame.toFront();
+ }
+
+ public static void main(String[] args) throws Exception {
+ focusGainedLatch = new CountDownLatch(1);
+ SwingButtonResizeTestWithOpenGL test =
+ new SwingButtonResizeTestWithOpenGL();
+ test.runTest();
+ }
+
+ public void runTest() throws Exception {
+ BufferedImage bimage1;
+ BufferedImage bimage2;
+
+ try {
+ robot = new Robot();
+ robot.setAutoWaitForIdle(true);
+ robot.setAutoDelay(200);
+
+ if (focusGainedLatch.await(3, TimeUnit.SECONDS)) {
+ System.out.println("Button focus gained...");
+ } else {
+ System.out.println("Button focus not gained...");
+ throw new RuntimeException(
+ "Can't gain focus on button even after waiting " +
+ "too long..");
+ }
+
+ System.out.println("Getting initial button image..image1");
+ bimage1 = getButtonImage();
+
+ // some platforms may not support maximize frame
+ if (frame.getToolkit().isFrameStateSupported(
+ JFrame.MAXIMIZED_BOTH)) {
+ robot.waitForIdle();
+ // maximize frame from normal size
+ frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
+ System.out.println("Frame is maximized");
+ robot.waitForIdle();
+
+ if (frame.getToolkit().isFrameStateSupported(JFrame.NORMAL)) {
+ System.out.println("Frame is back to normal");
+ // resize from maximum size to normal
+ frame.setExtendedState(JFrame.NORMAL);
+
+ // capture image of JButton after resize
+ System.out.println(
+ "Getting image of JButton after resize..image2");
+ bimage2 = getButtonImage();
+
+ // compare button images from before and after frame resize
+ DiffImage di = new DiffImage(bimage1.getWidth(),
+ bimage1.getHeight());
+ System.out.println(
+ "Taking the diff of two images, image1 and image2");
+ if (!di.compare(bimage1, bimage2)) {
+ throw new RuntimeException(
+ "Button renderings are different after window "
+ + "resize, num of Diff Pixels="
+ + di.getNumDiffPixels());
+ } else {
+ System.out.println("Test passed...");
+ }
+
+ } else {
+ System.out.println(
+ "Test skipped: JFrame.NORMAL resize is " +
+ "not supported");
+ }
+
+ } else {
+ System.out.println(
+ "Test skipped: JFrame.MAXIMIZED_BOTH resize is " +
+ "not supported");
+ }
+ } finally {
+ SwingUtilities.invokeAndWait(() -> disposeFrame());
+ }
+ }
+
+ // Capture button rendering as a BufferedImage
+ private BufferedImage getButtonImage() {
+ try {
+ robot.waitForIdle();
+ robot.delay(500);
+
+ AtomicReference buttonLocRef = new AtomicReference<>();
+ SwingUtilities.invokeAndWait(
+ () -> buttonLocRef.set(button.getLocationOnScreen()));
+ Point buttonLoc = buttonLocRef.get();
+ System.out.println("Button loc: " + buttonLoc);
+ return robot.createScreenCapture(
+ new Rectangle(buttonLoc.x, buttonLoc.y, button.getWidth(),
+ button.getHeight()));
+ } catch (Exception e) {
+ throw new RuntimeException(
+ "Problems capturing button image from Robot", e);
+ }
+ }
+
+ private void disposeFrame() {
+ if (frame != null) {
+ frame.dispose();
+ frame = null;
+ }
+ }
+
+ // Save BufferedImage to PNG file
+ private void saveButtonImage(BufferedImage image, File file) {
+ if (image != null) {
+ try {
+ System.out.println(
+ "Saving button image to " + file.getAbsolutePath());
+ ImageIO.write(image, "PNG", file);
+ } catch (Exception e) {
+ throw new RuntimeException("Could not write image file");
+ }
+ } else {
+ throw new RuntimeException("BufferedImage was set to null");
+ }
+ }
+
+ private class DiffImage extends BufferedImage {
+
+ public boolean diff = false;
+ public int nDiff = -1;
+
+ Color bgColor;
+
+ int threshold = 0;
+
+ public DiffImage(int w, int h) {
+ super(w, h, BufferedImage.TYPE_INT_ARGB);
+ bgColor = Color.LIGHT_GRAY;
+ }
+
+ public int getNumDiffPixels() {
+ return nDiff;
+ }
+
+ public boolean compare(BufferedImage img1, BufferedImage img2)
+ throws IOException {
+
+ int minx1 = img1.getMinX();
+ int minx2 = img2.getMinX();
+ int miny1 = img1.getMinY();
+ int miny2 = img2.getMinY();
+
+ int w1 = img1.getWidth();
+ int w2 = img2.getWidth();
+ int h1 = img1.getHeight();
+ int h2 = img2.getHeight();
+
+ if ((minx1 != minx2) || (miny1 != miny2) || (w1 != w2)
+ || (h1 != h2)) {
+ // image sizes are different
+ throw new RuntimeException(
+ "img1: <" + minx1 + "," + miny1 + "," + w1 + "x" + h1
+ + ">" + " img2: " + minx2 + "," + miny2 + "," + w2 + "x"
+ + h2 + ">" + " are different sizes");
+ }
+ // Get the actual data behind the images
+ Raster ras1 = img1.getData();
+ Raster ras2 = img2.getData();
+
+ ColorModel cm1 = img1.getColorModel();
+ ColorModel cm2 = img2.getColorModel();
+
+ int r1, r2; // red
+ int g1, g2; // green
+ int b1, b2; // blue
+
+ Object o1 = null;
+ Object o2 = null;
+ nDiff = 0;
+ for (int x = minx1; x < (minx1 + w1); x++) {
+ for (int y = miny1; y < (miny1 + h1); y++) {
+ // Causes rasters to allocate data
+ o1 = ras1.getDataElements(x, y, o1);
+ // and we reuse the data on every loop
+ o2 = ras2.getDataElements(x, y, o2);
+
+ r1 = cm1.getRed(o1);
+ r2 = cm2.getRed(o2);
+ g1 = cm1.getGreen(o1);
+ g2 = cm2.getGreen(o2);
+ b1 = cm1.getBlue(o1);
+ b2 = cm2.getBlue(o2);
+
+ int redAbs = Math.abs(r1 - r2);
+ int greenAbs = Math.abs(g1 - g2);
+ int blueAbs = Math.abs(b1 - b2);
+ if ((redAbs > threshold)
+ || (greenAbs > threshold)
+ || (blueAbs > threshold)) {
+ // pixel is different
+ setDiffPixel(x, y, redAbs, greenAbs, blueAbs);
+ nDiff++;
+ } else {
+ setSamePixel(x, y);
+ }
+
+ }
+ }
+ if (nDiff != 0) {
+ ImageIO.write(this, "png",
+ new File("diffImage.png"));
+ saveButtonImage(img1, new File("image1.png"));
+ saveButtonImage(img2, new File("image2.png"));
+ }
+ return nDiff == 0;
+ }
+
+ void setDiffPixel(int x, int y, int r, int g, int b) {
+ diff = true;
+ setPixelValue(x, y, 255, r, g, b);
+ }
+
+ void setSamePixel(int x, int y) {
+ if (bgColor != null) {
+ setPixelValue(x, y, 255, bgColor.getRed(),
+ bgColor.getGreen(),
+ bgColor.getBlue());
+ } else {
+ setPixelValue(x, y, 255, Color.black.getRed(),
+ Color.black.getGreen(), Color.black.getBlue());
+ }
+ }
+
+ void setPixelValue(int x, int y, int a, int r, int g, int b) {
+ // setRGB uses BufferedImage.TYPE_INT_ARGB format
+ int pixel =
+ ((a & 0xff) << 24) + ((r & 0xff) << 16) + ((g & 0xff) << 8)
+ + ((b & 0xff));
+ setRGB(x, y, pixel);
+ }
+
+ }
+
+}
+
+
diff --git a/test/jdk/javax/swing/JFileChooser/8080628/bug8080628.java b/test/jdk/javax/swing/JFileChooser/8080628/bug8080628.java
index 21490282550e6..426ed7456484a 100644
--- a/test/jdk/javax/swing/JFileChooser/8080628/bug8080628.java
+++ b/test/jdk/javax/swing/JFileChooser/8080628/bug8080628.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,17 @@
* @test
* @bug 8080628
* @summary No mnemonics on Open and Save buttons in JFileChooser.
- * @author Alexey Ivanov
+ * @requires os.family != "linux"
+ * @modules java.desktop/sun.swing
+ * @run main bug8080628
+ */
+
+/*
+ * @test
+ * @bug 8080628
+ * @key headful
+ * @summary No mnemonics on Open and Save buttons in JFileChooser.
+ * @requires os.family == "linux"
* @modules java.desktop/sun.swing
* @run main bug8080628
*/
@@ -81,8 +91,10 @@ private static void runTest() {
try {
UIManager.setLookAndFeel(info.getClassName());
} catch (final UnsupportedLookAndFeelException ignored) {
+ System.out.println("Unsupported L&F: " + info.getClassName());
continue;
}
+ System.out.println("Testing L&F: " + info.getClassName());
for (Locale locale : LOCALES) {
for (String key : MNEMONIC_KEYS) {
diff --git a/test/jdk/javax/swing/JTable/KeyBoardNavigation.java b/test/jdk/javax/swing/JTable/KeyBoardNavigation.java
index 595547421ad16..728361a3e9022 100644
--- a/test/jdk/javax/swing/JTable/KeyBoardNavigation.java
+++ b/test/jdk/javax/swing/JTable/KeyBoardNavigation.java
@@ -39,7 +39,7 @@
/*
* @test
* @key headful
- * @bug 4112270 8264102
+ * @bug 4112270 8264102 8329756
* @library /java/awt/regtesthelpers
* @build PassFailJFrame
* @summary Test Keyboard Navigation in JTable.
@@ -178,7 +178,7 @@ public static void main(String[] args) throws Exception {
1. Refer the below keyboard navigation specs
(referenced from bug report 4112270).
2. Check all combinations of navigational keys mentioned below
- and verifying each key combinations against the spec defined.
+ and verify each key combination against the spec defined.
If it does, press "pass", otherwise press "fail".
""";
@@ -270,24 +270,19 @@ public static String getOSSpecificInstructions() {
up/down
Left/Right Arrow - Deselect current selection;
move focus one cell left/right
- FN+Up Arrow/FN+Down Arrow - Deselect current selection;
+ fn+Up/Down Arrow - Deselect current selection;
scroll up/down one JViewport view;
first visible cell in current column gets focus
- Control-FN+Up Arrow/FN+Down Arrow - Deselect current selection;
- move focus and view to
- first/last cell in current row
- F2 - Allows editing in a cell containing information without
+ fn - Allows editing in a cell containing information without
overwriting the information
Esc - Resets the cell content back to the state it was in
before editing started
- Ctrl+A, Ctrl+/ - Select All
- Ctrl+\\ - Deselect all
+ Cmd+A - Select All
Shift-Up/Down Arrow - Extend selection up/down one row
Shift-Left/Right Arrow - Extend selection left/right one column
- FN-Shift Up/Down Arrow - Extend selection to top/bottom of column
- Shift-PageUp/PageDown - Extend selection up/down one view and scroll
- table
- """;
+ Ctrl-Shift Up/Down Arrow - Extend selection to top/bottom of row
+ Ctrl-Shift Left/Right Arrow - Extend selection to first/last of column
+ """;
String osName = System.getProperty("os.name").toLowerCase();
if (osName.startsWith("mac")) {
return MAC_SPECIFIC;
diff --git a/test/jdk/javax/swing/plaf/gtk/JTableCtrlShiftRightLeftKeyTest.java b/test/jdk/javax/swing/plaf/gtk/JTableCtrlShiftRightLeftKeyTest.java
new file mode 100644
index 0000000000000..1df2ed4861632
--- /dev/null
+++ b/test/jdk/javax/swing/plaf/gtk/JTableCtrlShiftRightLeftKeyTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+
+import javax.swing.JFrame;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+/*
+ * @test
+ * @bug 8338041
+ * @key headful
+ * @summary Verify that Ctrl Shift RIGHT/LEFT key extends columns till
+ * Last/First Columns in JTable
+ * @requires (os.family == "linux")
+ * @run main JTableCtrlShiftRightLeftKeyTest
+ */
+
+public class JTableCtrlShiftRightLeftKeyTest {
+ private static JFrame frame;
+ private static JTable table;
+ private static volatile Point tableLoc;
+ private static volatile Rectangle cellRect;
+ private static volatile int[] selectedColumnAfterKeyPress;
+ private static Robot robot;
+ private static final int SELECTED_COLUMN = 2;
+
+ public static void main(String[] args) throws Exception {
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
+ robot = new Robot();
+ robot.setAutoDelay(50);
+ try {
+ SwingUtilities.invokeAndWait(JTableCtrlShiftRightLeftKeyTest::createAndShowUI);
+ robot.waitForIdle();
+ robot.delay(1000);
+
+ SwingUtilities.invokeAndWait(() -> {
+ tableLoc = table.getLocationOnScreen();
+ cellRect = table.getCellRect(0, SELECTED_COLUMN, true);
+ });
+
+ robot.mouseMove(tableLoc.x + cellRect.x + cellRect.width / 2,
+ tableLoc.y + cellRect.y + cellRect.height / 2);
+ robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+ robot.waitForIdle();
+ robot.delay(100);
+
+ testCtrlShift(KeyEvent.VK_RIGHT, SELECTED_COLUMN,
+ table.getColumnCount() - 1, "RIGHT");
+
+ robot.waitForIdle();
+ robot.delay(100);
+ robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+ robot.waitForIdle();
+ robot.delay(100);
+
+ testCtrlShift(KeyEvent.VK_LEFT, 0,
+ SELECTED_COLUMN, "LEFT");
+ robot.waitForIdle();
+ robot.delay(100);
+ System.out.println("Test Passed!");
+
+ } finally {
+ SwingUtilities.invokeAndWait(() -> {
+ if (frame != null) {
+ frame.dispose();
+ }
+ });
+ }
+ }
+
+ private static void testCtrlShift(int keySelected, int startCellCheck,
+ int endCellCheck, String key) throws Exception {
+ robot.keyPress(KeyEvent.VK_SHIFT);
+ robot.keyPress(KeyEvent.VK_CONTROL);
+ robot.keyPress(keySelected);
+ robot.keyRelease(keySelected);
+ robot.keyRelease(KeyEvent.VK_SHIFT);
+ robot.keyRelease(KeyEvent.VK_CONTROL);
+ robot.waitForIdle();
+ robot.delay(100);
+
+ SwingUtilities.invokeAndWait(() -> {
+ selectedColumnAfterKeyPress = table.getSelectedColumns();
+ });
+
+ if (selectedColumnAfterKeyPress[0] != startCellCheck ||
+ selectedColumnAfterKeyPress[selectedColumnAfterKeyPress.length - 1] !=
+ endCellCheck) {
+ System.out.println("Selected Columns: ");
+ for (int columnsSelected : selectedColumnAfterKeyPress) {
+ System.out.println(columnsSelected);
+ }
+ String failureMsg = "Test Failure. Failed to select cells for Ctrl" +
+ " Shift " + key + " selection";
+ throw new RuntimeException(failureMsg);
+ }
+ }
+
+ private static void createAndShowUI() {
+ frame = new JFrame("Test Ctrl Shift RIGHT/LEFT Key Press");
+ table = new JTable(2, 5);
+ table.setColumnSelectionAllowed(true);
+ frame.getContentPane().add(table);
+
+ frame.setSize(200, 200);
+ frame.setLocationRelativeTo(null);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setVisible(true);
+ }
+}
diff --git a/test/jdk/jdk/jfr/api/settings/TestFilterEvents.java b/test/jdk/jdk/jfr/api/settings/TestFilterEvents.java
index 42bfc31767e98..67619fb10b4e9 100644
--- a/test/jdk/jdk/jfr/api/settings/TestFilterEvents.java
+++ b/test/jdk/jdk/jfr/api/settings/TestFilterEvents.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -70,6 +70,7 @@ public static void main(String[] args) throws Exception {
continuous.enable(HTTPGetEvent.class).with("threadNames", "\"unused-threadname-1\"");
assertEquals(0, makeProfilingRecording("\"unused-threadname-2\""));
assertEquals(1, makeProfilingRecording("\"" + Thread.currentThread().getName() + "\""));
+ assertEquals(2, makeCombineControl());
continuous.close();
}
@@ -94,4 +95,32 @@ private static int makeProfilingRecording(String threadNames) throws Exception {
}
}
+ private static int makeCombineControl() throws Exception {
+ try (Recording r1 = new Recording()) {
+ r1.enable(HTTPPostEvent.class).with("uriFilter", "https://www.example.com/list");
+ r1.start();
+
+ try (Recording r2 = new Recording()) {
+ r2.enable(HTTPPostEvent.class).with("uriFilter", "https://www.example.com/get");
+ r2.start();
+
+ HTTPPostEvent e1 = new HTTPPostEvent();
+ e1.uri = "https://www.example.com/list";
+ e1.commit();
+
+ HTTPPostEvent e2 = new HTTPPostEvent();
+ e2.uri = "https://www.example.com/get";
+ e2.commit();
+
+ HTTPPostEvent e3 = new HTTPPostEvent();
+ e3.uri = "https://www.example.com/put";
+ e3.commit();
+ }
+
+ r1.stop();
+
+ return Events.fromRecording(r1).size();
+ }
+ }
+
}
diff --git a/test/jdk/jdk/jfr/jvm/TestLongStringsInPool.java b/test/jdk/jdk/jfr/jvm/TestLongStringsInPool.java
new file mode 100644
index 0000000000000..8ce3fd3859fdb
--- /dev/null
+++ b/test/jdk/jdk/jfr/jvm/TestLongStringsInPool.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.jfr.jvm;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import jdk.jfr.Event;
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.jfr.EventNames;
+
+/**
+ * @test
+ * @summary Verify that duplicate longer strings doesn't take up unneccessary space
+ * @key jfr
+ * @requires vm.hasJFR
+ * @library /test/lib
+ * @run main/othervm jdk.jfr.jvm.TestLongStringsInPool
+ */
+public class TestLongStringsInPool {
+ private static class StringEvent extends Event {
+ String message;
+ }
+
+ public static void main(String[] args) throws Exception {
+ // Create two recordings; first has only one large
+ // string, second has several occurences of the same
+ // string. With long strings (>128 chars) being pooled,
+ // the two recording should be roughly the same size.
+ final int numEvents = 10;
+ final String longString = generateString();
+ final int strLen = longString.length();
+ final StringEvent event = new StringEvent();
+ event.message = longString;
+
+ Recording firstRec = new Recording();
+ firstRec.start();
+ // commit events with empty message (both recordings
+ // will have the same number of events)
+ for (int i = 0; i < numEvents - 1; i++) {
+ event.message = "";
+ event.commit();
+ }
+ // commit 1 event with a long string
+ event.message = longString;
+ event.commit();
+
+ firstRec.stop();
+ Path rec1 = Paths.get(".", "rec1.jfr");
+ firstRec.dump(rec1);
+ firstRec.close();
+
+
+ Recording secondRec = new Recording();
+ secondRec.start();
+ // commit events with the same long string
+ for (int i = 0; i < numEvents - 1; i++) {
+ event.message = longString;
+ event.commit();
+ }
+ // commit 1 event with a long string
+ event.message = longString;
+ event.commit();
+
+ secondRec.stop();
+ Path rec2 = Paths.get(".", "rec2.jfr");
+ secondRec.dump(rec2);
+ secondRec.close();
+
+ // the files aren't exactly the same size, but rec2 should
+ // not take up space for all strings if they're pooled correctly
+ long maxAllowedDiff = (numEvents - 1) * strLen;
+ long diff = Math.abs(Files.size(rec2) - Files.size(rec1));
+
+ Asserts.assertTrue(diff <= maxAllowedDiff, "Size difference between recordings is too large: "+ diff +" > " + maxAllowedDiff);
+ Asserts.assertFalse(RecordingFile.readAllEvents(rec1).isEmpty(), "No events found in recording 1");
+ Asserts.assertFalse(RecordingFile.readAllEvents(rec2).isEmpty(), "No events found in recording 2");
+ Asserts.assertEquals(RecordingFile.readAllEvents(rec1).size(), RecordingFile.readAllEvents(rec2).size(), "The recordings don't have the same number of events");
+ }
+
+ /**
+ * Generate a string of 256 chars length.
+ * @return
+ */
+ private static String generateString() {
+ final StringBuilder builder = new StringBuilder();
+ for (int i = 0; i < 32; i++) {
+ builder.append("abcdefgh");
+ }
+ return builder.toString();
+ }
+}
diff --git a/test/jdk/jdk/jfr/threading/TestStringPoolVirtualThreadPinning.java b/test/jdk/jdk/jfr/threading/TestStringPoolVirtualThreadPinning.java
new file mode 100644
index 0000000000000..0dc1ef8566139
--- /dev/null
+++ b/test/jdk/jdk/jfr/threading/TestStringPoolVirtualThreadPinning.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.jfr.threading;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ThreadFactory;
+
+import jdk.jfr.Event;
+import jdk.jfr.Name;
+import jdk.jfr.Recording;
+import jdk.jfr.consumer.RecordedEvent;
+import jdk.jfr.consumer.RecordedThread;
+import jdk.jfr.consumer.RecordingFile;
+import jdk.test.lib.Asserts;
+import jdk.test.lib.Utils;
+
+/**
+ * @test
+ * @bug 8338417
+ * @summary Tests pinning of virtual threads when the JFR string pool monitor is contended.
+ * @key jfr
+ * @requires vm.hasJFR & vm.continuations
+ * @library /test/lib /test/jdk
+ * @run main/othervm jdk.jfr.threading.TestStringPoolVirtualThreadPinning
+ */
+public class TestStringPoolVirtualThreadPinning {
+
+ private static final int VIRTUAL_THREAD_COUNT = 100_000;
+ private static final int STARTER_THREADS = 10;
+
+ @Name("test.Tester")
+ private static class TestEvent extends Event {
+ private String eventString = Thread.currentThread().getName();
+ }
+
+ /*
+ * During event commit, the thread is in a critical section because it has loaded a carrier thread local event writer object.
+ * For virtual threads, a contended monitor, such as a synchronized block, is a point where a thread could become unmounted.
+ * A monitor guards the JFR string pool, but because of the event writer, remounting a virtual thread onto another carrier is impossible.
+ *
+ * The test provokes JFR string pool monitor contention to exercise explicit pin constructs to ensure the pinning of virtual threads.
+ */
+ public static void main(String... args) throws Exception {
+ try (Recording r = new Recording()) {
+ r.start();
+
+ ThreadFactory factory = Thread.ofVirtual().factory();
+ CompletableFuture>[] c = new CompletableFuture[STARTER_THREADS];
+ for (int j = 0; j < STARTER_THREADS; j++) {
+ c[j] = CompletableFuture.runAsync(() -> {
+ for (int i = 0; i < VIRTUAL_THREAD_COUNT / STARTER_THREADS; i++) {
+ try {
+ Thread vt = factory.newThread(TestStringPoolVirtualThreadPinning::emitEvent);
+ // For an event field string to be placed in the JFR string pool, it must exceed 16 characters.
+ // We use the virtual thread name as the event field string so we can verify the result as a 1-1 mapping.
+ vt.setName("VirtualTestThread-" + i);
+ vt.start();
+ vt.join();
+ } catch (InterruptedException ie) {
+ ie.printStackTrace();
+ }
+ }
+ });
+ }
+ for (int j = 0; j < STARTER_THREADS; j++) {
+ c[j].get();
+ }
+
+ r.stop();
+ Path p = Utils.createTempFile("test", ".jfr");
+ r.dump(p);
+ List events = RecordingFile.readAllEvents(p);
+ Asserts.assertEquals(events.size(), VIRTUAL_THREAD_COUNT, "Expected " + VIRTUAL_THREAD_COUNT + " events");
+ for (RecordedEvent e : events) {
+ RecordedThread t = e.getThread();
+ Asserts.assertNotNull(t);
+ Asserts.assertTrue(t.isVirtual());
+ Asserts.assertEquals(e.getString("eventString"), t.getJavaName());
+ }
+ }
+ }
+
+ private static void emitEvent() {
+ TestEvent t = new TestEvent();
+ t.commit();
+ }
+}
diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTClient.java b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTClient.java
new file mode 100644
index 0000000000000..57f61a6cd8a64
--- /dev/null
+++ b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTClient.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /test/lib
+ * @library /javax/net/ssl/templates
+ * @bug 8242008
+ * @summary Verifies multiple PSKs are used by JSSE
+ * @run main/othervm MultiNSTClient -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.newSessionTicketCount=1
+ * @run main/othervm MultiNSTClient -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.newSessionTicketCount=3
+ * @run main/othervm MultiNSTClient -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.newSessionTicketCount=10
+ * @run main/othervm MultiNSTClient -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=true -Djdk.tls.client.enableSessionTicketExtension=true
+ * @run main/othervm MultiNSTClient -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=false -Djdk.tls.client.enableSessionTicketExtension=true
+ * @run main/othervm MultiNSTClient -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=true -Djdk.tls.client.enableSessionTicketExtension=false
+ * @run main/othervm MultiNSTClient -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.enableSessionTicketExtension=false -Djdk.tls.client.enableSessionTicketExtension=false
+ * @run main/othervm MultiNSTClient -Djdk.tls.client.protocols=TLSv1.2 -Djdk.tls.server.enableSessionTicketExtension=true -Djdk.tls.client.enableSessionTicketExtension=true
+ */
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+import javax.net.ssl.SSLSession;
+import java.util.Arrays;
+import java.util.HexFormat;
+import java.util.List;
+
+/**
+ * This test verifies that multiple NSTs and PSKs are sent by a JSSE server.
+ * Then JSSE client is able to store them all and resume the connection. It
+ * requires specific text in the TLS debugging to verify the success.
+ */
+
+public class MultiNSTClient {
+
+ static HexFormat hex = HexFormat.of();
+
+ public static void main(String[] args) throws Exception {
+
+ if (!args[0].equalsIgnoreCase("p")) {
+ StringBuilder sb = new StringBuilder();
+ Arrays.stream(args).forEach(a -> {
+ sb.append(a);
+ sb.append(" ");
+ });
+ String params = sb.toString();
+ System.setProperty("test.java.opts",
+ "-Dtest.src=" + System.getProperty("test.src") +
+ " -Dtest.jdk=" + System.getProperty("test.jdk") +
+ " -Dtest.root=" + System.getProperty("test.root") +
+ " -Djavax.net.debug=ssl,handshake " + params
+ );
+
+ boolean TLS13 = args[0].contains("1.3");
+
+ System.out.println("test.java.opts: " +
+ System.getProperty("test.java.opts"));
+
+ ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
+ Utils.addTestJavaOpts("MultiNSTClient", "p"));
+
+ OutputAnalyzer output = ProcessTools.executeProcess(pb);
+ System.out.println("I'm here");
+ boolean pass = true;
+ try {
+ List list = output.stderrShouldContain("MultiNST PSK").
+ asLines().stream().filter(s ->
+ s.contains("MultiNST PSK")).toList();
+ List serverPSK = list.stream().filter(s ->
+ s.contains("MultiNST PSK (Server)")).toList();
+ List clientPSK = list.stream().filter(s ->
+ s.contains("MultiNST PSK (Client)")).toList();
+ System.out.println("found list: " + list.size());
+ System.out.println("found server: " + serverPSK.size());
+ serverPSK.stream().forEach(s -> System.out.println("\t" + s));
+ System.out.println("found client: " + clientPSK.size());
+ clientPSK.stream().forEach(s -> System.out.println("\t" + s));
+ for (int i = 0; i < 2; i++) {
+ String svr = serverPSK.getFirst();
+ String cli = clientPSK.getFirst();
+ if (svr.regionMatches(svr.length() - 16, cli, cli.length() - 16, 16)) {
+ System.out.println("entry " + (i + 1) + " match.");
+ } else {
+ System.out.println("entry " + (i + 1) + " server and client PSK didn't match:");
+ System.out.println(" server: " + svr);
+ System.out.println(" client: " + cli);
+ pass = false;
+ }
+ }
+ } catch (RuntimeException e) {
+ System.out.println("No MultiNST PSK found.");
+ pass = false;
+ }
+
+ if (TLS13) {
+ if (!pass) {
+ throw new Exception("Test failed: " + params);
+ }
+ } else {
+ if (pass) {
+ throw new Exception("Test failed: " + params);
+ }
+ }
+ System.out.println("Test Passed");
+ return;
+ }
+
+ TLSBase.Server server = new TLSBase.Server();
+
+ System.out.println("------ Start connection");
+ TLSBase.Client initial = new TLSBase.Client();
+ SSLSession initialSession = initial.connect().getSession();
+ System.out.println("id = " + hex.formatHex(initialSession.getId()));
+ System.out.println("session = " + initialSession);
+
+ System.out.println("------ getNewSession from original client");
+ TLSBase.Client resumClient = new TLSBase.Client(initial);
+ SSLSession resumption = resumClient.connect().getSession();
+ System.out.println("id = " + hex.formatHex(resumption.getId()));
+ System.out.println("session = " + resumption);
+ if (!initialSession.toString().equalsIgnoreCase(resumption.toString())) {
+ throw new Exception("Resumed session did not match");
+ }
+
+ System.out.println("------ Second getNewSession from original client");
+ TLSBase.Client resumClient2 = new TLSBase.Client(initial);
+ resumption = resumClient2.connect().getSession();
+ System.out.println("id = " + hex.formatHex(resumption.getId()));
+ System.out.println("session = " + resumption);
+ if (!initialSession.toString().equalsIgnoreCase(resumption.toString())) {
+ throw new Exception("Resumed session did not match");
+ }
+
+ System.out.println("------ New client connection");
+ TLSBase.Client newConnection = new TLSBase.Client();
+ SSLSession newSession = newConnection.connect().getSession();
+ System.out.println("id = " + hex.formatHex(newSession.getId()));
+ System.out.println("session = " + newSession);
+ if (initialSession.toString().equalsIgnoreCase(newSession.toString())) {
+ throw new Exception("new session is the same as the initial.");
+ }
+
+ System.out.println("------ Closing connections");
+ initial.close();
+ resumClient.close();
+ resumClient2.close();
+ newConnection.close();
+ server.close();
+ System.out.println("------ End");
+ System.exit(0);
+ }
+}
diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTNoSessionCreation.java b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTNoSessionCreation.java
new file mode 100644
index 0000000000000..f80270afd37dd
--- /dev/null
+++ b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTNoSessionCreation.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /test/lib
+ * @library /javax/net/ssl/templates
+ * @bug 8242008
+ * @summary Verifies resumption fails with 0 NSTs and session creation off
+ * @run main/othervm MultiNSTNoSessionCreation -Djdk.tls.client.protocols=TLSv1.3 -Djdk.tls.server.newSessionTicketCount=0
+ * @run main/othervm MultiNSTNoSessionCreation -Djdk.tls.client.protocols=TLSv1.2 -Djdk.tls.server.newSessionTicketCount=0
+ */
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+import java.util.Arrays;
+
+/**
+ * With no NSTs sent by the server, try to resume the session with
+ * setEnabledSessionCreation(false). The test should get an exception and
+ * fail to connect.
+ */
+
+public class MultiNSTNoSessionCreation {
+
+ public static void main(String[] args) throws Exception {
+
+ if (!args[0].equalsIgnoreCase("p")) {
+ StringBuilder sb = new StringBuilder();
+ Arrays.stream(args).forEach(a -> sb.append(a).append(" "));
+ String params = sb.toString();
+ System.setProperty("test.java.opts",
+ "-Dtest.src=" + System.getProperty("test.src") +
+ " -Dtest.jdk=" + System.getProperty("test.jdk") +
+ " -Dtest.root=" + System.getProperty("test.root") +
+ " -Djavax.net.debug=ssl,handshake " + params);
+
+ System.out.println("test.java.opts: " +
+ System.getProperty("test.java.opts"));
+
+ ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
+ Utils.addTestJavaOpts("MultiNSTNoSessionCreation", "p"));
+
+ OutputAnalyzer output = ProcessTools.executeProcess(pb);
+ try {
+ if (output.stderrContains(
+ "(PROTOCOL_VERSION): New session creation is disabled")) {
+ return;
+ }
+ } catch (RuntimeException e) {
+ throw new Exception("Error collecting data", e);
+ }
+ throw new Exception("Disabled creation msg not found");
+ }
+
+ TLSBase.Server server = new TLSBase.Server();
+
+ System.out.println("------ Initial connection");
+ TLSBase.Client initial = new TLSBase.Client();
+ initial.connect();
+ System.out.println(
+ "------ Resume client w/ setEnableSessionCreation set to false");
+ TLSBase.Client resumClient = new TLSBase.Client(initial);
+ resumClient.socket.setEnableSessionCreation(false);
+ resumClient.connect();
+
+ System.out.println("------ Closing connections");
+ initial.close();
+ resumClient.close();
+ server.close();
+ System.out.println("------ End");
+ System.exit(0);
+ }
+}
diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTParallel.java b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTParallel.java
new file mode 100644
index 0000000000000..bff14113ea582
--- /dev/null
+++ b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTParallel.java
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /test/lib
+ * @library /javax/net/ssl/templates
+ * @bug 8242008
+ * @summary Verifies multiple PSKs are used by TLSv1.3
+ * @run main/othervm MultiNSTParallel 10 -Djdk.tls.client.protocols=TLSv1.3
+ */
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+import javax.net.ssl.SSLSession;
+import java.util.ArrayList;
+import java.util.HexFormat;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+
+/**
+ * This test verifies that parallel resumption connections successfully get
+ * a PSK entry and not initiate a full handshake.
+ *
+ * Note: THe first argument after 'MultiNSTParallel' is the ticket count
+ * The test will set 'jdk.tls.server.NewSessionTicketCount` to that number and
+ * will start the same number of resumption client attempts. The ticket count
+ * must be the same or larger than resumption attempts otherwise the queue runs
+ * empty and the test will fail.
+ *
+ * Because this test runs parallel connections, the thread order finish is not
+ * guaranteed. Each client NST id is checked with all server NSTs ids until
+ * a match is found. When a match is found, it is removed from the list to
+ * verify no NST was used more than once.
+ *
+ * TLS 1.2 spec does not specify multiple NST behavior.
+ */
+
+public class MultiNSTParallel {
+
+ static HexFormat hex = HexFormat.of();
+ final static CountDownLatch wait = new CountDownLatch(1);
+
+ static class ClientThread extends Thread {
+ TLSBase.Client client;
+
+ ClientThread(TLSBase.Client c) {
+ client = c;
+ }
+
+ public void run() {
+ String name = Thread.currentThread().getName();
+ SSLSession r;
+ System.err.println("waiting " + Thread.currentThread().getName());
+ try {
+ wait.await();
+ r = new TLSBase.Client(client).connect().getSession();
+ } catch (Exception e) {
+ throw new RuntimeException(name + ": " +e);
+ }
+ StringBuffer sb = new StringBuffer(100);
+ sb.append("(").append(name).append(") id = ");
+ sb.append(hex.formatHex(r.getId()));
+ sb.append("\n(").append(name).append(") session = ").append(r);
+ if (!client.getSession().toString().equalsIgnoreCase(r.toString())) {
+ throw new RuntimeException("(" + name +
+ ") Resumed session did not match");
+ }
+ }
+ }
+
+ static boolean pass = true;
+
+ public static void main(String[] args) throws Exception {
+
+ if (!args[0].equalsIgnoreCase("p")) {
+ int ticketCount = Integer.parseInt(args[0]);
+ StringBuilder sb = new StringBuilder();
+ for (int i = 1; i < args.length; i++) {
+ sb.append(" ").append(args[i]);
+ }
+ String params = sb.toString();
+ System.setProperty("test.java.opts",
+ "-Dtest.src=" + System.getProperty("test.src") +
+ " -Dtest.jdk=" + System.getProperty("test.jdk") +
+ " -Dtest.root=" + System.getProperty("test.root") +
+ " -Djavax.net.debug=ssl,handshake " +
+ " -Djdk.tls.server.newSessionTicketCount=" + ticketCount +
+ params);
+
+ boolean TLS13 = args[1].contains("1.3");
+
+ System.out.println("test.java.opts: " +
+ System.getProperty("test.java.opts"));
+
+ ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
+ Utils.addTestJavaOpts("MultiNSTParallel", "p"));
+
+ OutputAnalyzer output = ProcessTools.executeProcess(pb);
+ try {
+ List list = output.stderrShouldContain("MultiNST PSK").
+ asLines().stream().filter(s ->
+ s.contains("MultiNST PSK")).toList();
+ List sp = list.stream().filter(s ->
+ s.contains("MultiNST PSK (Server)")).toList();
+ List serverPSK = new ArrayList<>(sp.stream().toList());
+ List clientPSK = list.stream().filter(s ->
+ s.contains("MultiNST PSK (Client)")).toList();
+ System.out.println("found list: " + list.size());
+ System.out.println("found server: " + serverPSK.size());
+ serverPSK.stream().forEach(s -> System.out.println("\t" + s));
+ System.out.println("found client: " + clientPSK.size());
+ clientPSK.stream().forEach(s -> System.out.println("\t" + s));
+
+ // Must search all results as order is not guaranteed.
+ clientPSK.stream().forEach(cli -> {
+ for (int i = 0; i < serverPSK.size(); i++) {
+ String svr = serverPSK.get(i);
+ if (svr.regionMatches(svr.length() - 16, cli,
+ cli.length() - 16, 16)) {
+ System.out.println("entry " + (i + 1) + " match.");
+ serverPSK.remove(i);
+ return;
+ }
+ }
+ System.out.println("client entry (" + cli.substring(0, 16) +
+ ") not found in server list");
+ pass = false;
+ });
+ } catch (RuntimeException e) {
+ System.out.println("Error looking at PSK results.");
+ throw new Exception(e);
+ }
+
+ if (TLS13) {
+ if (!pass) {
+ throw new Exception("Test failed: " + params);
+ }
+ } else {
+ if (pass) {
+ throw new Exception("Test failed: " + params);
+ }
+ }
+ System.out.println("Test Passed");
+ return;
+ }
+
+ int ticketCount = Integer.parseInt(
+ System.getProperty("jdk.tls.server.newSessionTicketCount"));
+
+ TLSBase.Server server = new TLSBase.Server();
+
+ System.out.println("------ Start connection");
+ TLSBase.Client initial = new TLSBase.Client();
+ SSLSession initialSession = initial.getSession();
+ System.out.println("id = " + hex.formatHex(initialSession.getId()));
+ System.out.println("session = " + initialSession);
+
+ System.out.println("------ getNewSession from original client");
+
+ ArrayList slist = new ArrayList<>(ticketCount);
+
+ System.out.println("tx " + ticketCount);
+ for (int i = 0; ticketCount > i; i++) {
+ Thread t = new ClientThread(initial);
+ t.setName("Iteration " + i);
+ slist.add(t);
+ t.start();
+ }
+
+ wait.countDown();
+ for (Thread t : slist) {
+ t.join(1000);
+ System.err.println("released: " + t.getName());
+ }
+
+ System.out.println("------ Closing connections");
+ initial.close();
+ server.close();
+ System.out.println("------ End");
+ System.exit(0);
+ }
+}
diff --git a/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTSequence.java b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTSequence.java
new file mode 100644
index 0000000000000..888dba56a5023
--- /dev/null
+++ b/test/jdk/sun/security/ssl/SSLSessionImpl/MultiNSTSequence.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @library /test/lib
+ * @library /javax/net/ssl/templates
+ * @bug 8242008
+ * @summary Verifies sequence of used NST entries from the cache queue.
+ * @run main/othervm MultiNSTSequence -Djdk.tls.server.newSessionTicketCount=2
+ */
+
+import jdk.test.lib.Utils;
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+import javax.net.ssl.SSLSession;
+import java.util.Arrays;
+import java.util.HexFormat;
+import java.util.List;
+
+/**
+ * This test verifies that multiple NSTs take the oldest PSK from the
+ * QueueCacheEntry stored in the TLS Session Cache.
+ *
+ * Note: Beyond 9 iterations the PSK id verification code becomes complicated
+ * with a QueueCacheEntry limit set to retain only the 10 newest entries.
+ *
+ * TLS 1.2 spec does not specify multiple NST behavior.
+ */
+
+public class MultiNSTSequence {
+
+ static HexFormat hex = HexFormat.of();
+ static final int ITERATIONS = 9;
+
+ public static void main(String[] args) throws Exception {
+
+ if (!args[0].equalsIgnoreCase("p")) {
+ StringBuilder sb = new StringBuilder();
+ Arrays.stream(args).forEach(a -> sb.append(a).append(" "));
+ String params = sb.toString();
+ System.setProperty("test.java.opts",
+ "-Dtest.src=" + System.getProperty("test.src") +
+ " -Dtest.jdk=" + System.getProperty("test.jdk") +
+ " -Dtest.root=" + System.getProperty("test.root") +
+ " -Djavax.net.debug=ssl,handshake " + params
+ );
+
+ System.out.println("test.java.opts: " +
+ System.getProperty("test.java.opts"));
+
+ ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
+ Utils.addTestJavaOpts("MultiNSTSequence", "p"));
+
+ OutputAnalyzer output = ProcessTools.executeProcess(pb);
+ boolean pass = true;
+ try {
+ List list = output.stderrShouldContain("MultiNST PSK").
+ asLines().stream().filter(s ->
+ s.contains("MultiNST PSK")).toList();
+ List serverPSK = list.stream().filter(s ->
+ s.contains("MultiNST PSK (Server)")).toList();
+ List clientPSK = list.stream().filter(s ->
+ s.contains("MultiNST PSK (Client)")).toList();
+ System.out.println("found list: " + list.size());
+ System.out.println("found server: " + serverPSK.size());
+ serverPSK.stream().forEach(s -> System.out.println("\t" + s));
+ System.out.println("found client: " + clientPSK.size());
+ clientPSK.stream().forEach(s -> System.out.println("\t" + s));
+ int i;
+ for (i = 0; i < ITERATIONS; i++) {
+ String svr = serverPSK.get(i);
+ String cli = clientPSK.get(i);
+ if (svr.regionMatches(svr.length() - 16, cli, cli.length() - 16, 16)) {
+ System.out.println("entry " + (i + 1) + " match.");
+ } else {
+ System.out.println("entry " + (i + 1) + " server and client PSK didn't match:");
+ System.out.println(" server: " + svr);
+ System.out.println(" client: " + cli);
+ pass = false;
+ }
+ }
+ } catch (RuntimeException e) {
+ System.out.println("Server and Client PSK usage order is not" +
+ " the same.");
+ pass = false;
+ }
+
+ if (!pass) {
+ throw new Exception("Test failed: " + params);
+ }
+ System.out.println("Test Passed");
+ return;
+ }
+
+ TLSBase.Server server = new TLSBase.Server();
+
+ System.out.println("------ Initial connection");
+ TLSBase.Client initial = new TLSBase.Client();
+
+ SSLSession initialSession = initial.connect().getSession();
+ System.out.println("id = " + hex.formatHex(initialSession.getId()));
+ System.out.println("session = " + initialSession);
+
+ System.out.println("------ Resume client");
+ for (int i = 0; i < ITERATIONS; i++) {
+ SSLSession r = new TLSBase.Client(initial).connect().getSession();
+ StringBuilder sb = new StringBuilder(100);
+ sb.append("Iteration: ").append(i);
+ sb.append("\tid = ").append(hex.formatHex(r.getId()));
+ sb.append("\tsession = ").append(r);
+ System.out.println(sb);
+ if (!initialSession.toString().equalsIgnoreCase(r.toString())) {
+ throw new Exception("Resumed session did not match");
+ }
+ }
+
+ System.out.println("------ Closing connections");
+ initial.close();
+ server.close();
+ System.out.println("------ End");
+ System.exit(0);
+ }
+}
diff --git a/test/langtools/tools/javac/parser/JavacParserTest.java b/test/langtools/tools/javac/parser/JavacParserTest.java
index 547de1088b460..40ab577a5d135 100644
--- a/test/langtools/tools/javac/parser/JavacParserTest.java
+++ b/test/langtools/tools/javac/parser/JavacParserTest.java
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 7073631 7159445 7156633 8028235 8065753 8205418 8205913 8228451 8237041 8253584 8246774 8256411 8256149 8259050 8266436 8267221 8271928 8275097 8293897 8295401 8304671 8310326 8312093 8312204 8315452 8337976
+ * @bug 7073631 7159445 7156633 8028235 8065753 8205418 8205913 8228451 8237041 8253584 8246774 8256411 8256149 8259050 8266436 8267221 8271928 8275097 8293897 8295401 8304671 8310326 8312093 8312204 8315452 8337976 8324859
* @summary tests error and diagnostics positions
* @author Jan Lahoda
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -2483,6 +2483,537 @@ public class Test {
codes);
}
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion1() throws IOException {
+ String code = """
+ package tests;
+ public class TestB {
+ public static boolean test() // missing open brace
+ return true;
+ }
+ public static boolean test2() {
+ return true;
+ }
+ }""";
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion1: " + codes,
+ List.of("3:33:compiler.err.expected2"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+ \n\
+ public class TestB {
+ \n\
+ public static boolean test() {
+ return true;
+ }
+ \n\
+ public static boolean test2() {
+ return true;
+ }
+ }""");
+ }
+
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion2() throws IOException {
+ String code = """
+ package tests;
+ public class TestB {
+ public static boolean test() // missing open brace
+
+ public static boolean test2() {
+ return true;
+ }
+ } """;
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion2: " + codes,
+ List.of("3:33:compiler.err.expected2"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+ \n\
+ public class TestB {
+ \n\
+ public static boolean test();
+ \n\
+ public static boolean test2() {
+ return true;
+ }
+ }""");
+ }
+
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion3() throws IOException {
+ String code = """
+ package tests;
+ public class TestB {
+ public static boolean test() // missing open brace
+ }
+ """;
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion3: " + codes,
+ List.of("3:33:compiler.err.expected2"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+ \n\
+ public class TestB {
+ \n\
+ public static boolean test();
+ }""");
+ }
+
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion4() throws IOException {
+ String code = """
+ package tests;
+ public class TestB {
+ public static boolean test() // missing open brace
+ }
+ }
+ """;
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion4: " + codes,
+ List.of("3:33:compiler.err.expected2"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+ \n\
+ public class TestB {
+ \n\
+ public static boolean test() {
+ }
+ }""");
+ }
+
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion5() throws IOException {
+ String code = """
+ package tests;
+ public class TestB {
+ public static boolean test(String,
+ }
+ class T {}
+ """;
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion5: " + codes,
+ List.of("3:38:compiler.err.expected",
+ "4:1:compiler.err.illegal.start.of.type"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+ \n\
+ public class TestB {
+ \n\
+ public static boolean test(String , (ERROR: ) );
+ }
+ class T {
+ }""");
+ }
+
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion6() throws IOException {
+ String code = """
+ package tests;
+ public class TestB {
+ private Object testMethod(final String arg1 final String arg2) {
+ return null;
+ }
+ }
+ """;
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion5: " + codes,
+ List.of("3:48:compiler.err.expected3",
+ "3:66:compiler.err.expected"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+ \n\
+ public class TestB {
+ \n\
+ private Object testMethod(final String arg1);
+ final String arg2;
+ {
+ return null;
+ }
+ }""");
+ }
+
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion7() throws IOException {
+ //after 'default' attribute value, only semicolon (';') is expected,
+ //not left brace ('{'):
+ String code = """
+ package tests;
+ public @interface A {
+ public String value() default ""
+ }
+ """;
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion5: " + codes,
+ List.of("3:37:compiler.err.expected"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+ \n\
+ public @interface A {
+ \n\
+ public String value() default "";
+ }""");
+ }
+
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion10() throws IOException {
+ String code = """
+ package tests;
+ public class TestB {
+ public static boolean test() // missing open brace
+ String s = "";
+ return s.isEmpty();
+ }
+ public static boolean test2() {
+ return true;
+ }
+ }""";
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion1: " + codes,
+ List.of("3:33:compiler.err.expected2"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+
+ public class TestB {
+ \n\
+ public static boolean test() {
+ String s = "";
+ return s.isEmpty();
+ }
+ \n\
+ public static boolean test2() {
+ return true;
+ }
+ }""");
+ }
+
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion11() throws IOException {
+ String code = """
+ package tests;
+ public class TestB {
+ public static boolean test() // missing open brace
+ String s = ""; //field declaration
+ public static boolean test2() {
+ return true;
+ }
+ }""";
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion1: " + codes,
+ List.of("3:33:compiler.err.expected2"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+ \n\
+ public class TestB {
+ \n\
+ public static boolean test();
+ String s = "";
+ \n\
+ public static boolean test2() {
+ return true;
+ }
+ }""");
+ }
+
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion12() throws IOException {
+ String code = """
+ package tests;
+ public class TestB {
+ public static boolean test() // missing open brace
+ final String s = "";
+ return s.isEmpty();
+ }
+ public static boolean test2() {
+ return true;
+ }
+ }""";
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion1: " + codes,
+ List.of("3:33:compiler.err.expected2"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+ \n\
+ public class TestB {
+ \n\
+ public static boolean test() {
+ final String s = "";
+ return s.isEmpty();
+ }
+ \n\
+ public static boolean test2() {
+ return true;
+ }
+ }""");
+ }
+
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion13() throws IOException {
+ String code = """
+ package tests;
+ public class TestB {
+ public static boolean test() // missing open brace
+ final String s = ""; //field declaration?
+ public static boolean test2() {
+ return true;
+ }
+ }""";
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion1: " + codes,
+ List.of("3:33:compiler.err.expected2"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+ \n\
+ public class TestB {
+ \n\
+ public static boolean test();
+ final String s = "";
+ \n\
+ public static boolean test2() {
+ return true;
+ }
+ }""");
+ }
+
+ @Test //JDK-8324859
+ void testImplicitlyDeclaredClassesConfusion14() throws IOException {
+ String code = """
+ package tests;
+ public class TestB {
+ public static boolean test() // missing open brace
+ String s = "";
+ s.length();
+ if (true); //force parse as block
+ public static boolean test2() {
+ return true;
+ }
+ }""";
+ DiagnosticCollector coll =
+ new DiagnosticCollector<>();
+ JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, fm, coll,
+ List.of("--enable-preview", "--source", SOURCE_VERSION),
+ null, Arrays.asList(new MyFileObject(code)));
+ CompilationUnitTree cut = ct.parse().iterator().next();
+
+ List codes = new LinkedList<>();
+
+ for (Diagnostic extends JavaFileObject> d : coll.getDiagnostics()) {
+ codes.add(d.getLineNumber() + ":" + d.getColumnNumber() + ":" + d.getCode());
+ }
+
+ assertEquals("testImplicitlyDeclaredClassesConfusion1: " + codes,
+ List.of("3:33:compiler.err.expected2",
+ "7:5:compiler.err.illegal.start.of.expr"),
+ codes);
+ String result = toStringWithErrors(cut).replaceAll("\\R", "\n");
+ System.out.println("RESULT\n" + result);
+ assertEquals("incorrect AST",
+ result,
+ """
+ package tests;
+ \n\
+ public class TestB {
+ \n\
+ public static boolean test() {
+ String s = "";
+ s.length();
+ if (true) ;
+ (ERROR: );
+ }
+ \n\
+ public static boolean test2() {
+ return true;
+ }
+ }""");
+ }
+
void run(String[] args) throws Exception {
int passed = 0, failed = 0;
final Pattern p = (args != null && args.length > 0)
diff --git a/test/langtools/tools/javac/recovery/AttrRecovery.java b/test/langtools/tools/javac/recovery/AttrRecovery.java
index 629cef45c6270..19325420af7f9 100644
--- a/test/langtools/tools/javac/recovery/AttrRecovery.java
+++ b/test/langtools/tools/javac/recovery/AttrRecovery.java
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8301580 8322159 8333107 8332230
+ * @bug 8301580 8322159 8333107 8332230 8338678
* @summary Verify error recovery w.r.t. Attr
* @library /tools/lib
* @enablePreview
@@ -34,9 +34,23 @@
* @run main AttrRecovery
*/
+import com.sun.source.tree.VariableTree;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.source.util.TreePathScanner;
+import com.sun.source.util.Trees;
import java.nio.file.Path;
+import java.util.IdentityHashMap;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
+import java.util.stream.Collectors;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.DeclaredType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
+import javax.tools.Diagnostic;
import toolbox.JavacTask;
import toolbox.Task.Expect;
@@ -234,4 +248,80 @@ public Undefined g(Undefined u) {
}
}
+ @Test
+ public void testParameterizedErroneousType() throws Exception {
+ String code = """
+ public class C {
+ Undefined1 variable1;
+ }
+ """;
+ Path curPath = Path.of(".");
+ List actual = new JavacTask(tb)
+ .options("-XDrawDiagnostics")
+ .sources(code)
+ .outdir(curPath)
+ .callback(task -> {
+ task.addTaskListener(new TaskListener() {
+ @Override
+ public void finished(TaskEvent e) {
+ Trees trees = Trees.instance(task);
+
+ if (e.getKind() == TaskEvent.Kind.ANALYZE) {
+ new TreePathScanner() {
+ @Override
+ public Void visitVariable(VariableTree tree, Void p) {
+ VariableElement var = (VariableElement) trees.getElement(getCurrentPath());
+
+ trees.printMessage(Diagnostic.Kind.NOTE, type2String(var.asType()), tree, e.getCompilationUnit());
+
+ return super.visitVariable(tree, p);
+ }
+ }.scan(e.getCompilationUnit(), null);
+ }
+ }
+ Map identityRename = new IdentityHashMap<>();
+ String type2String(TypeMirror type) {
+ StringBuilder result = new StringBuilder();
+
+ result.append(type.getKind());
+ result.append(":");
+ result.append(type.toString());
+
+ if (type.getKind() == TypeKind.DECLARED ||
+ type.getKind() == TypeKind.ERROR) {
+ DeclaredType dt = (DeclaredType) type;
+ Element el = task.getTypes().asElement(dt);
+ result.append(":");
+ result.append(el.toString());
+ if (!dt.getTypeArguments().isEmpty()) {
+ result.append(dt.getTypeArguments()
+ .stream()
+ .map(tm -> type2String(tm))
+ .collect(Collectors.joining(", ", "<", ">")));
+ }
+ } else {
+ throw new AssertionError(type.getKind().name());
+ }
+
+ return result.toString();
+ }
+ });
+ })
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(OutputKind.DIRECT);
+
+ List expected = List.of(
+ "C.java:2:5: compiler.err.cant.resolve.location: kindname.class, Undefined1, , , (compiler.misc.location: kindname.class, C, null)",
+ "C.java:2:16: compiler.err.cant.resolve.location: kindname.class, Undefined2, , , (compiler.misc.location: kindname.class, C, null)",
+ "C.java:2:28: compiler.err.cant.resolve.location: kindname.class, Undefined3, , , (compiler.misc.location: kindname.class, C, null)",
+ "C.java:2:40: compiler.note.proc.messager: ERROR:Undefined1:Undefined1",
+ "3 errors"
+ );
+
+ if (!Objects.equals(actual, expected)) {
+ error("Expected: " + expected + ", but got: " + actual);
+ }
+ }
+
}
diff --git a/test/lib/jdk/test/lib/NetworkConfiguration.java b/test/lib/jdk/test/lib/NetworkConfiguration.java
index 8ea10ede6a4a2..3532bb1a3ee20 100644
--- a/test/lib/jdk/test/lib/NetworkConfiguration.java
+++ b/test/lib/jdk/test/lib/NetworkConfiguration.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -127,8 +127,8 @@ public static boolean isSameInterface(NetworkInterface ni1, NetworkInterface ni2
public static boolean isTestable(NetworkInterface nif) {
if (Platform.isOSX()) {
- if (nif.getName().contains("awdl")) {
- return false; // exclude awdl
+ if (nif.getName().contains("awdl") || nif.getName().contains("docker")) {
+ return false; // exclude awdl or docker
}
// filter out interfaces that only have link-local IPv6 addresses
// on macOS interfaces like 'en6' fall in this category and
@@ -145,6 +145,13 @@ public static boolean isTestable(NetworkInterface nif) {
return false;
}
}
+
+ if (Platform.isLinux()) {
+ String dName = nif.getDisplayName();
+ if (dName != null && dName.contains("docker")) {
+ return false;
+ }
+ }
return true;
}
diff --git a/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java b/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java
index bd68e582e6a2f..62883efb8bb89 100644
--- a/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java
+++ b/test/micro/org/openjdk/bench/java/util/concurrent/Maps.java
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2014, 2022, 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -35,6 +36,7 @@
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
+import java.util.Enumeration;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@@ -127,6 +129,21 @@ public ConcurrentHashMap testConcurrentHashMapPutAll() {
return map;
}
+ @Benchmark
+ public int testConcurrentHashMapIterators() {
+ ConcurrentHashMap map = (ConcurrentHashMap) staticMap;
+ int sum = 0;
+ Enumeration it = map.elements();
+ while (it.hasMoreElements()) {
+ sum += (int) it.nextElement();
+ }
+ it = map.keys();
+ while (it.hasMoreElements()) {
+ sum += (int) it.nextElement();
+ }
+ return sum;
+ }
+
private static class SimpleRandom {
private final static long multiplier = 0x5DEECE66DL;
private final static long addend = 0xBL;