diff --git a/closed/src/java.base/share/classes/jdk/crypto/jniprovider/NativeCrypto.java b/closed/src/java.base/share/classes/jdk/crypto/jniprovider/NativeCrypto.java index d2132df6398..096af2951ed 100644 --- a/closed/src/java.base/share/classes/jdk/crypto/jniprovider/NativeCrypto.java +++ b/closed/src/java.base/share/classes/jdk/crypto/jniprovider/NativeCrypto.java @@ -33,8 +33,6 @@ import jdk.internal.reflect.Reflection; import jdk.internal.reflect.CallerSensitive; -import sun.security.action.GetPropertyAction; - /*[IF CRIU_SUPPORT]*/ import openj9.internal.criu.InternalCRIUSupport; /*[ENDIF] CRIU_SUPPORT */ @@ -65,10 +63,10 @@ public class NativeCrypto { private static final Cleaner ECKeyCleaner = CleanerFactory.cleaner(); private static final boolean useNativeCrypto = Boolean.parseBoolean( - GetPropertyAction.privilegedGetProperty("jdk.nativeCrypto", "true")); + System.getProperty("jdk.nativeCrypto", "true")); private static final boolean traceEnabled = Boolean.parseBoolean( - GetPropertyAction.privilegedGetProperty("jdk.nativeCryptoTrace", "false")); + System.getProperty("jdk.nativeCryptoTrace", "false")); private static final class InstanceHolder { private static final NativeCrypto instance = new NativeCrypto(); @@ -160,7 +158,7 @@ public static final boolean isAlgorithmEnabled(String property, String name) { boolean useNativeAlgorithm = false; if (useNativeCrypto) { useNativeAlgorithm = Boolean.parseBoolean( - GetPropertyAction.privilegedGetProperty(property, "true")); + System.getProperty(property, "true")); } /* * User wants to use the native crypto implementation. Ensure that the native crypto library is enabled. diff --git a/closed/src/java.base/share/classes/openj9/internal/security/RestrictedSecurity.java b/closed/src/java.base/share/classes/openj9/internal/security/RestrictedSecurity.java index eda8eb2b476..9e8d2f23a96 100644 --- a/closed/src/java.base/share/classes/openj9/internal/security/RestrictedSecurity.java +++ b/closed/src/java.base/share/classes/openj9/internal/security/RestrictedSecurity.java @@ -345,9 +345,10 @@ private static void getProfileID(Properties props) { } String defaultMatch = null; boolean profileExists = false; + String profilePrefix = potentialProfileID + '.'; for (Object keyObject : props.keySet()) { if (keyObject instanceof String key) { - if (key.startsWith(potentialProfileID)) { + if (key.startsWith(profilePrefix)) { profileExists = true; if (key.endsWith(".desc.default")) { // Check if property is set to true. diff --git a/closed/src/java.base/share/classes/sun/security/rsa/NativeRSACore.java b/closed/src/java.base/share/classes/sun/security/rsa/NativeRSACore.java index 34c3a28c017..0fededf2d3f 100644 --- a/closed/src/java.base/share/classes/sun/security/rsa/NativeRSACore.java +++ b/closed/src/java.base/share/classes/sun/security/rsa/NativeRSACore.java @@ -37,7 +37,6 @@ import java.security.interfaces.*; import javax.crypto.BadPaddingException; -import sun.security.action.GetPropertyAction; import jdk.crypto.jniprovider.NativeCrypto; import sun.security.jca.JCAUtil; diff --git a/closed/test/jdk/openj9/internal/security/TestProperties.java b/closed/test/jdk/openj9/internal/security/TestProperties.java index c3bfc89e88b..96aebad0261 100644 --- a/closed/test/jdk/openj9/internal/security/TestProperties.java +++ b/closed/test/jdk/openj9/internal/security/TestProperties.java @@ -43,6 +43,15 @@ public class TestProperties { + private static Stream patternMatches_expectedExitValue0() { + return Stream.of( + // 1 - Test property - Same beginnings of the profile name without version. + Arguments.of("Test-Profile-SameStartWithoutVersion", + System.getProperty("test.src") + "/property-java.security", + "(?s)(?=.*Sun)(?=.*\\bSunJCE\\b)(?=.*SunJSSE)") + ); + } + private static Stream patternMatches_expectedExitValue1() { return Stream.of( // 1 - Test profile - base profile misspell properties. @@ -155,6 +164,19 @@ private static Stream patternMatches_expectedExitValue1() { ); } + @ParameterizedTest + @MethodSource("patternMatches_expectedExitValue0") + public void shouldContain_expectedExitValue0(String customprofile, String securityPropertyFile, String expected) throws Exception { + OutputAnalyzer outputAnalyzer = ProcessTools.executeTestJava( + "-Dsemeru.fips=true", + "-Dsemeru.customprofile=" + customprofile, + "-Djava.security.properties=" + securityPropertyFile, + "TestProperties" + ); + outputAnalyzer.reportDiagnosticSummary(); + outputAnalyzer.shouldHaveExitValue(0).shouldMatch(expected); + } + @ParameterizedTest @MethodSource("patternMatches_expectedExitValue1") public void shouldContain_expectedExitValue1(String customprofile, String securityPropertyFile, String expected) throws Exception { diff --git a/closed/test/jdk/openj9/internal/security/property-java.security b/closed/test/jdk/openj9/internal/security/property-java.security index 490d33e1594..4e84d4299af 100644 --- a/closed/test/jdk/openj9/internal/security/property-java.security +++ b/closed/test/jdk/openj9/internal/security/property-java.security @@ -525,3 +525,39 @@ RestrictedSecurity.Test-Profile-ConstraintChanged_3.Base.jce.provider.1 = com.s RestrictedSecurity.Test-Profile-ConstraintChanged_3.Base.securerandom.provider = OpenJCEPlusFIPS RestrictedSecurity.Test-Profile-ConstraintChanged_3.Base.securerandom.algorithm = SHA512DRBG + +# +# Test-Profile-SameStartWithoutVersion +# Test property - Same beginnings of the profile name without version +# +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.desc.name = Test-Profile-SameStartWithoutVersion +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.desc.default = true +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.desc.fips = true +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.desc.hash = SHA256:2c893d75043da09c3dba8d8b24cb71dc1c7ceac5fb8bf362a35847418a933a06 +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.desc.number = Certificate #XXX +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.desc.policy = https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/ +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.desc.sunsetDate = 2026-09-21 +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.fips.mode = 140-3 + +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.jce.provider.1 = sun.security.provider.Sun +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.jce.provider.2 = com.sun.crypto.provider.SunJCE +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.jce.provider.3 = sun.security.ssl.SunJSSE + +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.securerandom.provider = OpenJCEPlusFIPS +RestrictedSecurity.Test-Profile-SameStartWithoutVersion.securerandom.algorithm = SHA512DRBG + +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.desc.name = Test-Profile-SameStartWithoutVersionPart +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.desc.default = true +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.desc.fips = true +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.desc.hash = SHA256:2c893d75043da09c3dba8d8b24cb71dc1c7ceac5fb8bf362a35847418a933a06 +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.desc.number = Certificate #XXX +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.desc.policy = https://csrc.nist.gov/projects/cryptographic-module-validation-program/certificate/ +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.desc.sunsetDate = 2026-09-21 +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.fips.mode = 140-3 + +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.jce.provider.1 = sun.security.provider.Sun +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.jce.provider.2 = com.sun.crypto.provider.SunJCE +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.jce.provider.3 = sun.security.ssl.SunJSSE + +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.securerandom.provider = OpenJCEPlusFIPS +RestrictedSecurity.Test-Profile-SameStartWithoutVersionPart.securerandom.algorithm = SHA512DRBG diff --git a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java index f610eefe3b6..3aa679bb9b0 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java @@ -39,7 +39,6 @@ import jdk.crypto.jniprovider.NativeCrypto; import jdk.internal.util.StaticProperty; -import sun.security.action.GetPropertyAction; /* * The "SunJCE" Cryptographic Service Provider. diff --git a/src/java.base/share/classes/java/lang/ScopedValue.java b/src/java.base/share/classes/java/lang/ScopedValue.java index ac9b598b531..3730326ee3c 100644 --- a/src/java.base/share/classes/java/lang/ScopedValue.java +++ b/src/java.base/share/classes/java/lang/ScopedValue.java @@ -38,7 +38,6 @@ import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.Hidden; import jdk.internal.vm.ScopedValueContainer; -import sun.security.action.GetPropertyAction; /** * A value that may be safely and efficiently shared to methods without using method @@ -740,7 +739,7 @@ private static final class Cache { static { final String propertyName = "java.lang.ScopedValue.cacheSize"; - var sizeString = GetPropertyAction.privilegedGetProperty(propertyName, "16"); + var sizeString = System.getProperty(propertyName, "16"); var cacheSize = Integer.valueOf(sizeString); if (cacheSize < 2 || cacheSize > MAX_CACHE_SIZE) { cacheSize = MAX_CACHE_SIZE; diff --git a/src/java.base/share/classes/java/lang/StackStreamFactory.java b/src/java.base/share/classes/java/lang/StackStreamFactory.java index e2ec089e30d..404a74e96c7 100644 --- a/src/java.base/share/classes/java/lang/StackStreamFactory.java +++ b/src/java.base/share/classes/java/lang/StackStreamFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, 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 @@ -45,7 +45,6 @@ import java.util.stream.StreamSupport; import jdk.internal.vm.Continuation; import jdk.internal.vm.ContinuationScope; -import sun.security.action.GetPropertyAction; import static java.lang.StackStreamFactory.WalkerState.*; @@ -82,13 +81,8 @@ private StackStreamFactory() {} @Native private static final int SHOW_HIDDEN_FRAMES = 0x20; // LambdaForms are hidden by the VM @Native private static final int FILL_LIVE_STACK_FRAMES = 0x100; - /* - * For Throwable to use StackWalker, set useNewThrowable to true. - * Performance work and extensive testing is needed to replace the - * VM built-in backtrace filled in Throwable with the StackWalker. - */ static final boolean isDebug = - "true".equals(GetPropertyAction.privilegedGetProperty("stackwalk.debug")); + "true".equals(System.getProperty("stackwalk.debug")); static StackFrameTraverser makeStackTraverser(StackWalker walker, Function, ? extends T> function) diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index e5e8d4df27a..11c77d48bf0 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -55,6 +55,7 @@ import java.util.ResourceBundle; import java.util.Set; import java.util.concurrent.Executor; +import java.util.concurrent.ScheduledExecutorService; import java.util.function.Supplier; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; @@ -2304,6 +2305,10 @@ public Executor virtualThreadDefaultScheduler() { return VirtualThread.defaultScheduler(); } + public Stream virtualThreadDelayedTaskSchedulers() { + return VirtualThread.delayedTaskSchedulers(); + } + public StackWalker newStackWalkerInstance(Set options, ContinuationScope contScope, Continuation continuation) { diff --git a/src/java.base/share/classes/java/lang/ThreadLocal.java b/src/java.base/share/classes/java/lang/ThreadLocal.java index 8a9aa7998fd..fae322d2b73 100644 --- a/src/java.base/share/classes/java/lang/ThreadLocal.java +++ b/src/java.base/share/classes/java/lang/ThreadLocal.java @@ -33,7 +33,6 @@ import jdk.internal.misc.CarrierThreadLocal; import jdk.internal.misc.TerminatingThreadLocal; -import sun.security.action.GetPropertyAction; /** * This class provides thread-local variables. These variables differ from @@ -804,7 +803,7 @@ private void expungeStaleEntries() { * a stack trace should be printed when a virtual thread sets a thread local. */ private static boolean traceVirtualThreadLocals() { - String propValue = GetPropertyAction.privilegedGetProperty("jdk.traceVirtualThreadLocals"); + String propValue = System.getProperty("jdk.traceVirtualThreadLocals"); return (propValue != null) && (propValue.isEmpty() || Boolean.parseBoolean(propValue)); } diff --git a/src/java.base/share/classes/java/lang/VirtualThread.java b/src/java.base/share/classes/java/lang/VirtualThread.java index 8c1792f01dc..9203e633a62 100644 --- a/src/java.base/share/classes/java/lang/VirtualThread.java +++ b/src/java.base/share/classes/java/lang/VirtualThread.java @@ -29,6 +29,7 @@ */ package java.lang; +import java.util.Arrays; import java.util.Locale; import java.util.Objects; import java.util.concurrent.CountDownLatch; @@ -37,12 +38,12 @@ import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool.ForkJoinWorkerThreadFactory; import java.util.concurrent.ForkJoinTask; -import java.util.concurrent.ForkJoinWorkerThread; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; import jdk.internal.event.VirtualThreadEndEvent; import jdk.internal.event.VirtualThreadStartEvent; import jdk.internal.event.VirtualThreadSubmitFailedEvent; @@ -197,6 +198,13 @@ static Executor defaultScheduler() { return DEFAULT_SCHEDULER; } + /** + * Returns a stream of the delayed task schedulers used to support timed operations. + */ + static Stream delayedTaskSchedulers() { + return Arrays.stream(DELAYED_TASK_SCHEDULERS); + } + /** * Returns the continuation scope used for virtual threads. */ diff --git a/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java b/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java index 8e92ef59a50..45ed2fbbe81 100644 --- a/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java +++ b/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java @@ -456,9 +456,11 @@ default ClassDesc classSymbol() { * * @apiNote * {@code TAG_}-prefixed constants in this class, such as {@link #TAG_INT}, - * describe the possible return values of this method. + * describe the possible return values of this method. The return type is + * {@code int} for consistency with union indicator items in other union + * structures in the {@code class} file format. */ - char tag(); + int tag(); /** * {@return an enum value for an element-value pair} diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java index fdb8b497ff9..5762a92a061 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java @@ -98,7 +98,7 @@ public sealed interface PoolEntry * {@code TAG_}-prefixed constants in this class, such as {@link #TAG_UTF8}, * describe the possible return values of this method. */ - byte tag(); + int tag(); /** * {@return the index within the constant pool corresponding to this entry} diff --git a/src/java.base/share/classes/java/lang/foreign/Linker.java b/src/java.base/share/classes/java/lang/foreign/Linker.java index bfa205e2fad..c8e4cf4746b 100644 --- a/src/java.base/share/classes/java/lang/foreign/Linker.java +++ b/src/java.base/share/classes/java/lang/foreign/Linker.java @@ -852,8 +852,6 @@ static Option firstVariadicArg(int index) { * // use errno * } * } - *

- * This linker option can not be combined with {@link #critical}. * * @param capturedState the names of the values to save * @throws IllegalArgumentException if at least one of the provided diff --git a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index ffd368f47c1..cbcd4a7b433 100644 --- a/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -248,7 +248,7 @@ private byte[] classFileSetup(Consumer config) { return ClassFile.of().build(classEntry, pool, new Consumer<>() { @Override public void accept(ClassBuilder clb) { - clb.withFlags(ACC_ABSTRACT | ACC_SUPER) + clb.withFlags(ACC_FINAL | ACC_SUPER) .withSuperclass(INVOKER_SUPER_DESC) .with(SourceFileAttribute.of(clb.constantPool().utf8Entry(SOURCE_PREFIX + name))); config.accept(clb); diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java index c88cd773090..ec0bd7edd82 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -34,11 +34,9 @@ import jdk.internal.misc.VM; import jdk.internal.ref.CleanerFactory; import sun.invoke.util.Wrapper; -import sun.security.action.GetPropertyAction; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Field; -import java.util.Properties; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.TRACE_METHOD_LINKAGE; diff --git a/src/java.base/share/classes/java/net/IDN.java b/src/java.base/share/classes/java/net/IDN.java index 6f11643264f..0aaac840766 100644 --- a/src/java.base/share/classes/java/net/IDN.java +++ b/src/java.base/share/classes/java/net/IDN.java @@ -66,6 +66,9 @@ * Applications are responsible for taking adequate security measures when using * international domain names. * + *

Unless otherwise specified, passing a {@code null} argument to any method + * in this class will cause a {@link NullPointerException} to be thrown. + * * @spec https://www.rfc-editor.org/info/rfc1122 * RFC 1122: Requirements for Internet Hosts - Communication Layers * @spec https://www.rfc-editor.org/info/rfc1123 diff --git a/src/java.base/share/classes/java/net/InterfaceAddress.java b/src/java.base/share/classes/java/net/InterfaceAddress.java index f5b76ec9f90..979ed9cc7f5 100644 --- a/src/java.base/share/classes/java/net/InterfaceAddress.java +++ b/src/java.base/share/classes/java/net/InterfaceAddress.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, 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 @@ -42,10 +42,9 @@ public class InterfaceAddress { private short maskLength = 0; /* - * Package private constructor. Can't be built directly, instances are - * obtained through the NetworkInterface class. + * This constructor is called via JNI in NetworkInterface.c */ - InterfaceAddress() { + private InterfaceAddress() { } /** diff --git a/src/java.base/share/classes/java/net/Socket.java b/src/java.base/share/classes/java/net/Socket.java index 83c0dec682c..929e99b5303 100644 --- a/src/java.base/share/classes/java/net/Socket.java +++ b/src/java.base/share/classes/java/net/Socket.java @@ -454,6 +454,7 @@ private Socket(SocketAddress address, SocketAddress localAddr, boolean stream) throws IOException { Objects.requireNonNull(address); + assert address instanceof InetSocketAddress; // create the SocketImpl and the underlying socket SocketImpl impl = createImpl(); @@ -463,16 +464,13 @@ private Socket(SocketAddress address, SocketAddress localAddr, boolean stream) this.state = SOCKET_CREATED; try { - if (localAddr != null) + if (localAddr != null) { bind(localAddr); - connect(address); - } catch (IOException | IllegalArgumentException e) { - try { - close(); - } catch (IOException ce) { - e.addSuppressed(ce); } - throw e; + connect(address); + } catch (Throwable throwable) { + closeSuppressingExceptions(throwable); + throw throwable; } } @@ -571,6 +569,10 @@ void setConnected() { /** * Connects this socket to the server. * + *

If the endpoint is an unresolved {@link InetSocketAddress}, or the + * connection cannot be established, then the socket is closed, and an + * {@link IOException} is thrown. + * *

This method is {@linkplain Thread#interrupt() interruptible} in the * following circumstances: *

    @@ -589,6 +591,8 @@ void setConnected() { * @param endpoint the {@code SocketAddress} * @throws IOException if an error occurs during the connection, the socket * is already connected or the socket is closed + * @throws UnknownHostException if the endpoint is an unresolved + * {@link InetSocketAddress} * @throws java.nio.channels.IllegalBlockingModeException * if this socket has an associated channel, * and the channel is in non-blocking mode @@ -605,6 +609,11 @@ public void connect(SocketAddress endpoint) throws IOException { * A timeout of zero is interpreted as an infinite timeout. The connection * will then block until established or an error occurs. * + *

    If the endpoint is an unresolved {@link InetSocketAddress}, the + * connection cannot be established, or the timeout expires before the + * connection is established, then the socket is closed, and an + * {@link IOException} is thrown. + * *

    This method is {@linkplain Thread#interrupt() interruptible} in the * following circumstances: *

      @@ -625,6 +634,8 @@ public void connect(SocketAddress endpoint) throws IOException { * @throws IOException if an error occurs during the connection, the socket * is already connected or the socket is closed * @throws SocketTimeoutException if timeout expires before connecting + * @throws UnknownHostException if the endpoint is an unresolved + * {@link InetSocketAddress} * @throws java.nio.channels.IllegalBlockingModeException * if this socket has an associated channel, * and the channel is in non-blocking mode @@ -644,26 +655,25 @@ public void connect(SocketAddress endpoint, int timeout) throws IOException { if (isClosed(s)) throw new SocketException("Socket is closed"); if (isConnected(s)) - throw new SocketException("already connected"); + throw new SocketException("Already connected"); if (!(endpoint instanceof InetSocketAddress epoint)) throw new IllegalArgumentException("Unsupported address type"); + if (epoint.isUnresolved()) { + var uhe = new UnknownHostException(epoint.getHostName()); + closeSuppressingExceptions(uhe); + throw uhe; + } + InetAddress addr = epoint.getAddress(); - int port = epoint.getPort(); checkAddress(addr, "connect"); try { getImpl().connect(epoint, timeout); - } catch (SocketTimeoutException e) { - throw e; - } catch (InterruptedIOException e) { - Thread thread = Thread.currentThread(); - if (thread.isVirtual() && thread.isInterrupted()) { - close(); - throw new SocketException("Closed by interrupt"); - } - throw e; + } catch (IOException error) { + closeSuppressingExceptions(error); + throw error; } // connect will bind the socket if not previously bound @@ -1589,6 +1599,14 @@ public boolean getReuseAddress() throws SocketException { return ((Boolean) (getImpl().getOption(SocketOptions.SO_REUSEADDR))).booleanValue(); } + private void closeSuppressingExceptions(Throwable parentException) { + try { + close(); + } catch (IOException exception) { + parentException.addSuppressed(exception); + } + } + /** * Closes this socket. *

      diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java index 62ce8020d80..f4ba247caf1 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java @@ -45,6 +45,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.ScheduledExecutorService; import java.util.stream.Stream; import jdk.internal.loader.NativeLibraries; @@ -595,6 +596,11 @@ public interface JavaLangAccess { */ Executor virtualThreadDefaultScheduler(); + /** + * Returns a stream of the delayed task schedulers used for virtual threads. + */ + Stream virtualThreadDelayedTaskSchedulers(); + /** * Creates a new StackWalker */ diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java index 35b9f2dd1bb..3e50773d59e 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractPoolEntry.java @@ -104,7 +104,7 @@ public int hashCode() { return hash; } - public abstract byte tag(); + public abstract int tag(); public int width() { return 1; @@ -181,7 +181,7 @@ enum State { RAW, BYTE, CHAR, STRING } } @Override - public byte tag() { + public int tag() { return TAG_UTF8; } @@ -522,7 +522,7 @@ public static final class ClassEntryImpl extends AbstractNamedEntry implements C } @Override - public byte tag() { + public int tag() { return TAG_CLASS; } @@ -582,7 +582,7 @@ public static final class PackageEntryImpl extends AbstractNamedEntry implements } @Override - public byte tag() { + public int tag() { return TAG_PACKAGE; } @@ -613,7 +613,7 @@ public static final class ModuleEntryImpl extends AbstractNamedEntry implements } @Override - public byte tag() { + public int tag() { return TAG_MODULE; } @@ -645,7 +645,7 @@ public static final class NameAndTypeEntryImpl extends AbstractRefsEntry values) } @Override - public char tag() { + public int tag() { return TAG_ARRAY; } } @@ -201,7 +201,7 @@ public char tag() { public record OfEnumImpl(Utf8Entry className, Utf8Entry constantName) implements AnnotationValue.OfEnum { @Override - public char tag() { + public int tag() { return TAG_ENUM; } } @@ -209,7 +209,7 @@ public char tag() { public record OfAnnotationImpl(Annotation annotation) implements AnnotationValue.OfAnnotation { @Override - public char tag() { + public int tag() { return TAG_ANNOTATION; } } @@ -217,7 +217,7 @@ public char tag() { public record OfClassImpl(Utf8Entry className) implements AnnotationValue.OfClass { @Override - public char tag() { + public int tag() { return TAG_CLASS; } } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/AnnotationReader.java b/src/java.base/share/classes/jdk/internal/classfile/impl/AnnotationReader.java index 5c4058e6dce..8abc221940a 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/AnnotationReader.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/AnnotationReader.java @@ -354,7 +354,7 @@ public static void writeTypeAnnotations(BufWriter buf, List list public static void writeAnnotationValue(BufWriterImpl buf, AnnotationValue value) { var tag = value.tag(); buf.writeU1(tag); - switch (value.tag()) { + switch (tag) { case TAG_BOOLEAN, TAG_BYTE, TAG_CHAR, TAG_DOUBLE, TAG_FLOAT, TAG_INT, TAG_LONG, TAG_SHORT, TAG_STRING -> buf.writeIndex(((AnnotationValue.OfConstant) value).constant()); case TAG_CLASS -> buf.writeIndex(((AnnotationValue.OfClass) value).className()); diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index 97417efaa8c..a52881b047b 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -889,23 +889,27 @@ public void setAtIndex(AddressLayout layout, long index, MemorySegment value) { layout.varHandle().set((MemorySegment)this, index * layout.byteSize(), value); } + @ForceInline @Override public String getString(long offset) { return getString(offset, sun.nio.cs.UTF_8.INSTANCE); } + @ForceInline @Override public String getString(long offset, Charset charset) { Objects.requireNonNull(charset); return StringSupport.read(this, offset, charset); } + @ForceInline @Override public void setString(long offset, String str) { Objects.requireNonNull(str); setString(offset, str, sun.nio.cs.UTF_8.INSTANCE); } + @ForceInline @Override public void setString(long offset, String str, Charset charset) { Objects.requireNonNull(charset); diff --git a/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java b/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java index d928f8fc425..068db1bf593 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java +++ b/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java @@ -28,7 +28,6 @@ import jdk.internal.misc.ScopedMemoryAccess; import jdk.internal.util.Architecture; import jdk.internal.util.ArraysSupport; -import jdk.internal.util.ByteArrayLittleEndian; import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.Stable; @@ -50,6 +49,7 @@ public final class SegmentBulkOperations { private SegmentBulkOperations() {} private static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess(); + private static final long LONG_MASK = ~7L; // The last three bits are zero // All the threshold values below MUST be a power of two and should preferably be // greater or equal to 2^3. @@ -75,21 +75,21 @@ public static MemorySegment fill(AbstractMemorySegmentImpl dst, byte value) { int offset = 0; // 0...0X...X000 final int limit = (int) (dst.length & (NATIVE_THRESHOLD_FILL - 8)); - for (; offset < limit; offset += 8) { + for (; offset < limit; offset += Long.BYTES) { SCOPED_MEMORY_ACCESS.putLongUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + offset, longValue, !Architecture.isLittleEndian()); } int remaining = (int) dst.length - limit; // 0...0X00 - if (remaining >= 4) { + if (remaining >= Integer.BYTES) { SCOPED_MEMORY_ACCESS.putIntUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + offset, (int) longValue, !Architecture.isLittleEndian()); - offset += 4; - remaining -= 4; + offset += Integer.BYTES; + remaining -= Integer.BYTES; } // 0...00X0 - if (remaining >= 2) { + if (remaining >= Short.BYTES) { SCOPED_MEMORY_ACCESS.putShortUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + offset, (short) longValue, !Architecture.isLittleEndian()); - offset += 2; - remaining -= 2; + offset += Short.BYTES; + remaining -= Short.BYTES; } // 0...000X if (remaining == 1) { @@ -123,26 +123,26 @@ public static void copy(AbstractMemorySegmentImpl src, long srcOffset, // is an overlap, we could tolerate one particular direction of overlap (but not the other). // 0...0X...X000 - final int limit = (int) (size & (NATIVE_THRESHOLD_COPY - 8)); + final int limit = (int) (size & (NATIVE_THRESHOLD_COPY - Long.BYTES)); int offset = 0; - for (; offset < limit; offset += 8) { + for (; offset < limit; offset += Long.BYTES) { final long v = SCOPED_MEMORY_ACCESS.getLongUnaligned(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcOffset + offset, !Architecture.isLittleEndian()); SCOPED_MEMORY_ACCESS.putLongUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstOffset + offset, v, !Architecture.isLittleEndian()); } int remaining = (int) size - offset; // 0...0X00 - if (remaining >= 4) { + if (remaining >= Integer.BYTES) { final int v = SCOPED_MEMORY_ACCESS.getIntUnaligned(src.sessionImpl(), src.unsafeGetBase(),src.unsafeGetOffset() + srcOffset + offset, !Architecture.isLittleEndian()); SCOPED_MEMORY_ACCESS.putIntUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstOffset + offset, v, !Architecture.isLittleEndian()); - offset += 4; - remaining -= 4; + offset += Integer.BYTES; + remaining -= Integer.BYTES; } // 0...00X0 - if (remaining >= 2) { + if (remaining >= Short.BYTES) { final short v = SCOPED_MEMORY_ACCESS.getShortUnaligned(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcOffset + offset, !Architecture.isLittleEndian()); SCOPED_MEMORY_ACCESS.putShortUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstOffset + offset, v, !Architecture.isLittleEndian()); - offset += 2; - remaining -=2; + offset += Short.BYTES; + remaining -= Short.BYTES; } // 0...000X if (remaining == 1) { @@ -202,9 +202,9 @@ public static int contentHash(AbstractMemorySegmentImpl segment, long fromOffset return 1; } int result = 1; - final long longBytes = length & ((1L << 62) - 8); + final long longBytes = length & LONG_MASK; final long limit = fromOffset + longBytes; - for (; fromOffset < limit; fromOffset += 8) { + for (; fromOffset < limit; fromOffset += Long.BYTES) { long val = SCOPED_MEMORY_ACCESS.getLongUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + fromOffset, !Architecture.isLittleEndian()); result = result * POWERS_OF_31[7] + ((byte) (val >>> 56)) * POWERS_OF_31[6] @@ -218,24 +218,24 @@ public static int contentHash(AbstractMemorySegmentImpl segment, long fromOffset } int remaining = (int) (length - longBytes); // 0...0X00 - if (remaining >= 4) { + if (remaining >= Integer.BYTES) { int val = SCOPED_MEMORY_ACCESS.getIntUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + fromOffset, !Architecture.isLittleEndian()); result = result * POWERS_OF_31[3] + ((byte) (val >>> 24)) * POWERS_OF_31[2] + ((byte) (val >>> 16)) * POWERS_OF_31[1] + ((byte) (val >>> 8)) * POWERS_OF_31[0] + ((byte) val); - fromOffset += 4; - remaining -= 4; + fromOffset += Integer.BYTES; + remaining -= Integer.BYTES; } // 0...00X0 - if (remaining >= 2) { + if (remaining >= Short.BYTES) { short val = SCOPED_MEMORY_ACCESS.getShortUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + fromOffset, !Architecture.isLittleEndian()); result = result * POWERS_OF_31[1] + ((byte) (val >>> 8)) * POWERS_OF_31[0] + ((byte) val); - fromOffset += 2; - remaining -= 2; + fromOffset += Short.BYTES; + remaining -= Short.BYTES; } // 0...000X if (remaining == 1) { @@ -288,7 +288,7 @@ private static long mismatch(AbstractMemorySegmentImpl src, long srcFromOffset, long start, int length, boolean srcAndDstBytesDiffer) { int offset = 0; final int limit = length & (NATIVE_THRESHOLD_MISMATCH - 8); - for (; offset < limit; offset += 8) { + for (; offset < limit; offset += Long.BYTES) { final long s = SCOPED_MEMORY_ACCESS.getLongUnaligned(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcFromOffset + offset, false); final long d = SCOPED_MEMORY_ACCESS.getLongUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstFromOffset + offset, false); if (s != d) { @@ -298,24 +298,24 @@ private static long mismatch(AbstractMemorySegmentImpl src, long srcFromOffset, int remaining = length - offset; // 0...0X00 - if (remaining >= 4) { + if (remaining >= Integer.BYTES) { final int s = SCOPED_MEMORY_ACCESS.getIntUnaligned(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcFromOffset + offset, false); final int d = SCOPED_MEMORY_ACCESS.getIntUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstFromOffset + offset, false); if (s != d) { return start + offset + mismatch(s, d); } - offset += 4; - remaining -= 4; + offset += Integer.BYTES; + remaining -= Integer.BYTES; } // 0...00X0 - if (remaining >= 2) { + if (remaining >= Short.BYTES) { final short s = SCOPED_MEMORY_ACCESS.getShortUnaligned(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcFromOffset + offset, false); final short d = SCOPED_MEMORY_ACCESS.getShortUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstFromOffset + offset, false); if (s != d) { return start + offset + mismatch(s, d); } - offset += 2; - remaining -= 2; + offset += Short.BYTES; + remaining -= Short.BYTES; } // 0...000X if (remaining == 1) { diff --git a/src/java.base/share/classes/jdk/internal/foreign/StringSupport.java b/src/java.base/share/classes/jdk/internal/foreign/StringSupport.java index 78550c56136..8f182f3b338 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/StringSupport.java +++ b/src/java.base/share/classes/jdk/internal/foreign/StringSupport.java @@ -27,8 +27,10 @@ import jdk.internal.access.JavaLangAccess; import jdk.internal.access.SharedSecrets; -import jdk.internal.foreign.abi.SharedUtils; +import jdk.internal.misc.ScopedMemoryAccess; +import jdk.internal.util.Architecture; import jdk.internal.util.ArraysSupport; +import jdk.internal.vm.annotation.ForceInline; import java.lang.foreign.MemorySegment; import java.nio.charset.Charset; @@ -40,11 +42,14 @@ */ public final class StringSupport { - static final JavaLangAccess JAVA_LANG_ACCESS = SharedSecrets.getJavaLangAccess(); + private static final JavaLangAccess JAVA_LANG_ACCESS = SharedSecrets.getJavaLangAccess(); + private static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess(); + private static final long LONG_MASK = ~7L; // The last three bits are zero private StringSupport() {} - public static String read(MemorySegment segment, long offset, Charset charset) { + @ForceInline + public static String read(AbstractMemorySegmentImpl segment, long offset, Charset charset) { return switch (CharsetKind.of(charset)) { case SINGLE_BYTE -> readByte(segment, offset, charset); case DOUBLE_BYTE -> readShort(segment, offset, charset); @@ -52,7 +57,8 @@ public static String read(MemorySegment segment, long offset, Charset charset) { }; } - public static void write(MemorySegment segment, long offset, Charset charset, String string) { + @ForceInline + public static void write(AbstractMemorySegmentImpl segment, long offset, Charset charset, String string) { switch (CharsetKind.of(charset)) { case SINGLE_BYTE -> writeByte(segment, offset, charset, string); case DOUBLE_BYTE -> writeShort(segment, offset, charset, string); @@ -60,111 +66,183 @@ public static void write(MemorySegment segment, long offset, Charset charset, St } } - private static String readByte(MemorySegment segment, long offset, Charset charset) { - long len = chunkedStrlenByte(segment, offset); - byte[] bytes = new byte[(int)len]; - MemorySegment.copy(segment, JAVA_BYTE, offset, bytes, 0, (int)len); + @ForceInline + private static String readByte(AbstractMemorySegmentImpl segment, long offset, Charset charset) { + final int len = strlenByte(segment, offset, segment.byteSize()); + final byte[] bytes = new byte[len]; + MemorySegment.copy(segment, JAVA_BYTE, offset, bytes, 0, len); return new String(bytes, charset); } - private static void writeByte(MemorySegment segment, long offset, Charset charset, String string) { + @ForceInline + private static void writeByte(AbstractMemorySegmentImpl segment, long offset, Charset charset, String string) { int bytes = copyBytes(string, segment, charset, offset); segment.set(JAVA_BYTE, offset + bytes, (byte)0); } - private static String readShort(MemorySegment segment, long offset, Charset charset) { - long len = chunkedStrlenShort(segment, offset); - byte[] bytes = new byte[(int)len]; - MemorySegment.copy(segment, JAVA_BYTE, offset, bytes, 0, (int)len); + @ForceInline + private static String readShort(AbstractMemorySegmentImpl segment, long offset, Charset charset) { + int len = strlenShort(segment, offset, segment.byteSize()); + byte[] bytes = new byte[len]; + MemorySegment.copy(segment, JAVA_BYTE, offset, bytes, 0, len); return new String(bytes, charset); } - private static void writeShort(MemorySegment segment, long offset, Charset charset, String string) { + @ForceInline + private static void writeShort(AbstractMemorySegmentImpl segment, long offset, Charset charset, String string) { int bytes = copyBytes(string, segment, charset, offset); segment.set(JAVA_SHORT_UNALIGNED, offset + bytes, (short)0); } - private static String readInt(MemorySegment segment, long offset, Charset charset) { - long len = strlenInt(segment, offset); - byte[] bytes = new byte[(int)len]; - MemorySegment.copy(segment, JAVA_BYTE, offset, bytes, 0, (int)len); + @ForceInline + private static String readInt(AbstractMemorySegmentImpl segment, long offset, Charset charset) { + int len = strlenInt(segment, offset, segment.byteSize()); + byte[] bytes = new byte[len]; + MemorySegment.copy(segment, JAVA_BYTE, offset, bytes, 0, len); return new String(bytes, charset); } - private static void writeInt(MemorySegment segment, long offset, Charset charset, String string) { + @ForceInline + private static void writeInt(AbstractMemorySegmentImpl segment, long offset, Charset charset, String string) { int bytes = copyBytes(string, segment, charset, offset); segment.set(JAVA_INT_UNALIGNED, offset + bytes, 0); } /** - * {@return the shortest distance beginning at the provided {@code start} - * to the encountering of a zero byte in the provided {@code segment}} + * {@return the index of the first zero byte beginning at the provided + * {@code fromOffset} to the encountering of a zero byte in the provided + * {@code segment} checking bytes before the {@code toOffset}} *

      - * The method divides the region of interest into three distinct regions: - *

        - *
      • head (access made on a byte-by-byte basis) (if any)
      • - *
      • body (access made with eight bytes at a time at physically 64-bit-aligned memory) (if any)
      • - *
      • tail (access made on a byte-by-byte basis) (if any)
      • - *
      - *

      - * The body is using a heuristic method to determine if a long word - * contains a zero byte. The method might have false positives but - * never false negatives. + * The method is using a heuristic method to determine if a long word contains a + * zero byte. The method might have false positives but never false negatives. *

      * This method is inspired by the `glibc/string/strlen.c` implementation * - * @param segment to examine - * @param start from where examination shall begin + * @param segment to examine + * @param fromOffset from where examination shall begin (inclusive) + * @param toOffset to where examination shall end (exclusive) * @throws IllegalArgumentException if the examined region contains no zero bytes * within a length that can be accepted by a String */ - public static int chunkedStrlenByte(MemorySegment segment, long start) { - - // Handle the first unaligned "head" bytes separately - int headCount = (int)SharedUtils.remainsToAlignment(segment.address() + start, Long.BYTES); - - int offset = 0; - for (; offset < headCount; offset++) { - byte curr = segment.get(JAVA_BYTE, start + offset); - if (curr == 0) { - return offset; + @ForceInline + public static int strlenByte(final AbstractMemorySegmentImpl segment, + final long fromOffset, + final long toOffset) { + final long length = toOffset - fromOffset; + segment.checkBounds(fromOffset, length); + if (length == 0) { + // The state has to be checked explicitly for zero-length segments + segment.scope.checkValidState(); + throw nullNotFound(segment, fromOffset, toOffset); + } + final long longBytes = length & LONG_MASK; + final long longLimit = fromOffset + longBytes; + long offset = fromOffset; + for (; offset < longLimit; offset += Long.BYTES) { + long val = SCOPED_MEMORY_ACCESS.getLongUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + offset, !Architecture.isLittleEndian()); + if (mightContainZeroByte(val)) { + for (int j = 0; j < Long.BYTES; j++) { + if (SCOPED_MEMORY_ACCESS.getByte(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + offset + j) == 0) { + return requireWithinStringSize(offset + j - fromOffset, segment, fromOffset, toOffset); + } + } + } + } + // Handle the tail + for (; offset < toOffset; offset++) { + byte val = SCOPED_MEMORY_ACCESS.getByte(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + offset); + if (val == 0) { + return requireWithinStringSize(offset - fromOffset, segment, fromOffset, toOffset); } } + throw nullNotFound(segment, fromOffset, toOffset); + } - // We are now on a long-aligned boundary so this is the "body" - int bodyCount = bodyCount(segment.byteSize() - start - headCount); - - for (; offset < bodyCount; offset += Long.BYTES) { - // We know we are `long` aligned so, we can save on alignment checking here - long curr = segment.get(JAVA_LONG_UNALIGNED, start + offset); - // Is this a candidate? - if (mightContainZeroByte(curr)) { - for (int j = 0; j < 8; j++) { - if (segment.get(JAVA_BYTE, start + offset + j) == 0) { - return offset + j; + @ForceInline + public static int strlenShort(final AbstractMemorySegmentImpl segment, + final long fromOffset, + final long toOffset) { + final long length = toOffset - fromOffset; + segment.checkBounds(fromOffset, length); + if (length == 0) { + segment.scope.checkValidState(); + throw nullNotFound(segment, fromOffset, toOffset); + } + final long longBytes = length & LONG_MASK; + final long longLimit = fromOffset + longBytes; + long offset = fromOffset; + for (; offset < longLimit; offset += Long.BYTES) { + long val = SCOPED_MEMORY_ACCESS.getLongUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + offset, !Architecture.isLittleEndian()); + if (mightContainZeroShort(val)) { + for (int j = 0; j < Long.BYTES; j += Short.BYTES) { + if (SCOPED_MEMORY_ACCESS.getShortUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + offset + j, !Architecture.isLittleEndian()) == 0) { + return requireWithinStringSize(offset + j - fromOffset, segment, fromOffset, toOffset); } } } } + // Handle the tail + // Prevent over scanning as we step by 2 + final long endScan = toOffset & ~1; // The last bit is zero + for (; offset < endScan; offset += Short.BYTES) { + short val = SCOPED_MEMORY_ACCESS.getShortUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + offset, !Architecture.isLittleEndian()); + if (val == 0) { + return requireWithinStringSize(offset - fromOffset, segment, fromOffset, toOffset); + } + } + throw nullNotFound(segment, fromOffset, toOffset); + } - // Handle the "tail" - return requireWithinArraySize((long) offset + strlenByte(segment, start + offset)); + @ForceInline + public static int strlenInt(final AbstractMemorySegmentImpl segment, + final long fromOffset, + final long toOffset) { + final long length = toOffset - fromOffset; + segment.checkBounds(fromOffset, length); + if (length == 0) { + segment.scope.checkValidState(); + throw nullNotFound(segment, fromOffset, toOffset); + } + final long longBytes = length & LONG_MASK; + final long longLimit = fromOffset + longBytes; + long offset = fromOffset; + for (; offset < longLimit; offset += Long.BYTES) { + long val = SCOPED_MEMORY_ACCESS.getLongUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + offset, !Architecture.isLittleEndian()); + if (mightContainZeroInt(val)) { + for (int j = 0; j < Long.BYTES; j += Integer.BYTES) { + if (SCOPED_MEMORY_ACCESS.getIntUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + offset + j, !Architecture.isLittleEndian()) == 0) { + return requireWithinStringSize(offset + j - fromOffset, segment, fromOffset, toOffset); + } + } + } + } + // Handle the tail + // Prevent over scanning as we step by 4 + final long endScan = toOffset & ~3; // The last two bit are zero + for (; offset < endScan; offset += Integer.BYTES) { + int val = SCOPED_MEMORY_ACCESS.getIntUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + offset, !Architecture.isLittleEndian()); + if (val == 0) { + return requireWithinStringSize(offset - fromOffset, segment, fromOffset, toOffset); + } + } + throw nullNotFound(segment, fromOffset, toOffset); } - /* Bits 63 and N * 8 (N = 1..7) of this number are zero. Call these bits - the "holes". Note that there is a hole just to the left of - each byte, with an extra at the end: + /* + Bits 63 and N * 8 (N = 1..7) of this number are zero. Call these bits + the "holes". Note that there is a hole just to the left of + each byte, with an extra at the end: - bits: 01111110 11111110 11111110 11111110 11111110 11111110 11111110 11111111 - bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE FFFFFFFF GGGGGGGG HHHHHHHH + bits: 01111110 11111110 11111110 11111110 11111110 11111110 11111110 11111111 + bytes: AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD EEEEEEEE FFFFFFFF GGGGGGGG HHHHHHHH - The 1-bits make sure that carries propagate to the next 0-bit. - The 0-bits provide holes for carries to fall into. + The 1-bits make sure that carries propagate to the next 0-bit. + The 0-bits provide holes for carries to fall into. */ private static final long HIMAGIC_FOR_BYTES = 0x8080_8080_8080_8080L; private static final long LOMAGIC_FOR_BYTES = 0x0101_0101_0101_0101L; - static boolean mightContainZeroByte(long l) { + private static boolean mightContainZeroByte(long l) { return ((l - LOMAGIC_FOR_BYTES) & (~l) & HIMAGIC_FOR_BYTES) != 0; } @@ -175,99 +253,40 @@ static boolean mightContainZeroShort(long l) { return ((l - LOMAGIC_FOR_SHORTS) & (~l) & HIMAGIC_FOR_SHORTS) != 0; } - static int requireWithinArraySize(long size) { - if (size > ArraysSupport.SOFT_MAX_ARRAY_LENGTH) { - throw newIaeStringTooLarge(); - } - return (int) size; - } - - static int bodyCount(long remaining) { - return (int) Math.min( - // Make sure we do not wrap around - Integer.MAX_VALUE - Long.BYTES, - // Remaining bytes to consider - remaining) - & -Long.BYTES; // Mask 0xFFFFFFF8 - } + private static final long HIMAGIC_FOR_INTS = 0x8000_0000_8000_0000L; + private static final long LOMAGIC_FOR_INTS = 0x0000_0001_0000_0001L; - private static int strlenByte(MemorySegment segment, long start) { - for (int offset = 0; offset < ArraysSupport.SOFT_MAX_ARRAY_LENGTH; offset += 1) { - byte curr = segment.get(JAVA_BYTE, start + offset); - if (curr == 0) { - return offset; - } - } - throw newIaeStringTooLarge(); + static boolean mightContainZeroInt(long l) { + return ((l - LOMAGIC_FOR_INTS) & (~l) & HIMAGIC_FOR_INTS) != 0; } - /** - * {@return the shortest distance beginning at the provided {@code start} - * to the encountering of a zero short in the provided {@code segment}} - *

      - * Note: The inspected region must be short aligned. - * - * @see #chunkedStrlenByte(MemorySegment, long) for more information - * - * @param segment to examine - * @param start from where examination shall begin - * @throws IllegalArgumentException if the examined region contains no zero shorts - * within a length that can be accepted by a String - */ - public static int chunkedStrlenShort(MemorySegment segment, long start) { - - // Handle the first unaligned "head" bytes separately - int headCount = (int)SharedUtils.remainsToAlignment(segment.address() + start, Long.BYTES); - int offset = 0; - for (; offset < headCount; offset += Short.BYTES) { - short curr = segment.get(JAVA_SHORT_UNALIGNED, start + offset); - if (curr == 0) { - return offset; - } - } - - // We are now on a long-aligned boundary so this is the "body" - int bodyCount = bodyCount(segment.byteSize() - start - headCount); - - for (; offset < bodyCount; offset += Long.BYTES) { - // We know we are `long` aligned so, we can save on alignment checking here - long curr = segment.get(JAVA_LONG_UNALIGNED, start + offset); - // Is this a candidate? - if (mightContainZeroShort(curr)) { - for (int j = 0; j < Long.BYTES; j += Short.BYTES) { - if (segment.get(JAVA_SHORT_UNALIGNED, start + offset + j) == 0) { - return offset + j; - } - } - } + private static int requireWithinStringSize(long size, + AbstractMemorySegmentImpl segment, + long fromOffset, + long toOffset) { + if (size > ArraysSupport.SOFT_MAX_ARRAY_LENGTH) { + throw stringTooLarge(segment, fromOffset, toOffset); } + return (int) size; + } - // Handle the "tail" - return requireWithinArraySize((long) offset + strlenShort(segment, start + offset)); + private static IllegalArgumentException stringTooLarge(AbstractMemorySegmentImpl segment, + long fromOffset, + long toOffset) { + return new IllegalArgumentException("String too large: " + exceptionInfo(segment, fromOffset, toOffset)); } - private static int strlenShort(MemorySegment segment, long start) { - for (int offset = 0; offset < ArraysSupport.SOFT_MAX_ARRAY_LENGTH; offset += Short.BYTES) { - short curr = segment.get(JAVA_SHORT_UNALIGNED, start + offset); - if (curr == (short)0) { - return offset; - } - } - throw newIaeStringTooLarge(); + private static IndexOutOfBoundsException nullNotFound(AbstractMemorySegmentImpl segment, + long fromOffset, + long toOffset) { + return new IndexOutOfBoundsException("No null terminator found: " + exceptionInfo(segment, fromOffset, toOffset)); } - // The gain of using `long` wide operations for `int` is lower than for the two other `byte` and `short` variants - // so, there is only one method for ints. - public static int strlenInt(MemorySegment segment, long start) { - for (int offset = 0; offset < ArraysSupport.SOFT_MAX_ARRAY_LENGTH; offset += Integer.BYTES) { - // We are guaranteed to be aligned here so, we can use unaligned access. - int curr = segment.get(JAVA_INT_UNALIGNED, start + offset); - if (curr == 0) { - return offset; - } - } - throw newIaeStringTooLarge(); + private static String exceptionInfo(AbstractMemorySegmentImpl segment, + long fromOffset, + long toOffset) { + return segment + " using region [" + fromOffset + ", " + toOffset + ")"; } public enum CharsetKind { @@ -323,9 +342,4 @@ public static int copyBytes(String string, MemorySegment segment, Charset charse public static void copyToSegmentRaw(String string, MemorySegment segment, long offset) { JAVA_LANG_ACCESS.copyToSegmentRaw(string, segment, offset); } - - private static IllegalArgumentException newIaeStringTooLarge() { - return new IllegalArgumentException("String too large"); - } - } diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/CallingSequence.java b/src/java.base/share/classes/jdk/internal/foreign/abi/CallingSequence.java index e301f692167..5aad4ccc890 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/CallingSequence.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/CallingSequence.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, 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 @@ -195,6 +195,10 @@ public boolean needsTransition() { return !linkerOptions.isCritical(); } + public boolean usingAddressPairs() { + return linkerOptions.allowsHeapAccess(); + } + public int numLeadingParams() { return 2 + (linkerOptions.hasCapturedCallState() ? 1 : 0); // 2 for addr, allocator } diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/CallingSequenceBuilder.java b/src/java.base/share/classes/jdk/internal/foreign/abi/CallingSequenceBuilder.java index f24de62c807..a03c20d3173 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/CallingSequenceBuilder.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/CallingSequenceBuilder.java @@ -108,9 +108,18 @@ public CallingSequence build() { MethodType calleeMethodType; if (!forUpcall) { if (linkerOptions.hasCapturedCallState()) { - addArgumentBinding(0, MemorySegment.class, ValueLayout.ADDRESS, List.of( - Binding.unboxAddress(), - Binding.vmStore(abi.capturedStateStorage(), long.class))); + if (linkerOptions.allowsHeapAccess()) { + addArgumentBinding(0, MemorySegment.class, ValueLayout.ADDRESS, List.of( + Binding.dup(), + Binding.segmentBase(), + Binding.vmStore(abi.capturedStateStorage(), Object.class), + Binding.segmentOffsetAllowHeap(), + Binding.vmStore(null, long.class))); + } else { + addArgumentBinding(0, MemorySegment.class, ValueLayout.ADDRESS, List.of( + Binding.unboxAddress(), + Binding.vmStore(abi.capturedStateStorage(), long.class))); + } } addArgumentBinding(0, MemorySegment.class, ValueLayout.ADDRESS, List.of( Binding.unboxAddress(), diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/DowncallLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/DowncallLinker.java index 627de9f0765..2df30edb326 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/DowncallLinker.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/DowncallLinker.java @@ -84,7 +84,8 @@ public MethodHandle getBoundMethodHandle() { leafType, callingSequence.needsReturnBuffer(), callingSequence.capturedStateMask(), - callingSequence.needsTransition() + callingSequence.needsTransition(), + callingSequence.usingAddressPairs() ); MethodHandle handle = JLIA.nativeMethodHandle(nep); diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/LinkerOptions.java b/src/java.base/share/classes/jdk/internal/foreign/abi/LinkerOptions.java index fcc98ecccc0..5ca410f40e2 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/LinkerOptions.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/LinkerOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -63,11 +63,7 @@ private static LinkerOptions forShared(BiConsumer 1 != needsReturnBuffer) { throw new AssertionError("Multiple register return, but needsReturnBuffer was false"); } - checkType(methodType, needsReturnBuffer, capturedStateMask); + checkMethodType(methodType, needsReturnBuffer, capturedStateMask, usingAddressPairs); CacheKey key = new CacheKey(methodType, abi, Arrays.asList(argMoves), Arrays.asList(returnMoves), needsReturnBuffer, capturedStateMask, needsTransition); @@ -80,14 +81,26 @@ public static NativeEntryPoint make(ABIDescriptor abi, }); } - private static void checkType(MethodType methodType, boolean needsReturnBuffer, int savedValueMask) { - if (methodType.parameterType(0) != long.class) { - throw new AssertionError("Address expected as first param: " + methodType); + private static void checkMethodType(MethodType methodType, boolean needsReturnBuffer, int savedValueMask, + boolean usingAddressPairs) { + int checkIdx = 0; + checkParamType(methodType, checkIdx++, long.class, "Function address"); + if (needsReturnBuffer) { + checkParamType(methodType, checkIdx++, long.class, "Return buffer address"); } - int checkIdx = 1; - if ((needsReturnBuffer && methodType.parameterType(checkIdx++) != long.class) - || (savedValueMask != 0 && methodType.parameterType(checkIdx) != long.class)) { - throw new AssertionError("return buffer and/or preserved value address expected: " + methodType); + if (savedValueMask != 0) { // capturing call state + if (usingAddressPairs) { + checkParamType(methodType, checkIdx++, Object.class, "Capture state heap base"); + checkParamType(methodType, checkIdx, long.class, "Capture state offset"); + } else { + checkParamType(methodType, checkIdx, long.class, "Capture state address"); + } + } + } + + private static void checkParamType(MethodType methodType, int checkIdx, Class expectedType, String name) { + if (methodType.parameterType(checkIdx) != expectedType) { + throw new AssertionError(name + " expected at index " + checkIdx + ": " + methodType); } } diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java index ad5e4b97175..54906d9fef2 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java @@ -163,8 +163,14 @@ private static Object doDowncall(SegmentAllocator returnAllocator, Object[] args acquiredSessions.add(targetImpl); MemorySegment capturedState = null; + Object captureStateHeapBase = null; if (invData.capturedStateMask() != 0) { capturedState = SharedUtils.checkCaptureSegment((MemorySegment) args[argStart++]); + if (!invData.allowsHeapAccess) { + SharedUtils.checkNative(capturedState); + } else { + captureStateHeapBase = capturedState.heapBase().orElse(null); + } MemorySessionImpl capturedStateImpl = ((AbstractMemorySegmentImpl) capturedState).sessionImpl(); capturedStateImpl.acquire0(); acquiredSessions.add(capturedStateImpl); @@ -199,7 +205,8 @@ private static Object doDowncall(SegmentAllocator returnAllocator, Object[] args retSeg = (invData.returnLayout() instanceof GroupLayout ? returnAllocator : arena).allocate(invData.returnLayout); } - LibFallback.doDowncall(invData.cif, target, retSeg, argPtrs, capturedState, invData.capturedStateMask(), + LibFallback.doDowncall(invData.cif, target, retSeg, argPtrs, + captureStateHeapBase, capturedState, invData.capturedStateMask(), heapBases, args.length); Reference.reachabilityFence(invData.cif()); diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/LibFallback.java b/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/LibFallback.java index b68b1ed4bad..6fe8dd5f91c 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/LibFallback.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/LibFallback.java @@ -90,10 +90,11 @@ private static boolean tryLoadLibrary() { * @see jdk.internal.foreign.abi.CapturableState */ static void doDowncall(MemorySegment cif, MemorySegment target, MemorySegment retPtr, MemorySegment argPtrs, - MemorySegment capturedState, int capturedStateMask, + Object captureStateHeapBase, MemorySegment capturedState, int capturedStateMask, Object[] heapBases, int numArgs) { doDowncall(cif.address(), target.address(), retPtr == null ? 0 : retPtr.address(), argPtrs.address(), + captureStateHeapBase, capturedState == null ? 0 : capturedState.address(), capturedStateMask, heapBases, numArgs); } @@ -212,7 +213,7 @@ private static void checkStatus(int code) { private static native int createClosure(long cif, Object userData, long[] ptrs); private static native void freeClosure(long closureAddress, long globalTarget); private static native void doDowncall(long cif, long fn, long rvalue, long avalues, - long capturedState, int capturedStateMask, + Object captureStateHeapBase, long capturedState, int capturedStateMask, Object[] heapBases, int numArgs); private static native int ffi_prep_cif(long cif, int abi, int nargs, long rtype, long atypes); diff --git a/src/java.base/share/classes/jdk/internal/vm/Continuation.java b/src/java.base/share/classes/jdk/internal/vm/Continuation.java index 05a32cc3b21..a97f9ac9ea4 100644 --- a/src/java.base/share/classes/jdk/internal/vm/Continuation.java +++ b/src/java.base/share/classes/jdk/internal/vm/Continuation.java @@ -28,7 +28,6 @@ import jdk.internal.misc.Unsafe; import jdk.internal.vm.annotation.DontInline; import jdk.internal.vm.annotation.IntrinsicCandidate; -import sun.security.action.GetPropertyAction; import java.util.EnumSet; import java.util.Set; @@ -51,7 +50,7 @@ public class Continuation { StackChunk.init(); // ensure StackChunk class is initialized - String value = GetPropertyAction.privilegedGetProperty("jdk.preserveScopedValueCache"); + String value = System.getProperty("jdk.preserveScopedValueCache"); PRESERVE_SCOPED_VALUE_CACHE = (value == null) || Boolean.parseBoolean(value); } @@ -503,7 +502,7 @@ private void dump() { } private static boolean isEmptyOrTrue(String property) { - String value = GetPropertyAction.privilegedGetProperty(property); + String value = System.getProperty(property); if (value == null) return false; return value.isEmpty() || Boolean.parseBoolean(value); diff --git a/src/java.base/share/classes/jdk/internal/vm/JcmdVThreadCommands.java b/src/java.base/share/classes/jdk/internal/vm/JcmdVThreadCommands.java new file mode 100644 index 00000000000..66ac6c2aca9 --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/vm/JcmdVThreadCommands.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2023, 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. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.internal.vm; + +import java.nio.charset.StandardCharsets; +import java.util.List; +import java.util.stream.IntStream; +import jdk.internal.access.JavaLangAccess; +import jdk.internal.access.SharedSecrets; +import sun.nio.ch.Poller; + +/** + * The implementation for the jcmd Thread.vthread_* diagnostic commands. These methods are + * called from the "Attach Listener" thread. + */ +public class JcmdVThreadCommands { + private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); + + private JcmdVThreadCommands() { } + + /** + * Invoked by the VM to print the virtual scheduler to a byte[]. + */ + private static byte[] printScheduler() { + StringBuilder sb = new StringBuilder(); + + // virtual thread scheduler + sb.append(JLA.virtualThreadDefaultScheduler()) + .append(System.lineSeparator()); + + // break + sb.append(System.lineSeparator()); + + // delayed task schedulers + sb.append("Delayed task schedulers:").append(System.lineSeparator()); + var delayedTaskSchedulers = JLA.virtualThreadDelayedTaskSchedulers().toList(); + IntStream.range(0, delayedTaskSchedulers.size()) + .forEach(i -> sb.append('[') + .append(i) + .append("] ") + .append(delayedTaskSchedulers.get(i)) + .append(System.lineSeparator())); + + return sb.toString().getBytes(StandardCharsets.UTF_8); + } + + /** + * Invoked by the VM to print the I/O pollers to a byte[]. + */ + private static byte[] printPollers() { + StringBuilder sb = new StringBuilder(); + + Poller masterPoller = Poller.masterPoller(); + List readPollers = Poller.readPollers(); + List writePollers = Poller.writePollers(); + + if (masterPoller != null) { + sb.append("Master I/O poller:") + .append(System.lineSeparator()) + .append(masterPoller) + .append(System.lineSeparator()); + + // break + sb.append(System.lineSeparator()); + } + + sb.append("Read I/O pollers:"); + sb.append(System.lineSeparator()); + IntStream.range(0, readPollers.size()) + .forEach(i -> sb.append('[') + .append(i) + .append("] ") + .append(readPollers.get(i)) + .append(System.lineSeparator())); + + // break + sb.append(System.lineSeparator()); + + sb.append("Write I/O pollers:"); + sb.append(System.lineSeparator()); + IntStream.range(0, writePollers.size()) + .forEach(i -> sb.append('[') + .append(i) + .append("] ") + .append(writePollers.get(i)) + .append(System.lineSeparator())); + + return sb.toString().getBytes(StandardCharsets.UTF_8); + } +} diff --git a/src/java.base/share/classes/jdk/internal/vm/ThreadContainers.java b/src/java.base/share/classes/jdk/internal/vm/ThreadContainers.java index e1672febc3c..aeae6b36520 100644 --- a/src/java.base/share/classes/jdk/internal/vm/ThreadContainers.java +++ b/src/java.base/share/classes/jdk/internal/vm/ThreadContainers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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,6 @@ import java.util.stream.Stream; import jdk.internal.access.JavaLangAccess; import jdk.internal.access.SharedSecrets; -import sun.security.action.GetPropertyAction; /** * This class consists exclusively of static methods to support groupings of threads. @@ -52,7 +51,7 @@ public class ThreadContainers { private static final ReferenceQueue QUEUE = new ReferenceQueue<>(); static { - String s = GetPropertyAction.privilegedGetProperty("jdk.trackAllThreads"); + String s = System.getProperty("jdk.trackAllThreads"); if (s == null || s.isEmpty() || Boolean.parseBoolean(s)) { TRACK_ALL_THREADS = true; ROOT_CONTAINER = new RootContainer.TrackingRootContainer(); diff --git a/src/java.base/share/classes/sun/nio/ch/Net.java b/src/java.base/share/classes/sun/nio/ch/Net.java index 03dcf04a50f..5c922aff676 100644 --- a/src/java.base/share/classes/sun/nio/ch/Net.java +++ b/src/java.base/share/classes/sun/nio/ch/Net.java @@ -40,6 +40,7 @@ import java.net.StandardSocketOptions; import java.net.UnknownHostException; import java.nio.channels.AlreadyBoundException; +import java.nio.channels.AlreadyConnectedException; import java.nio.channels.ClosedChannelException; import java.nio.channels.NotYetBoundException; import java.nio.channels.NotYetConnectedException; @@ -166,6 +167,8 @@ else if (x instanceof NotYetConnectedException) nx = newSocketException("Socket is not connected"); else if (x instanceof AlreadyBoundException) nx = newSocketException("Already bound"); + else if (x instanceof AlreadyConnectedException) + nx = newSocketException("Already connected"); else if (x instanceof NotYetBoundException) nx = newSocketException("Socket is not bound yet"); else if (x instanceof UnsupportedAddressTypeException) @@ -190,32 +193,12 @@ private static SocketException newSocketException(String msg) { return new SocketException(msg); } - static void translateException(Exception x, - boolean unknownHostForUnresolved) - throws IOException - { + static void translateException(Exception x) throws IOException { if (x instanceof IOException ioe) throw ioe; - // Throw UnknownHostException from here since it cannot - // be thrown as a SocketException - if (unknownHostForUnresolved && - (x instanceof UnresolvedAddressException)) - { - throw new UnknownHostException(); - } translateToSocketException(x); } - static void translateException(Exception x) - throws IOException - { - translateException(x, false); - } - - private static InetSocketAddress getLoopbackAddress(int port) { - return new InetSocketAddress(InetAddress.getLoopbackAddress(), port); - } - private static final InetAddress ANY_LOCAL_INET4ADDRESS; private static final InetAddress ANY_LOCAL_INET6ADDRESS; private static final InetAddress INET4_LOOPBACK_ADDRESS; diff --git a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java index 40bc3156680..7c64d6721e2 100644 --- a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java @@ -599,8 +599,11 @@ protected void connect(SocketAddress remote, int millis) throws IOException { } } catch (IOException ioe) { close(); - if (ioe instanceof InterruptedIOException) { + if (ioe instanceof SocketTimeoutException) { throw ioe; + } else if (ioe instanceof InterruptedIOException) { + assert Thread.currentThread().isVirtual(); + throw new SocketException("Closed by interrupt"); } else { throw SocketExceptions.of(ioe, isa); } diff --git a/src/java.base/share/classes/sun/nio/ch/Poller.java b/src/java.base/share/classes/sun/nio/ch/Poller.java index d25dfec7f42..4a2cb4d8fdf 100644 --- a/src/java.base/share/classes/sun/nio/ch/Poller.java +++ b/src/java.base/share/classes/sun/nio/ch/Poller.java @@ -36,6 +36,7 @@ import java.util.concurrent.locks.LockSupport; import java.util.function.BooleanSupplier; import jdk.internal.misc.InnocuousThread; +import jdk.internal.vm.annotation.Stable; /** * Polls file descriptors. Virtual threads invoke the poll method to park @@ -53,6 +54,9 @@ public abstract class Poller { } } + // the poller or sub-poller thread + private @Stable Thread owner; + // maps file descriptors to parked Thread private final Map map = new ConcurrentHashMap<>(); @@ -238,6 +242,7 @@ private void wakeup(int fdVal) { * descriptor that is polled. */ private void pollerLoop() { + owner = Thread.currentThread(); try { for (;;) { poll(-1); @@ -258,6 +263,7 @@ private void pollerLoop() { */ private void subPollerLoop(Poller masterPoller) { assert Thread.currentThread().isVirtual(); + owner = Thread.currentThread(); try { int polled = 0; for (;;) { @@ -282,7 +288,8 @@ public int registered() { @Override public String toString() { - return Objects.toIdentityString(this) + " [registered = " + registered() + "]"; + return String.format("%s [registered = %d, owner = %s]", + Objects.toIdentityString(this), registered(), owner); } /** @@ -442,4 +449,25 @@ private void startPlatformThread(String name, Runnable task) { } } } + + /** + * Return the master poller or null if there is no master poller. + */ + public static Poller masterPoller() { + return POLLERS.masterPoller(); + } + + /** + * Return the list of read pollers. + */ + public static List readPollers() { + return POLLERS.readPollers(); + } + + /** + * Return the list of write pollers. + */ + public static List writePollers() { + return POLLERS.writePollers(); + } } diff --git a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java index cbcfd79378c..d8ed1cfb675 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java @@ -35,6 +35,7 @@ import java.net.SocketException; import java.net.SocketOption; import java.net.StandardSocketOptions; +import java.net.UnknownHostException; import java.nio.channels.SocketChannel; import java.util.Set; @@ -85,6 +86,14 @@ public void connect(SocketAddress remote) throws IOException { public void connect(SocketAddress remote, int timeout) throws IOException { if (remote == null) throw new IllegalArgumentException("connect: The address can't be null"); + if (remote instanceof InetSocketAddress isa && isa.isUnresolved()) { + if (!sc.isOpen()) + throw new SocketException("Socket is closed"); + if (sc.isConnected()) + throw new SocketException("Already connected"); + close(); + throw new UnknownHostException(remote.toString()); + } if (timeout < 0) throw new IllegalArgumentException("connect: timeout can't be negative"); try { @@ -95,7 +104,7 @@ public void connect(SocketAddress remote, int timeout) throws IOException { sc.blockingConnect(remote, Long.MAX_VALUE); } } catch (Exception e) { - Net.translateException(e, true); + Net.translateException(e); } } diff --git a/src/java.base/share/classes/sun/security/action/GetPropertyAction.java b/src/java.base/share/classes/sun/security/action/GetPropertyAction.java deleted file mode 100644 index 8954c615cba..00000000000 --- a/src/java.base/share/classes/sun/security/action/GetPropertyAction.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.security.action; - -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Properties; - -/** - * A convenience class for retrieving the string value of a system - * property as a privileged action. - * - *

      An instance of this class can be used as the argument of - * AccessController.doPrivileged. - * - *

      The following code retrieves the value of the system - * property named "prop" as a privileged action: - * - *

      - * String s = java.security.AccessController.doPrivileged
      - *                      (new GetPropertyAction("prop"));
      - * 
      - * - * @author Roland Schemers - * @see java.security.PrivilegedAction - * @see java.security.AccessController - * @since 1.2 - */ - -public class GetPropertyAction implements PrivilegedAction { - private final String theProp; - private final String defaultVal; - - /** - * Constructor that takes the name of the system property whose - * string value needs to be determined. - * - * @param theProp the name of the system property. - */ - public GetPropertyAction(String theProp) { - this.theProp = theProp; - this.defaultVal = null; - } - - /** - * Constructor that takes the name of the system property and the default - * value of that property. - * - * @param theProp the name of the system property. - * @param defaultVal the default value. - */ - public GetPropertyAction(String theProp, String defaultVal) { - this.theProp = theProp; - this.defaultVal = defaultVal; - } - - /** - * Determines the string value of the system property whose - * name was specified in the constructor. - * - * @return the string value of the system property, - * or the default value if there is no property with that key. - */ - public String run() { - String value = System.getProperty(theProp); - return (value == null) ? defaultVal : value; - } - - /** - * Convenience method to get a property without going through doPrivileged - * if no security manager is present. This is unsafe for inclusion in a - * public API but allowable here since this class is now encapsulated. - * - * Note that this method performs a privileged action using caller-provided - * inputs. The caller of this method should take care to ensure that the - * inputs are not tainted and the returned property is not made accessible - * to untrusted code if it contains sensitive information. - * - * @param theProp the name of the system property. - */ - @SuppressWarnings("removal") - public static String privilegedGetProperty(String theProp) { - if (System.getSecurityManager() == null) { - return System.getProperty(theProp); - } else { - return AccessController.doPrivileged( - new GetPropertyAction(theProp)); - } - } - - /** - * Convenience method to get a property without going through doPrivileged - * if no security manager is present. This is unsafe for inclusion in a - * public API but allowable here since this class is now encapsulated. - * - * Note that this method performs a privileged action using caller-provided - * inputs. The caller of this method should take care to ensure that the - * inputs are not tainted and the returned property is not made accessible - * to untrusted code if it contains sensitive information. - * - * @param theProp the name of the system property. - * @param defaultVal the default value. - */ - @SuppressWarnings("removal") - public static String privilegedGetProperty(String theProp, - String defaultVal) { - if (System.getSecurityManager() == null) { - return System.getProperty(theProp, defaultVal); - } else { - return AccessController.doPrivileged( - new GetPropertyAction(theProp, defaultVal)); - } - } - - /** - * Convenience method to call System.getProperties without - * having to go through doPrivileged if no security manager is present. - * This is unsafe for inclusion in a public API but allowable here since - * this class is now encapsulated. - * - * Note that this method performs a privileged action, and callers of - * this method should take care to ensure that the returned properties - * are not made accessible to untrusted code since it may contain - * sensitive information. - */ - @SuppressWarnings("removal") - public static Properties privilegedGetProperties() { - if (System.getSecurityManager() == null) { - return System.getProperties(); - } else { - return AccessController.doPrivileged( - new PrivilegedAction() { - public Properties run() { - return System.getProperties(); - } - } - ); - } - } -} diff --git a/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java b/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java index b9d520d4083..850f198c8b1 100644 --- a/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java +++ b/src/java.base/share/classes/sun/util/calendar/LocalGregorianCalendar.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, 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 @@ -28,7 +28,6 @@ import java.util.TimeZone; import java.util.regex.Matcher; import java.util.regex.Pattern; -import sun.security.action.GetPropertyAction; /** * @@ -146,8 +145,7 @@ static LocalGregorianCalendar getLocalGregorianCalendar(String name) { } // Append an era to the predefined eras if it's given by the property. - String prop = GetPropertyAction - .privilegedGetProperty("jdk.calendar.japanese.supplemental.era"); + String prop = System.getProperty("jdk.calendar.japanese.supplemental.era"); if (prop != null) { Era era = parseEraEntry(prop); if (era != null) { diff --git a/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java b/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java index a027191e45f..5e7a4c719d1 100644 --- a/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java +++ b/src/java.base/share/classes/sun/util/locale/provider/LocaleProviderAdapter.java @@ -48,7 +48,6 @@ import java.util.spi.LocaleNameProvider; import java.util.spi.LocaleServiceProvider; import java.util.spi.TimeZoneNameProvider; -import sun.security.action.GetPropertyAction; import sun.text.spi.JavaTimeDateTimePatternProvider; import sun.util.spi.CalendarProvider; @@ -115,7 +114,7 @@ public String getTextResourcesPackage() { adapterCache = new ConcurrentHashMap<>(); static { - String order = GetPropertyAction.privilegedGetProperty("java.locale.providers"); + String order = System.getProperty("java.locale.providers"); ArrayList typeList = new ArrayList<>(); String invalidTypeMessage = null; String compatWarningMessage = null; diff --git a/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java b/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java index ee6ec0f72ba..4ae0275fdda 100644 --- a/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java +++ b/src/java.base/share/classes/sun/util/locale/provider/LocaleResources.java @@ -63,7 +63,6 @@ import java.util.stream.Stream; import jdk.internal.util.StaticProperty; -import sun.security.action.GetPropertyAction; import sun.util.resources.LocaleData; import sun.util.resources.OpenListResourceBundle; import sun.util.resources.ParallelListResourceBundle; @@ -899,7 +898,7 @@ String getCacheKey() { } private static final boolean TRACE_ON = Boolean.parseBoolean( - GetPropertyAction.privilegedGetProperty("locale.resources.debug", "false")); + System.getProperty("locale.resources.debug", "false")); public static void trace(String format, Object... params) { if (TRACE_ON) { diff --git a/src/java.base/share/data/lsrdata/language-subtag-registry.txt b/src/java.base/share/data/lsrdata/language-subtag-registry.txt index 3079d77ed8b..b00ea67e7e8 100644 --- a/src/java.base/share/data/lsrdata/language-subtag-registry.txt +++ b/src/java.base/share/data/lsrdata/language-subtag-registry.txt @@ -1,4 +1,4 @@ -File-Date: 2024-06-14 +File-Date: 2024-11-19 %% Type: language Subtag: aa @@ -47991,6 +47991,16 @@ Added: 2008-10-14 Prefix: kw %% Type: variant +Subtag: kleinsch +Description: Kleinschmidt orthography +Description: Allattaasitaamut +Added: 2024-07-20 +Prefix: kl +Prefix: kl-tunumiit +Comments: Orthography for Greenlandic designed by Samuel Kleinschmidt, + used from 1851 to 1973. +%% +Type: variant Subtag: kociewie Description: The Kociewie dialect of Polish Added: 2014-11-27 diff --git a/src/java.base/share/native/libfallbackLinker/fallbackLinker.c b/src/java.base/share/native/libfallbackLinker/fallbackLinker.c index 2ee64fb05bc..5a85fedd774 100644 --- a/src/java.base/share/native/libfallbackLinker/fallbackLinker.c +++ b/src/java.base/share/native/libfallbackLinker/fallbackLinker.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -112,12 +112,16 @@ static void do_capture_state(int32_t* value_ptr, int captured_state_mask) { JNIEXPORT void JNICALL Java_jdk_internal_foreign_abi_fallback_LibFallback_doDowncall(JNIEnv* env, jclass cls, jlong cif, jlong fn, jlong rvalue, - jlong avalues, jlong jcaptured_state, jint captured_state_mask, + jlong avalues, + jarray capture_state_heap_base, jlong captured_state_offset, + jint captured_state_mask, jarray heapBases, jint numArgs) { void** carrays; + int capture_state_hb_offset = numArgs; + int32_t* captured_state_addr = jlong_to_ptr(captured_state_offset); if (heapBases != NULL) { void** aptrs = jlong_to_ptr(avalues); - carrays = malloc(sizeof(void*) * numArgs); + carrays = malloc(sizeof(void*) * (numArgs + 1)); for (int i = 0; i < numArgs; i++) { jarray hb = (jarray) (*env)->GetObjectArrayElement(env, heapBases, i); if (hb != NULL) { @@ -130,10 +134,20 @@ Java_jdk_internal_foreign_abi_fallback_LibFallback_doDowncall(JNIEnv* env, jclas *((void**)aptrs[i]) = arrayPtr + offset; } } + if (capture_state_heap_base != NULL) { + jboolean isCopy; + jbyte* arrayPtr = (*env)->GetPrimitiveArrayCritical(env, capture_state_heap_base, &isCopy); + carrays[capture_state_hb_offset] = arrayPtr; + captured_state_addr = (int32_t*) (arrayPtr + captured_state_offset); + } } ffi_call(jlong_to_ptr(cif), jlong_to_ptr(fn), jlong_to_ptr(rvalue), jlong_to_ptr(avalues)); + if (captured_state_mask != 0) { + do_capture_state(captured_state_addr, captured_state_mask); + } + if (heapBases != NULL) { for (int i = 0; i < numArgs; i++) { jarray hb = (jarray) (*env)->GetObjectArrayElement(env, heapBases, i); @@ -141,13 +155,11 @@ Java_jdk_internal_foreign_abi_fallback_LibFallback_doDowncall(JNIEnv* env, jclas (*env)->ReleasePrimitiveArrayCritical(env, hb, carrays[i], JNI_COMMIT); } } + if (capture_state_heap_base != NULL) { + (*env)->ReleasePrimitiveArrayCritical(env, capture_state_heap_base, carrays[capture_state_hb_offset], JNI_COMMIT); + } free(carrays); } - - if (captured_state_mask != 0) { - int32_t* captured_state = jlong_to_ptr(jcaptured_state); - do_capture_state(captured_state, captured_state_mask); - } } static void do_upcall(ffi_cif* cif, void* ret, void** args, void* user_data) { diff --git a/src/java.base/windows/native/libjava/io_util_md.c b/src/java.base/windows/native/libjava/io_util_md.c index 4709bbbae24..bae9803a564 100644 --- a/src/java.base/windows/native/libjava/io_util_md.c +++ b/src/java.base/windows/native/libjava/io_util_md.c @@ -342,16 +342,8 @@ handleNonSeekAvailable(FD fd, long *pbytes) { return FALSE; } - if (! PeekNamedPipe(han, NULL, 0, NULL, pbytes, NULL)) { - /* PeekNamedPipe fails when at EOF. In that case we - * simply make *pbytes = 0 which is consistent with the - * behavior we get on Solaris when an fd is at EOF. - * The only alternative is to raise and Exception, - * which isn't really warranted. - */ - if (GetLastError() != ERROR_BROKEN_PIPE) { - return FALSE; - } + if (!PeekNamedPipe(han, NULL, 0, NULL, pbytes, NULL)) { + // If PeekNamedPipe fails, set the number of available bytes to zero. *pbytes = 0; } return TRUE; diff --git a/src/java.desktop/share/classes/javax/swing/text/Document.java b/src/java.desktop/share/classes/javax/swing/text/Document.java index c9658aa3b21..801d6bcbbc3 100644 --- a/src/java.desktop/share/classes/javax/swing/text/Document.java +++ b/src/java.desktop/share/classes/javax/swing/text/Document.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -471,24 +471,31 @@ public interface Document { public void remove(int offs, int len) throws BadLocationException; /** - * Inserts a string of content. This will cause a DocumentEvent - * of type DocumentEvent.EventType.INSERT to be sent to the - * registered DocumentListeners, unless an exception is thrown. - * The DocumentEvent will be delivered by calling the - * insertUpdate method on the DocumentListener. - * The offset and length of the generated DocumentEvent - * will indicate what change was actually made to the Document. - *

      + * For example, if the document contains the text + * ‘The brown fox’, + * calling {@code insert(4, "quick ", null)} will insert the word + * ‘quick’ and the following space into the text, + * and all the marks at 4 and above will be moved by 6 (the number + * of inserted characters). + *

      Diagram shows insertion of 'quick' in 'The quick brown fox' *

      - * If the Document structure changed as result of the insertion, - * the details of what Elements were inserted and removed in + * If the {@code Document} structure changed as result of the insertion, + * the details of what {@code Element}s were inserted and removed in * response to the change will also be contained in the generated - * DocumentEvent. It is up to the implementation of a Document + * {@code DocumentEvent}. It is up to the implementation of a {@code Document} * to decide how the structure should change in response to an * insertion. *

      - * If the Document supports undo/redo, an UndoableEditEvent will + * If the {@code Document} supports undo/redo, an {@code UndoableEditEvent} will * also be generated. * * @param offset the offset into the document to insert the content >= 0. @@ -496,7 +503,7 @@ public interface Document { * will move. * @param str the string to insert * @param a the attributes to associate with the inserted - * content. This may be null if there are no attributes. + * content. This may be {@code null} if there are no attributes. * @throws BadLocationException the given insert position is not a valid * position within the document * @see javax.swing.event.DocumentEvent diff --git a/src/java.desktop/share/classes/javax/swing/text/doc-files/Document-insert.gif b/src/java.desktop/share/classes/javax/swing/text/doc-files/Document-insert.gif deleted file mode 100644 index 7e943ce77aa..00000000000 Binary files a/src/java.desktop/share/classes/javax/swing/text/doc-files/Document-insert.gif and /dev/null differ diff --git a/src/java.desktop/share/classes/javax/swing/text/doc-files/Document-insert.svg b/src/java.desktop/share/classes/javax/swing/text/doc-files/Document-insert.svg new file mode 100644 index 00000000000..09a74210d41 --- /dev/null +++ b/src/java.desktop/share/classes/javax/swing/text/doc-files/Document-insert.svg @@ -0,0 +1,150 @@ + + + + + + + + + + + + + Before Insert + + + + + + 4 + + After Insert + + + + T + + h + + e + + + + + + + q + + u + + i + + c + + k + + + + + + + b + + r + + o + + w + + n + + + + f + + o + + x + + + + + + 10 + + diff --git a/src/java.desktop/share/classes/javax/swing/text/html/CSS.java b/src/java.desktop/share/classes/javax/swing/text/html/CSS.java index 8239565a53f..ef422a8d4e9 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/CSS.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/CSS.java @@ -38,6 +38,7 @@ import java.util.ArrayList; import java.util.Enumeration; import java.util.Hashtable; +import java.util.Map; import java.util.Objects; import javax.swing.ImageIcon; @@ -1089,7 +1090,7 @@ private static int getTableBorder(AttributeSet tableAttr) { * Therefore, the value associated with each HTML.Attribute. * key ends up being an array of CSS.Attribute.* objects. */ - private static final Hashtable htmlAttrToCssAttrMap = new Hashtable(20); + private static final Map htmlAttrToCssAttrMap; /** * The hashtable and static initialization that follows sets @@ -1113,53 +1114,57 @@ private static int getTableBorder(AttributeSet tableAttr) { valueMap.put(Value.allValues[i].toString(), Value.allValues[i]); } - - htmlAttrToCssAttrMap.put(HTML.Attribute.COLOR, - new CSS.Attribute[]{CSS.Attribute.COLOR}); - htmlAttrToCssAttrMap.put(HTML.Attribute.TEXT, - new CSS.Attribute[]{CSS.Attribute.COLOR}); - htmlAttrToCssAttrMap.put(HTML.Attribute.CLEAR, - new CSS.Attribute[]{CSS.Attribute.CLEAR}); - htmlAttrToCssAttrMap.put(HTML.Attribute.BACKGROUND, - new CSS.Attribute[]{CSS.Attribute.BACKGROUND_IMAGE}); - htmlAttrToCssAttrMap.put(HTML.Attribute.BGCOLOR, - new CSS.Attribute[]{CSS.Attribute.BACKGROUND_COLOR}); - htmlAttrToCssAttrMap.put(HTML.Attribute.WIDTH, - new CSS.Attribute[]{CSS.Attribute.WIDTH}); - htmlAttrToCssAttrMap.put(HTML.Attribute.HEIGHT, - new CSS.Attribute[]{CSS.Attribute.HEIGHT}); - htmlAttrToCssAttrMap.put(HTML.Attribute.BORDER, - new CSS.Attribute[]{CSS.Attribute.BORDER_TOP_WIDTH, CSS.Attribute.BORDER_RIGHT_WIDTH, CSS.Attribute.BORDER_BOTTOM_WIDTH, CSS.Attribute.BORDER_LEFT_WIDTH}); - htmlAttrToCssAttrMap.put(HTML.Attribute.CELLPADDING, - new CSS.Attribute[]{CSS.Attribute.PADDING}); - htmlAttrToCssAttrMap.put(HTML.Attribute.CELLSPACING, - new CSS.Attribute[]{CSS.Attribute.BORDER_SPACING}); - htmlAttrToCssAttrMap.put(HTML.Attribute.MARGINWIDTH, - new CSS.Attribute[]{CSS.Attribute.MARGIN_LEFT, - CSS.Attribute.MARGIN_RIGHT}); - htmlAttrToCssAttrMap.put(HTML.Attribute.MARGINHEIGHT, - new CSS.Attribute[]{CSS.Attribute.MARGIN_TOP, - CSS.Attribute.MARGIN_BOTTOM}); - htmlAttrToCssAttrMap.put(HTML.Attribute.HSPACE, - new CSS.Attribute[]{CSS.Attribute.PADDING_LEFT, - CSS.Attribute.PADDING_RIGHT}); - htmlAttrToCssAttrMap.put(HTML.Attribute.VSPACE, - new CSS.Attribute[]{CSS.Attribute.PADDING_BOTTOM, - CSS.Attribute.PADDING_TOP}); - htmlAttrToCssAttrMap.put(HTML.Attribute.FACE, - new CSS.Attribute[]{CSS.Attribute.FONT_FAMILY}); - htmlAttrToCssAttrMap.put(HTML.Attribute.SIZE, - new CSS.Attribute[]{CSS.Attribute.FONT_SIZE}); - htmlAttrToCssAttrMap.put(HTML.Attribute.VALIGN, - new CSS.Attribute[]{CSS.Attribute.VERTICAL_ALIGN}); - htmlAttrToCssAttrMap.put(HTML.Attribute.ALIGN, - new CSS.Attribute[]{CSS.Attribute.VERTICAL_ALIGN, - CSS.Attribute.TEXT_ALIGN, - CSS.Attribute.FLOAT}); - htmlAttrToCssAttrMap.put(HTML.Attribute.TYPE, - new CSS.Attribute[]{CSS.Attribute.LIST_STYLE_TYPE}); - htmlAttrToCssAttrMap.put(HTML.Attribute.NOWRAP, - new CSS.Attribute[]{CSS.Attribute.WHITE_SPACE}); + htmlAttrToCssAttrMap = Map.ofEntries( + Map.entry(HTML.Attribute.COLOR, + new CSS.Attribute[]{CSS.Attribute.COLOR}), + Map.entry(HTML.Attribute.TEXT, + new CSS.Attribute[]{CSS.Attribute.COLOR}), + Map.entry(HTML.Attribute.CLEAR, + new CSS.Attribute[]{CSS.Attribute.CLEAR}), + Map.entry(HTML.Attribute.BACKGROUND, + new CSS.Attribute[]{CSS.Attribute.BACKGROUND_IMAGE}), + Map.entry(HTML.Attribute.BGCOLOR, + new CSS.Attribute[]{CSS.Attribute.BACKGROUND_COLOR}), + Map.entry(HTML.Attribute.WIDTH, + new CSS.Attribute[]{CSS.Attribute.WIDTH}), + Map.entry(HTML.Attribute.HEIGHT, + new CSS.Attribute[]{CSS.Attribute.HEIGHT}), + Map.entry(HTML.Attribute.BORDER, + new CSS.Attribute[]{CSS.Attribute.BORDER_TOP_WIDTH, + CSS.Attribute.BORDER_RIGHT_WIDTH, + CSS.Attribute.BORDER_BOTTOM_WIDTH, + CSS.Attribute.BORDER_LEFT_WIDTH}), + Map.entry(HTML.Attribute.CELLPADDING, + new CSS.Attribute[]{CSS.Attribute.PADDING}), + Map.entry(HTML.Attribute.CELLSPACING, + new CSS.Attribute[]{CSS.Attribute.BORDER_SPACING}), + Map.entry(HTML.Attribute.MARGINWIDTH, + new CSS.Attribute[]{CSS.Attribute.MARGIN_LEFT, + CSS.Attribute.MARGIN_RIGHT}), + Map.entry(HTML.Attribute.MARGINHEIGHT, + new CSS.Attribute[]{CSS.Attribute.MARGIN_TOP, + CSS.Attribute.MARGIN_BOTTOM}), + Map.entry(HTML.Attribute.HSPACE, + new CSS.Attribute[]{CSS.Attribute.PADDING_LEFT, + CSS.Attribute.PADDING_RIGHT}), + Map.entry(HTML.Attribute.VSPACE, + new CSS.Attribute[]{CSS.Attribute.PADDING_BOTTOM, + CSS.Attribute.PADDING_TOP}), + Map.entry(HTML.Attribute.FACE, + new CSS.Attribute[]{CSS.Attribute.FONT_FAMILY}), + Map.entry(HTML.Attribute.SIZE, + new CSS.Attribute[]{CSS.Attribute.FONT_SIZE}), + Map.entry(HTML.Attribute.VALIGN, + new CSS.Attribute[]{CSS.Attribute.VERTICAL_ALIGN}), + Map.entry(HTML.Attribute.ALIGN, + new CSS.Attribute[]{CSS.Attribute.VERTICAL_ALIGN, + CSS.Attribute.TEXT_ALIGN, + CSS.Attribute.FLOAT}), + Map.entry(HTML.Attribute.TYPE, + new CSS.Attribute[]{CSS.Attribute.LIST_STYLE_TYPE}), + Map.entry(HTML.Attribute.NOWRAP, + new CSS.Attribute[]{CSS.Attribute.WHITE_SPACE}) + ); // initialize StyleConstants mapping styleConstantToCssMap.put(StyleConstants.FontFamily, diff --git a/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java b/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java index ee0f32d91c0..af1b7c74b59 100644 --- a/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java +++ b/src/java.desktop/share/classes/sun/awt/shell/ShellFolder.java @@ -232,7 +232,7 @@ public Image getIcon(int width, int height) { managerClass = null; } // swallow the exceptions below and use default shell folder - } catch (ClassNotFoundException | SecurityException | NullPointerException e) { + } catch (ClassNotFoundException | NullPointerException e) { } if (managerClass == null) { diff --git a/src/java.desktop/share/classes/sun/awt/shell/ShellFolderManager.java b/src/java.desktop/share/classes/sun/awt/shell/ShellFolderManager.java index 868a5bb3910..10d0b539285 100644 --- a/src/java.desktop/share/classes/sun/awt/shell/ShellFolderManager.java +++ b/src/java.desktop/share/classes/sun/awt/shell/ShellFolderManager.java @@ -28,8 +28,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.util.concurrent.Callable; -import java.util.stream.Stream; - /** * @author Michael Martak @@ -70,13 +68,13 @@ public Object get(String key) { // Return the default shellfolder for a new filechooser File homeDir = new File(System.getProperty("user.home")); try { - return checkFile(createShellFolder(homeDir)); + return createShellFolder(homeDir); } catch (FileNotFoundException e) { - return checkFile(homeDir); + return homeDir; } } else if (key.equals("roots")) { // The root(s) of the displayable hierarchy - return checkFiles(File.listRoots()); + return File.listRoots(); } else if (key.equals("fileChooserComboBoxFolders")) { // Return an array of ShellFolders representing the list to // show by default in the file chooser's combobox @@ -86,44 +84,12 @@ public Object get(String key) { // folders, such as Desktop, Documents, History, Network, Home, etc. // This is used in the shortcut panel of the filechooser on Windows 2000 // and Windows Me - return checkFiles(new File[] { (File)get("fileChooserDefaultFolder") }); + return new File[] { (File)get("fileChooserDefaultFolder") }; } return null; } - private static File checkFile(File f) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - return (sm == null || f == null) ? f : checkFile(f, sm); - } - - private static File checkFile(File f, @SuppressWarnings("removal") SecurityManager sm) { - try { - sm.checkRead(f.getPath()); - if (f instanceof ShellFolder) { - ShellFolder sf = (ShellFolder)f; - if (sf.isLink()) { - sm.checkRead(sf.getLinkLocation().getPath()); - } - } - return f; - } catch (SecurityException | FileNotFoundException e) { - return null; - } - } - - private static File[] checkFiles(File[] fs) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - return (sm == null || fs == null) ? fs : checkFiles(Stream.of(fs), sm); - } - - private static File[] checkFiles(Stream fs, @SuppressWarnings("removal") SecurityManager sm) { - return fs.filter(f -> f != null && checkFile(f, sm) != null) - .toArray(File[]::new); - } - /** * Does {@code dir} represent a "computer" such as a node on the network, or * "My Computer" on the desktop. diff --git a/src/java.desktop/share/classes/sun/swing/FilePane.java b/src/java.desktop/share/classes/sun/swing/FilePane.java index 395cf058b7d..052e7a96ac4 100644 --- a/src/java.desktop/share/classes/sun/swing/FilePane.java +++ b/src/java.desktop/share/classes/sun/swing/FilePane.java @@ -2119,24 +2119,20 @@ public boolean canWrite(File f) { return false; } - try { - if (f instanceof ShellFolder) { - return f.canWrite(); - } else { - if (usesShellFolder(getFileChooser())) { - try { - return ShellFolder.getShellFolder(f).canWrite(); - } catch (FileNotFoundException ex) { - // File doesn't exist - return false; - } - } else { - // Ordinary file - return f.canWrite(); + if (f instanceof ShellFolder) { + return f.canWrite(); + } else { + if (usesShellFolder(getFileChooser())) { + try { + return ShellFolder.getShellFolder(f).canWrite(); + } catch (FileNotFoundException ex) { + // File doesn't exist + return false; } + } else { + // Ordinary file + return f.canWrite(); } - } catch (SecurityException e) { - return false; } } diff --git a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java index 24e2bb45df8..0a4fb12cda6 100644 --- a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java +++ b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolder2.java @@ -666,13 +666,6 @@ public String call() throws IOException { return getFileSystemPath0(csidl); } }, IOException.class); - if (path != null) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(path); - } - } return path; } @@ -750,11 +743,6 @@ private native long getEnumObjects(long pIShellFolder, boolean isDesktop, * {@code null} if this shellfolder does not denote a directory. */ public File[] listFiles(final boolean includeHiddenFiles) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(getPath()); - } try { File[] files = invoke(new Callable() { @@ -813,7 +801,7 @@ && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) { } }, InterruptedException.class); - return Win32ShellFolderManager2.checkFiles(files); + return files; } catch (InterruptedException e) { return new File[0]; } diff --git a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java index 810b25b55fd..53653f07f34 100644 --- a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java +++ b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java @@ -42,7 +42,6 @@ import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -import java.util.stream.Stream; import sun.awt.OSInfo; import sun.awt.util.ThreadGroupUtils; @@ -167,9 +166,6 @@ static Win32ShellFolder2 getDesktop() { if (desktop == null) { try { desktop = new Win32ShellFolder2(DESKTOP); - } catch (final SecurityException ignored) { - // Ignore, the message may have sensitive information, not - // accessible other ways } catch (IOException | InterruptedException e) { if (log.isLoggable(PlatformLogger.Level.WARNING)) { log.warning("Cannot access 'Desktop'", e); @@ -183,9 +179,6 @@ static Win32ShellFolder2 getDrives() { if (drives == null) { try { drives = new Win32ShellFolder2(DRIVES); - } catch (final SecurityException ignored) { - // Ignore, the message may have sensitive information, not - // accessible other ways } catch (IOException | InterruptedException e) { if (log.isLoggable(PlatformLogger.Level.WARNING)) { log.warning("Cannot access 'Drives'", e); @@ -202,9 +195,6 @@ static Win32ShellFolder2 getRecent() { if (path != null) { recent = createShellFolder(getDesktop(), new File(path)); } - } catch (final SecurityException ignored) { - // Ignore, the message may have sensitive information, not - // accessible other ways } catch (InterruptedException | IOException e) { if (log.isLoggable(PlatformLogger.Level.WARNING)) { log.warning("Cannot access 'Recent'", e); @@ -218,9 +208,6 @@ static Win32ShellFolder2 getNetwork() { if (network == null) { try { network = new Win32ShellFolder2(NETWORK); - } catch (final SecurityException ignored) { - // Ignore, the message may have sensitive information, not - // accessible other ways } catch (IOException | InterruptedException e) { if (log.isLoggable(PlatformLogger.Level.WARNING)) { log.warning("Cannot access 'Network'", e); @@ -244,9 +231,6 @@ static Win32ShellFolder2 getPersonal() { personal.setIsPersonal(); } } - } catch (final SecurityException ignored) { - // Ignore, the message may have sensitive information, not - // accessible other ways } catch (InterruptedException | IOException e) { if (log.isLoggable(PlatformLogger.Level.WARNING)) { log.warning("Cannot access 'Personal'", e); @@ -287,7 +271,7 @@ public Object get(String key) { if (file == null) { file = getDesktop(); } - return checkFile(file); + return file; } else if (key.equals("roots")) { // Should be "History" and "Desktop" ? if (roots == null) { @@ -298,11 +282,11 @@ public Object get(String key) { roots = (File[])super.get(key); } } - return checkFiles(roots); + return roots; } else if (key.equals("fileChooserComboBoxFolders")) { Win32ShellFolder2 desktop = getDesktop(); - if (desktop != null && checkFile(desktop) != null) { + if (desktop != null) { ArrayList folders = new ArrayList(); Win32ShellFolder2 drives = getDrives(); @@ -313,7 +297,7 @@ public Object get(String key) { folders.add(desktop); // Add all second level folders - File[] secondLevelFolders = checkFiles(desktop.listFiles()); + File[] secondLevelFolders = desktop.listFiles(); Arrays.sort(secondLevelFolders); for (File secondLevelFolder : secondLevelFolders) { Win32ShellFolder2 folder = (Win32ShellFolder2) secondLevelFolder; @@ -321,7 +305,7 @@ public Object get(String key) { folders.add(folder); // Add third level for "My Computer" if (folder.equals(drives)) { - File[] thirdLevelFolders = checkFiles(folder.listFiles()); + File[] thirdLevelFolders = folder.listFiles(); if (thirdLevelFolders != null && thirdLevelFolders.length > 0) { List thirdLevelFoldersList = Arrays.asList(thirdLevelFolders); @@ -331,7 +315,7 @@ public Object get(String key) { } } } - return checkFiles(folders); + return folders.toArray(new File[folders.size()]); } else { return super.get(key); } @@ -374,7 +358,7 @@ public Object get(String key) { } } } - return checkFiles(folders); + return folders.toArray(new File[folders.size()]); } else if (key.startsWith("fileChooserIcon ")) { String name = key.substring(key.indexOf(" ") + 1); @@ -421,53 +405,6 @@ public Object get(String key) { return null; } - private static File checkFile(File file) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - return (sm == null || file == null) ? file : checkFile(file, sm); - } - - private static File checkFile(File file, @SuppressWarnings("removal") SecurityManager sm) { - try { - sm.checkRead(file.getPath()); - - if (file instanceof Win32ShellFolder2) { - Win32ShellFolder2 f = (Win32ShellFolder2)file; - if (f.isLink()) { - Win32ShellFolder2 link = (Win32ShellFolder2)f.getLinkLocation(); - if (link != null) - sm.checkRead(link.getPath()); - } - } - return file; - } catch (SecurityException se) { - return null; - } - } - - static File[] checkFiles(File[] files) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm == null || files == null || files.length == 0) { - return files; - } - return checkFiles(Arrays.stream(files), sm); - } - - private static File[] checkFiles(List files) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm == null || files.isEmpty()) { - return files.toArray(new File[files.size()]); - } - return checkFiles(files.stream(), sm); - } - - private static File[] checkFiles(Stream filesStream, @SuppressWarnings("removal") SecurityManager sm) { - return filesStream.filter((file) -> checkFile(file, sm) != null) - .toArray(File[]::new); - } - /** * Does {@code dir} represent a "computer" such as a node on the network, or * "My Computer" on the desktop. diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WInputMethod.java b/src/java.desktop/windows/classes/sun/awt/windows/WInputMethod.java index 1dcd4bf11af..e893a58f9ed 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WInputMethod.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WInputMethod.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 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 @@ -319,6 +319,10 @@ public void activate() { isLastFocussedActiveClient = isAc; } isActive = true; + + // Sync currentLocale with the Windows keyboard layout which could be changed + // while the component was inactive. + getLocale(); if (currentLocale != null) { setLocale(currentLocale, true); } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java index 00ba08f1028..2da15b8b6a6 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java @@ -26,7 +26,6 @@ package sun.security.jgss.wrapper; import java.io.Serial; -import java.util.HashMap; import java.security.Provider; import jdk.internal.util.OperatingSystem; @@ -64,10 +63,10 @@ static void debug(String message) { System.err.println(NAME + ": " + message); } - private static final HashMap MECH_MAP = constructMechMap(); + private static final Oid[] MECH_OIDS = getMechOIDs(); @SuppressWarnings("restricted") - private static HashMap constructMechMap() { + private static Oid[] getMechOIDs() { try { // Ensure the InetAddress class is loaded before // loading j2gss. The library will access this class @@ -112,28 +111,29 @@ private static HashMap constructMechMap() { debug("Loaded GSS library: " + libName); } Oid[] mechs = GSSLibStub.indicateMechs(); - HashMap map = new HashMap<>(); - for (int i = 0; i < mechs.length; i++) { - if (DEBUG) { - debug("Native MF for " + mechs[i]); + if (DEBUG) { + for (Oid mech : mechs) { + debug("Native MF for " + mech); } - map.put("GssApiMechanism." + mechs[i], MF_CLASS); } - return map; + return mechs; } } return null; } - // initialize INSTANCE after MECH_MAP is constructed + // initialize INSTANCE after MECH_OIDS is constructed static final Provider INSTANCE = new SunNativeProvider(); public SunNativeProvider() { /* We are the Sun NativeGSS provider */ super(NAME, PROVIDER_VER, INFO); - if (MECH_MAP != null) { - putAll(MECH_MAP); + if (MECH_OIDS != null) { + for (Oid mech : MECH_OIDS) { + putService(new Service(this, "GssApiMechanism", + mech.toString(), MF_CLASS, null, null)); + } } } } diff --git a/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java b/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java index 20a76e38b2e..9ec28f926ec 100644 --- a/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java +++ b/src/java.sql.rowset/share/classes/javax/sql/rowset/BaseRowSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2019, 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 @@ -1892,7 +1892,7 @@ public void setDouble(int parameterIndex, double x) throws SQLException { /** * Sets the designated parameter to the given - * java.lang.BigDecimal value. The driver converts this to + * java.math.BigDecimal value. The driver converts this to * an SQL NUMERIC value when it sends it to the database. *

      * The parameter value set by this method is stored internally and diff --git a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_de.properties b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_de.properties index 1373f3bfa5f..3d4306e988f 100644 --- a/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_de.properties +++ b/src/java.xml.crypto/share/classes/com/sun/org/apache/xml/internal/security/resource/xmlsecurity_de.properties @@ -20,36 +20,36 @@ # algorithm.alreadyRegistered = URI {0} wurde bereits an die Klasse {1} gebunden -algorithm.classDoesNotExist = Kann URI {0} nicht für Klasse {1} registrieren weil sie nicht existiert +algorithm.classDoesNotExist = Kann URI {0} nicht f\u00fcr Klasse {1} registrieren weil sie nicht existiert algorithm.ClassDoesNotExist = Klasse {0} existiert nicht -algorithm.extendsWrongClass = Kann URI {0} nicht für Klasse {1} registrieren weil sie nicht von {2} abgeleitet ist -algorithms.CannotUseAlgorithmParameterSpecOnDSA = AlgorithmParameterSpec kann nicht für DSA Signaturen benutzt werden. -algorithms.CannotUseAlgorithmParameterSpecOnRSA = AlgorithmParameterSpec kann nicht für RSA Signaturen benutzt werden. -algorithms.CannotUseSecureRandomOnMAC = SecureRandom kann nicht für MAC's angewandt werden. +algorithm.extendsWrongClass = Kann URI {0} nicht f\u00fcr Klasse {1} registrieren weil sie nicht von {2} abgeleitet ist +algorithms.CannotUseAlgorithmParameterSpecOnDSA = AlgorithmParameterSpec kann nicht f\u00fcr DSA Signaturen benutzt werden. +algorithms.CannotUseAlgorithmParameterSpecOnRSA = AlgorithmParameterSpec kann nicht f\u00fcr RSA Signaturen benutzt werden. +algorithms.CannotUseSecureRandomOnMAC = SecureRandom kann nicht f\u00fcr MAC's angewandt werden. algorithms.HMACOutputLengthMax = HMACOutputLength darf nicht grosser als {0} sein algorithms.HMACOutputLengthMin = HMACOutputLength darf nicht kleiner als {0} sein -algorithms.HMACOutputLengthOnlyForHMAC = Die HMACOutputLength kann nur bei HMAC integritäts Algorithmen angegeben werden +algorithms.HMACOutputLengthOnlyForHMAC = Die HMACOutputLength kann nur bei HMAC integrit\u00e4ts Algorithmen angegeben werden algorithms.MissingRSAPSSParams = RSAPSSParams is a required Element for http://www.w3.org/2007/05/xmldsig-more#rsa-pss -algorithms.NoSuchAlgorithm = Der Algorithmus {0} ist nicht verfügbar. -algorithms.NoSuchAlgorithm = Der Algorithmus {0} ist nicht verfügbar. Original Nachricht war\: {1} +algorithms.NoSuchAlgorithm = Der Algorithmus {0} ist nicht verf\u00fcgbar. +algorithms.NoSuchAlgorithm = Der Algorithmus {0} ist nicht verf\u00fcgbar. Original Nachricht war\: {1} algorithms.NoSuchMap = Algorithmus URI "{0}" konnte auf keinen JCE Algorithmus gemappt werden algorithms.NoSuchProvider = Der angegebene Provider {0} existiert nicht. Original Nachricht war\: {1} -algorithms.operationOnlyVerification = Ein öffentlicher Schlüssel (public key) kann nur zur Verifizierung einer Signatur verwendet werden. -algorithms.WrongKeyForThisOperation = Der angegebene Schlüssel-Typ kann nicht für diese Operation verwendet werden. Angegeben wurde {0} aber ein {1} wird benötigt. +algorithms.operationOnlyVerification = Ein \u00f6ffentlicher Schl\u00fcssel (public key) kann nur zur Verifizierung einer Signatur verwendet werden. +algorithms.WrongKeyForThisOperation = Der angegebene Schl\u00fcssel-Typ kann nicht f\u00fcr diese Operation verwendet werden. Angegeben wurde {0} aber ein {1} wird ben\u00f6tigt. attributeValueIllegal = Das Attribut {0} hat den Wert {1} muss aber {2} sein. -c14n.Canonicalizer.Exception = Fehler während der Kanonisierung\: Original Nachricht war {0} -c14n.Canonicalizer.IllegalNode = Unzulässiger NodeType {0}, NodeName lautete {1} +c14n.Canonicalizer.Exception = Fehler w\u00e4hrend der Kanonisierung\: Original Nachricht war {0} +c14n.Canonicalizer.IllegalNode = Unzul\u00e4ssiger NodeType {0}, NodeName lautete {1} c14n.Canonicalizer.NoSuchCanonicalizer = Kein Kanonisierer mit dem URI {0} gefunden -c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException während der Kanonisierung\: Original Nachricht war {0} +c14n.Canonicalizer.ParserConfigurationException = ParserConfigurationException w\u00e4hrend der Kanonisierung\: Original Nachricht war {0} c14n.Canonicalizer.RelativeNamespace = Das Element {0} hat einen relativen Namespace: {1}="{2}" -c14n.Canonicalizer.SAXException = SAXException während der Kanonisierung\: Original Nachricht war {0} -c14n.Canonicalizer.TraversalNotSupported = Das DOM Dokument unterstützt keine Traversal {0} -c14n.Canonicalizer.UnsupportedEncoding = Nicht unterstützte Kodierung {0} -c14n.Canonicalizer.UnsupportedOperation = Der Kanonisierer unterstützt diese Operation nicht -c14n.XMLUtils.circumventBug2650forgotten = Die Baumstruktur wurde nicht vorbereitet für die Kanonisierung mit XMLUtils\#circumventBug2650(Document) +c14n.Canonicalizer.SAXException = SAXException w\u00e4hrend der Kanonisierung\: Original Nachricht war {0} +c14n.Canonicalizer.TraversalNotSupported = Das DOM Dokument unterst\u00fctzt keine Traversal {0} +c14n.Canonicalizer.UnsupportedEncoding = Nicht unterst\u00fctzte Kodierung {0} +c14n.Canonicalizer.UnsupportedOperation = Der Kanonisierer unterst\u00fctzt diese Operation nicht +c14n.XMLUtils.circumventBug2650forgotten = Die Baumstruktur wurde nicht vorbereitet f\u00fcr die Kanonisierung mit XMLUtils\#circumventBug2650(Document) certificate.noSki.lowVersion = Das Zertifikat dard kein SubjectKeyIdentifier enthalten da es nur ein X509v{0} ist certificate.noSki.notOctetString = Der SubjectKeyIdentifier des Zertifikates ist kein "OctetString" -certificate.noSki.null = Das Zertifikat enthält kein SubjectKeyIdentifier +certificate.noSki.null = Das Zertifikat enth\u00e4lt kein SubjectKeyIdentifier defaultNamespaceCannotBeSetHere = Standard Namespace kann hier nicht gesetzt werden ElementProxy.nullElement = Kann keinen ElementProxy aus einem null Argument erzeugen empty = {0} @@ -57,23 +57,23 @@ encryption.algorithmCannotBeUsedForEncryptedData = encryption.algorithmCannotBeU encryption.algorithmCannotEatInitParams = encryption.algorithmCannotEatInitParams encryption.algorithmCannotEncryptDecrypt = encryption.algorithmCannotEncryptDecrypt encryption.algorithmCannotWrapUnWrap = encryption.algorithmCannotWrapUnWrap -encryption.ExplicitKeySizeMismatch = Das xenc\:KeySize Element fordert eine Schlüssel-Länge von {0} bits aber der Algorithmus besitzt {1} bits -encryption.nonceLongerThanDecryptedPlaintext = Das angegebene "Nonce" ist länger als der verfügbare Plaintext. +encryption.ExplicitKeySizeMismatch = Das xenc\:KeySize Element fordert eine Schl\u00fcssel-L\u00e4nge von {0} bits aber der Algorithmus besitzt {1} bits +encryption.nonceLongerThanDecryptedPlaintext = Das angegebene "Nonce" ist l\u00e4nger als der verf\u00fcgbare Plaintext. encryption.RSAOAEP.dataHashWrong = Falscher Hash-Wert encryption.RSAOAEP.dataStartWrong = Falscher Start Input {0} encryption.RSAOAEP.dataTooShort = Zu wenig Input encryption.RSAPKCS15.blockTruncated = Block abgeschnitten encryption.RSAPKCS15.noDataInBlock = Im Block sind keine Daten enthalten encryption.RSAPKCS15.unknownBlockType = Unbekannter Block Typ -encryption.nokey = Es ist kein verschlüsselungs Schlüssel geladen und es konnte kein Schlüssel mit Hilfe der "key resolvers" gefunden werden. -endorsed.jdk1.4.0 = Leider scheint niemand unsere Installations-Anleitung zu lesen, deshalb müssen wir es über die Exception machen\: Du hast den "endorsing" Mechanismus vom JDK 1.4 nicht richtig angewandt. Schaue unter nach wie man das Problem löst. -errorMessages.InvalidDigestValueException = Ungültige Signatur\: Referen-Validierung fehlgeschlagen. -errorMessages.InvalidSignatureValueException = Ungültige Signatur\: Core Validierung fehlgeschlagen. +encryption.nokey = Es ist kein verschl\u00fcsselungs Schl\u00fcssel geladen und es konnte kein Schl\u00fcssel mit Hilfe der "key resolvers" gefunden werden. +endorsed.jdk1.4.0 = Leider scheint niemand unsere Installations-Anleitung zu lesen, deshalb m\u00fcssen wir es \u00fcber die Exception machen\: Du hast den "endorsing" Mechanismus vom JDK 1.4 nicht richtig angewandt. Schaue unter nach wie man das Problem l\u00f6st. +errorMessages.InvalidDigestValueException = Ung\u00fcltige Signatur\: Referen-Validierung fehlgeschlagen. +errorMessages.InvalidSignatureValueException = Ung\u00fcltige Signatur\: Core Validierung fehlgeschlagen. errorMessages.IOException = Datei oder Resource kann nicht gelesen werden. -errorMessages.MissingKeyFailureException = Verifizierung fehlgeschlagen, weil der öffentliche Schlüssel (public key) nicht verfügbar ist. Resourcen via addResource() hinzufügen und erneut versuchen. -errorMessages.MissingResourceFailureException = Verifizierung fehlgeschlagen, weil Resourcen nicht verfügbar sind. Resourcen via addResource() hinzufügen und erneut versuchen. +errorMessages.MissingKeyFailureException = Verifizierung fehlgeschlagen, weil der \u00f6ffentliche Schl\u00fcssel (public key) nicht verf\u00fcgbar ist. Resourcen via addResource() hinzuf\u00fcgen und erneut versuchen. +errorMessages.MissingResourceFailureException = Verifizierung fehlgeschlagen, weil Resourcen nicht verf\u00fcgbar sind. Resourcen via addResource() hinzuf\u00fcgen und erneut versuchen. errorMessages.NoSuchAlgorithmException = Unbekannter Algorithmus {0} -errorMessages.NotYetImplementedException = Funktionalität noch nicht implementiert. +errorMessages.NotYetImplementedException = Funktionalit\u00e4t noch nicht implementiert. errorMessages.XMLSignatureException = Verifizierung aus unbekanntem Grund fehlgeschlagen. decoding.divisible.four = It should be divisible by four decoding.general = Fehler beim Decodieren @@ -84,70 +84,70 @@ FileKeyStorageImpl.NoCert.SubjName = Kein X509-Zertifikat mit SubjectName {0} ge generic.dontHaveConstructionElement = Konstruktions-Element fehlt generic.EmptyMessage = {0} generic.NotYetImplemented = {0} Leider noch nicht implementiert ;-(( -java.security.InvalidKeyException = Ungültiger Schlüssel -java.security.NoSuchProviderException = Unbekannter oder nicht unterstützter Provider -java.security.UnknownKeyType = Unbekannter oder nicht unterstützter Schlüssel-Typ {0} +java.security.InvalidKeyException = Ung\u00fcltiger Schl\u00fcssel +java.security.NoSuchProviderException = Unbekannter oder nicht unterst\u00fctzter Provider +java.security.UnknownKeyType = Unbekannter oder nicht unterst\u00fctzter Schl\u00fcssel-Typ {0} KeyInfo.error = Error loading Key Info -KeyInfo.needKeyResolver = Es müssen mehrere KeyResolver registriert sein -KeyInfo.nokey = Kann keinen Schlüssel aus {0} gewinnen -KeyInfo.noKey = Kann keinen öffentlichen Schlüssel finden -KeyInfo.wrongNumberOfObject = Benötige {0} keyObjects +KeyInfo.needKeyResolver = Es m\u00fcssen mehrere KeyResolver registriert sein +KeyInfo.nokey = Kann keinen Schl\u00fcssel aus {0} gewinnen +KeyInfo.noKey = Kann keinen \u00f6ffentlichen Schl\u00fcssel finden +KeyInfo.wrongNumberOfObject = Ben\u00f6tige {0} keyObjects KeyInfo.wrongUse = Dieses Objekt wird verwendet, um {0} zu gewinnen -keyResolver.alreadyRegistered = Die Klasse {1} wurde bereits registriert für {0} -KeyResolver.needStorageResolver = Es wird ein StorageResolver benötigt um ein Zertifikat aus {0} zu holen +keyResolver.alreadyRegistered = Die Klasse {1} wurde bereits registriert f\u00fcr {0} +KeyResolver.needStorageResolver = Es wird ein StorageResolver ben\u00f6tigt um ein Zertifikat aus {0} zu holen KeyResoverSpiImpl.cannotGetCert = Cannot get the Certificate that include or in {1} in implement class {0} KeyResoverSpiImpl.elementGeneration = Cannot make {1} element in implement class {0} KeyResoverSpiImpl.getPoublicKey = Cannot get the public key from implement class {0} KeyResoverSpiImpl.InvalidElement = Cannot set (2) Element in implement class {0} KeyResoverSpiImpl.keyStore = KeyStorage Fehler in der implementierenden Klasse {0} -KeyResoverSpiImpl.need.Element = Es wird der Typ {1} benötigt in der implementierenden Klasse {0} +KeyResoverSpiImpl.need.Element = Es wird der Typ {1} ben\u00f6tigt in der implementierenden Klasse {0} KeyResoverSpiImpl.wrongCRLElement = Cannot make CRL from {1} in implement class {0} KeyResoverSpiImpl.wrongKeyObject = Need {1} type of KeyObject for generation Element in implement class{0} KeyResoverSpiImpl.wrongNumberOfObject = Need {1} keyObject in implement class {0} -KeyStore.alreadyRegistered = Klasse {0} bereits registriert für {1} +KeyStore.alreadyRegistered = Klasse {0} bereits registriert f\u00fcr {1} KeyStore.register = {1} type class register error in class {0} -KeyStore.registerStore.register = Registrierungsfehler für Typ {0} +KeyStore.registerStore.register = Registrierungsfehler f\u00fcr Typ {0} KeyValue.IllegalArgument = Kann kein {0} aus {1} erzeugen namespacePrefixAlreadyUsedByOtherURI = Namespace {0} wird bereits von einer anderen URI {1} gebraucht notYetInitialized = Das Modul {0} ist noch nicht initialisiert prefix.AlreadyAssigned = Sie binden den Prefix {0} an den Namespace {1} aber er ist bereits an {2} zugewiesen -signature.Canonicalizer.UnknownCanonicalizer = Unbekannter Kanonisierer. Kein Handler installiert für URI {0} -signature.DSA.invalidFormat = Ungültige ASN.1 Kodierung der DSA Signatur +signature.Canonicalizer.UnknownCanonicalizer = Unbekannter Kanonisierer. Kein Handler installiert f\u00fcr URI {0} +signature.DSA.invalidFormat = Ung\u00fcltige ASN.1 Kodierung der DSA Signatur signature.Generation.signBeforeGetValue = Es muss zuerst XMLSignature.sign(java.security.PrivateKey) aufgerufen werden signature.Reference.ForbiddenResolver = Der "Resolver" {0} ist bei aktivierter "secure validation" nicht erlaubt signature.Reference.NoDigestMethod = A Signature Reference Element must contain a DigestMethod child signature.Reference.NoDigestValue = A Signature Reference Element must contain a DigestValue child signature.signatureAlgorithm = Der Algorithmus {0} ist bei aktivierter "secure validation" nicht erlaubt signature.signaturePropertyHasNoTarget = Das Target Attribut der SignatureProperty muss gesetzt sein -signature.tooManyReferences = Das Manifest enthält {0} Referenzen, bei aktivierter "secure validation" sind aber maximal {1} erlaubt -signature.tooManyTransforms = Die Referenz enthält {0} Transformationen, bei aktivierter "secure validation" sind aber maximal {1} erlaubt -signature.Transform.ErrorDuringTransform = Während der Transformation {0} trat eine {1} auf. +signature.tooManyReferences = Das Manifest enth\u00e4lt {0} Referenzen, bei aktivierter "secure validation" sind aber maximal {1} erlaubt +signature.tooManyTransforms = Die Referenz enth\u00e4lt {0} Transformationen, bei aktivierter "secure validation" sind aber maximal {1} erlaubt +signature.Transform.ErrorDuringTransform = W\u00e4hrend der Transformation {0} trat eine {1} auf. signature.Transform.ForbiddenTransform = Die Transformation {0} ist bei aktivierter "secure validation" nicht erlaubt signature.Transform.NotYetImplemented = Transform {0} noch nicht implementiert -signature.Transform.NullPointerTransform = Null pointer als URI übergeben. Programmierfehler? -signature.Transform.UnknownTransform = Unbekannte Transformation. Kein Handler installiert für URI {0} +signature.Transform.NullPointerTransform = Null pointer als URI \u00fcbergeben. Programmierfehler? +signature.Transform.UnknownTransform = Unbekannte Transformation. Kein Handler installiert f\u00fcr URI {0} signature.Util.BignumNonPositive = bigInteger.signum() muss positiv sein signature.Util.NonTextNode = Keine Text Node signature.Util.TooManyChilds = Zu viele Kind-Elemente vom Typ {0} in {1} signature.Verification.certificateError = Zertifikatsfehler signature.Verification.IndexOutOfBounds = Index {0} illegal. Es sind nur {1} Referenzen vorhanden signature.Verification.internalError = Interner Fehler -signature.Verification.InvalidDigestOrReference = Ungültiger Digest Wert der Referenz {0} +signature.Verification.InvalidDigestOrReference = Ung\u00fcltiger Digest Wert der Referenz {0} signature.Verification.InvalidElement = Current Node {0} is not permitted in this location in the Signature -signature.Verification.keyStore = Öffnen des KeyStore fehlgeschlagen +signature.Verification.keyStore = \u00d6ffnen des KeyStore fehlgeschlagen signature.Verification.MissingID = Element mit der ID {0} nicht gefunden -signature.Verification.MissingResources = Kann die externe Resource {0} nicht auflösen +signature.Verification.MissingResources = Kann die externe Resource {0} nicht aufl\u00f6sen signature.Verification.MultipleIDs = Mehrere Elemente mit der ID {0} gefunden -signature.Verification.NoSignatureElement = Input Dokument enthält kein {0} Element mit dem Namespace {1} -signature.Verification.Reference.NoInput = Die Referenz für den URI {0} hat keinen XMLSignatureInput erhalten. +signature.Verification.NoSignatureElement = Input Dokument enth\u00e4lt kein {0} Element mit dem Namespace {1} +signature.Verification.Reference.NoInput = Die Referenz f\u00fcr den URI {0} hat keinen XMLSignatureInput erhalten. signature.Verification.SignatureError = Signatur Fehler signature.XMLSignatureInput.MissingConstuctor = Kann aus der Klasse {0} keinen XMLSignatureInput erzeugen signature.XMLSignatureInput.SerializeDOM = Input mit einem DOM Dokument initialisiert. Muss mit C14N serialisiert werden -transform.Init.IllegalContextArgument = Unzulässiges Kontext Argument der Klasse {0}. Muss String, org.w3c.dom.NodeList oder java.io.InputStream sein. +transform.Init.IllegalContextArgument = Unzul\u00e4ssiges Kontext Argument der Klasse {0}. Muss String, org.w3c.dom.NodeList oder java.io.InputStream sein. transform.init.NotInitialized = transform.init.wrongURI = Initialisiert mit dem falschen URI. Das sollte nie passieren. Die Transformation implementiert {0} aber {1} wurde bei der Instantiierung verwendet. -utils.Base64.IllegalBitlength = Ungültige Byte-Länge; Muss ein vielfaches von 4 sein -utils.resolver.noClass = Keinen Resolver für URI {0} und Base {1} gefunden +utils.Base64.IllegalBitlength = Ung\u00fcltige Byte-L\u00e4nge; Muss ein vielfaches von 4 sein +utils.resolver.noClass = Keinen Resolver f\u00fcr URI {0} und Base {1} gefunden xml.WrongContent = Kann {0} nicht finden in {1} xml.WrongElement = Kann kein {0} aus einem {1} Element erzeugen xpath.funcHere.documentsDiffer = Der XPath ist nicht im selben Dokument wie der Kontext Node @@ -157,43 +157,43 @@ signature.Transform.nodeAndType = Aktuelle Node\: {0}, Typ\: {1} signature.XMLSignatureInput.nodesetReference = Das Node-Set der Referenz konnte nicht konvertieren werden transform.envelopedSignatureTransformNotInSignatureElement = Enveloped Transform konnte kein Signatur Element finden Base64Decoding = Fehler bei der Decodierung -secureProcessing.MaximumAllowedTransformsPerReference = Die Referenz enthält {0} Transformationen. Es sind aber maximal {1} erlaubt. Die Limite kann über das Konfigurations-Property "MaximumAllowedTransformsPerReference" erhöht werden. -secureProcessing.MaximumAllowedReferencesPerManifest = Das Manifest enhält {0} Referenzen. Es sind aber maximal {1} erlaubt. Die Limite kann über das Konfigurations-Property "MaximumAllowedReferencesPerManifest" erhöht werden. -secureProcessing.DoNotThrowExceptionForManifests = Signatur-Manifests werden nicht unterstützt. Das werfen dieser Exception kann durch das Konfigurations-Property "DoNotThrowExceptionForManifests" verhindert werden. -secureProcessing.AllowMD5Algorithm = Vom Einsatz des MD5 Algorithmus wird strengstens abgeraten. Trotzdem kann er über das Konfigurations-Property "AllowMD5Algorithm" erlaubt werden. -secureProcessing.AllowNotSameDocumentReferences = Externe Referenzen gefunden. Die Verarbeitung von externen Referenzen ist standardmässig ausgeschaltet. Es kann über das Konfigurations-Property "AllowNotSameDocumentReferences" aktiviert werden. -secureProcessing.MaximumAllowedXMLStructureDepth = Die Maximum erlaubte Dokumenten-Tiefe von ({0}) wurde erreicht. Die Limite kann über das Konfigurations-Property "MaximumAllowedXMLStructureDepth" erhöht werden. +secureProcessing.MaximumAllowedTransformsPerReference = Die Referenz enth\u00e4lt {0} Transformationen. Es sind aber maximal {1} erlaubt. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedTransformsPerReference" erh\u00f6ht werden. +secureProcessing.MaximumAllowedReferencesPerManifest = Das Manifest enh\u00e4lt {0} Referenzen. Es sind aber maximal {1} erlaubt. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedReferencesPerManifest" erh\u00f6ht werden. +secureProcessing.DoNotThrowExceptionForManifests = Signatur-Manifests werden nicht unterst\u00fctzt. Das werfen dieser Exception kann durch das Konfigurations-Property "DoNotThrowExceptionForManifests" verhindert werden. +secureProcessing.AllowMD5Algorithm = Vom Einsatz des MD5 Algorithmus wird strengstens abgeraten. Trotzdem kann er \u00fcber das Konfigurations-Property "AllowMD5Algorithm" erlaubt werden. +secureProcessing.AllowNotSameDocumentReferences = Externe Referenzen gefunden. Die Verarbeitung von externen Referenzen ist standardm\u00e4ssig ausgeschaltet. Es kann \u00fcber das Konfigurations-Property "AllowNotSameDocumentReferences" aktiviert werden. +secureProcessing.MaximumAllowedXMLStructureDepth = Die Maximum erlaubte Dokumenten-Tiefe von ({0}) wurde erreicht. Die Limite kann \u00fcber das Konfigurations-Property "MaximumAllowedXMLStructureDepth" erh\u00f6ht werden. secureProcessing.inputStreamLimitReached = Maximal erlaubte Anzahl bytes ({0}) erreicht. stax.duplicateActions=Doppelte Actions sind nicht erlaubt. stax.missingSecurityProperties = SecurityProperties darf nicht null sein\! stax.noOutputAction = Keine ausgehenden "Actions" definiert. -stax.noKey = Kein Schlüssel geladen und es konnte kein Schlüssel gefunden werden für {0} -stax.keyNotFound = Schlüssel nicht gefunden. -stax.unsupportedKeyValue = Kein oder ungültiger KeyValue. -stax.emptyReferenceURI = Referenz enthält kein URI Attribut. -stax.encryption.unprocessedReferences = Es wurden nicht alle Verschlüsselungs-Referenzen verarbeitet... +stax.noKey = Kein Schl\u00fcssel geladen und es konnte kein Schl\u00fcssel gefunden werden f\u00fcr {0} +stax.keyNotFound = Schl\u00fcssel nicht gefunden. +stax.unsupportedKeyValue = Kein oder ung\u00fcltiger KeyValue. +stax.emptyReferenceURI = Referenz enth\u00e4lt kein URI Attribut. +stax.encryption.unprocessedReferences = Es wurden nicht alle Verschl\u00fcsselungs-Referenzen verarbeitet... stax.signature.unprocessedReferences = Es wurden nicht alle Signatur-Referenzen verarbeitet... -stax.unsupportedToken = {0} nicht unterstützt. +stax.unsupportedToken = {0} nicht unterst\u00fctzt. stax.xmlStructureSizeExceeded = Maximal erlaubte ({0}) XML-Struktur Tiefe erreicht. stax.unexpectedXMLEvent = Unerwarteter StAX-Event\: {0} -stax.encryption.noEncAlgo = xenc\:EncryptedKey enthält kein xenc\:EncryptionMethod/@Algorithm. -stax.encryption.noCipherValue = EncryptedKey enthält kein xenc\:CipherData/xenc\:CipherValue. +stax.encryption.noEncAlgo = xenc\:EncryptedKey enth\u00e4lt kein xenc\:EncryptionMethod/@Algorithm. +stax.encryption.noCipherValue = EncryptedKey enth\u00e4lt kein xenc\:CipherData/xenc\:CipherValue. stax.unsecuredMessage = Ungesicherte Nachricht. Weder ein Signatur- noch ein EncryptedData- Element wurde gefunden. stax.signature.signedInfoMissing = SignedInfo Element fehlt. stax.signature.signatureMethodMissing = Signature method fehlt. stax.signature.canonicalizationMethodMissing = Signature canonicalization method fehlt. stax.signature.signatureValueMissing = Signature value fehlt. stax.signature.publicKeyOrCertificateMissing = Weder ein Zertifikat noch ein public-key wurde konfiguriert. -stax.encryption.encryptionKeyMissing = Kein Schlüssel für die Verschlüsselung wurde konfiguriert. -stax.unsupportedKeyTransp = Der public-key Algorithmus ist zu kurz um den symmetrischen Schlüssel zu verschlüsseln. -stax.recursiveKeyReference = Rekursive Schlüssel referenzierung detektiert. -stax.ecParametersNotSupported = ECParameters werden nicht unterstützt. +stax.encryption.encryptionKeyMissing = Kein Schl\u00fcssel f\u00fcr die Verschl\u00fcsselung wurde konfiguriert. +stax.unsupportedKeyTransp = Der public-key Algorithmus ist zu kurz um den symmetrischen Schl\u00fcssel zu verschl\u00fcsseln. +stax.recursiveKeyReference = Rekursive Schl\u00fcssel referenzierung detektiert. +stax.ecParametersNotSupported = ECParameters werden nicht unterst\u00fctzt. stax.namedCurveMissing = NamedCurve fehlt. -stax.encryption.securePartNotFound = Part zum Verschlüsseln nicht gefunden: {0} +stax.encryption.securePartNotFound = Part zum Verschl\u00fcsseln nicht gefunden: {0} stax.signature.securePartNotFound = Part zum Signieren nicht gefunden: {0} stax.multipleSignaturesNotSupported = Mehrere Signaturen werden nicht unterstützt. stax.signature.keyNameMissing = KeyName nicht konfiguriert. -stax.keyNotFoundForName = Kein Schlüssel für Schlüsselname konfiguriert: {0} -stax.keyTypeNotSupported = Key vom Typ {0} nicht für einen Key-Namenssuche unterstützt +stax.keyNotFoundForName = Kein Schl\u00fcssel für Schl\u00fcsselname konfiguriert: {0} +stax.keyTypeNotSupported = Key vom Typ {0} nicht f\u00fcr einen Key-Namenssuche unterst\u00fctzt stax.idsetbutnotgenerated = An Id attribute is specified, but Id generation is disabled stax.idgenerationdisablewithmultipleparts = Id generation must not be disabled when multiple parts need signing diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index c55c2db98de..a02945dee3c 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -3428,7 +3428,7 @@ PatternResult analyzePattern(int lookahead) { case GTGT: typeDepth--; case GT: typeDepth--; - if (typeDepth == 0) { + if (typeDepth == 0 && !peekToken(lookahead, DOT)) { return peekToken(lookahead, LAX_IDENTIFIER) || peekToken(lookahead, tk -> tk == LPAREN) ? PatternResult.PATTERN : PatternResult.EXPRESSION; diff --git a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java index ea2845f56f5..ebcbaa3a773 100644 --- a/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java +++ b/src/jdk.httpserver/share/classes/com/sun/net/httpserver/HttpExchange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, 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 @@ -233,22 +233,29 @@ protected HttpExchange() { public abstract String getProtocol(); /** - * {@link Filter} modules may store arbitrary objects with {@code HttpExchange} - * instances as an out-of-band communication mechanism. Other filters + * Returns the attribute's value from this exchange's + * {@linkplain HttpContext#getAttributes() context attributes}. + * + * @apiNote {@link Filter} modules may store arbitrary objects as attributes through + * {@code HttpExchange} instances as an out-of-band communication mechanism. Other filters * or the exchange handler may then access these objects. * *

      Each {@code Filter} class will document the attributes which they make * available. * * @param name the name of the attribute to retrieve - * @return the attribute object, or {@code null} if it does not exist + * @return the attribute's value or {@code null} if either the attribute isn't set + * or the attribute value is {@code null} * @throws NullPointerException if name is {@code null} */ public abstract Object getAttribute(String name); /** - * {@link Filter} modules may store arbitrary objects with {@code HttpExchange} - * instances as an out-of-band communication mechanism. Other filters + * Sets an attribute with the given {@code name} and {@code value} in this exchange's + * {@linkplain HttpContext#getAttributes() context attributes}. + * + * @apiNote {@link Filter} modules may store arbitrary objects as attributes through + * {@code HttpExchange} instances as an out-of-band communication mechanism. Other filters * or the exchange handler may then access these objects. * *

      Each {@code Filter} class will document the attributes which they make diff --git a/src/jdk.jcmd/share/man/jcmd.md b/src/jdk.jcmd/share/man/jcmd.md index 2d2e08bc9f5..4e67e7a4502 100644 --- a/src/jdk.jcmd/share/man/jcmd.md +++ b/src/jdk.jcmd/share/man/jcmd.md @@ -737,6 +737,17 @@ The following commands are available: - `-e`: (Optional) Print extended thread information (BOOLEAN, false) - `-l`: (Optional) Prints `java.util.concurrent` locks (BOOLEAN, false) +`Thread.vthread_scheduler` +: Print the virtual thread scheduler, and the delayed task schedulers that support + virtual threads doing timed operations. + + Impact: Low + +`Thread.vthread_pollers` +: Print the I/O pollers that support virtual threads doing blocking network I/O operations. + + Impact: Low + `VM.cds` \[*arguments*\] : Dump a static or dynamic shared archive that includes all currently loaded classes. diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/AnnotationWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/AnnotationWriter.java index 66b978f252c..d480cbb1690 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/AnnotationWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/AnnotationWriter.java @@ -225,11 +225,12 @@ private void writeIndex(PoolEntry entry, boolean resolveIndices) { } public void write(AnnotationValue value, boolean resolveIndices) { + var tagChar = (char) value.tag(); switch (value) { case AnnotationValue.OfConstant ev -> { if (resolveIndices) { var entry = ev.constant(); - switch (ev.tag()) { + switch (tagChar) { case 'B': print("(byte) "); print(constantWriter.stringValue(entry)); @@ -258,11 +259,11 @@ public void write(AnnotationValue value, boolean resolveIndices) { print("\""); break; default: - print(ev.tag() + "#" + entry.index()); + print(tagChar + "#" + entry.index()); break; } } else { - print(ev.tag() + "#" + ev.constant().index()); + print(tagChar + "#" + ev.constant().index()); } } case AnnotationValue.OfEnum ev -> { @@ -271,7 +272,7 @@ public void write(AnnotationValue value, boolean resolveIndices) { print("."); writeIndex(ev.constantName(), resolveIndices); } else { - print(ev.tag() + "#" + ev.className().index() + ".#" + print(tagChar + "#" + ev.className().index() + ".#" + ev.constantName().index()); } } @@ -280,11 +281,11 @@ public void write(AnnotationValue value, boolean resolveIndices) { print("class "); writeIndex(ev.className(), resolveIndices); } else { - print(ev.tag() + "#" + ev.className().index()); + print(tagChar + "#" + ev.className().index()); } } case AnnotationValue.OfAnnotation ev -> { - print(ev.tag()); + print(tagChar); AnnotationWriter.this.write(ev.annotation(), resolveIndices); } case AnnotationValue.OfArray ev -> { diff --git a/src/jdk.jfr/share/classes/jdk/jfr/Recording.java b/src/jdk.jfr/share/classes/jdk/jfr/Recording.java index f1dcadf8b68..6168ddb2832 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/Recording.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/Recording.java @@ -97,6 +97,7 @@ public Map toMap() { * support, or if the file repository can't be created or accessed) * * @see jdk.jfr + * @since 11 */ public Recording(Map settings) { Objects.requireNonNull(settings, "settings"); diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java index 466c5d0a14c..9e05fe31aa9 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java @@ -32,6 +32,7 @@ import java.io.DataOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.io.UncheckedIOException; import java.nio.ByteOrder; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -56,7 +57,6 @@ import jdk.tools.jlink.internal.runtimelink.JimageDiffGenerator.ImageResource; import jdk.tools.jlink.internal.runtimelink.ResourceDiff; import jdk.tools.jlink.internal.runtimelink.ResourcePoolReader; -import jdk.tools.jlink.internal.runtimelink.RuntimeImageLinkException; import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ResourcePool; import jdk.tools.jlink.plugin.ResourcePoolBuilder; @@ -91,14 +91,11 @@ public final class ImageFileCreator { private final Map> entriesForModule = new HashMap<>(); private final ImagePluginStack plugins; private final boolean generateRuntimeImage; - private final TaskHelper helper; private ImageFileCreator(ImagePluginStack plugins, - boolean generateRuntimeImage, - TaskHelper taskHelper) { + boolean generateRuntimeImage) { this.plugins = Objects.requireNonNull(plugins); this.generateRuntimeImage = generateRuntimeImage; - this.helper = taskHelper; } /** @@ -118,24 +115,20 @@ private ImageFileCreator(ImagePluginStack plugins, public static ExecutableImage create(Set archives, ByteOrder byteOrder, ImagePluginStack plugins, - boolean generateRuntimeImage, - TaskHelper taskHelper) + boolean generateRuntimeImage) throws IOException { ImageFileCreator image = new ImageFileCreator(plugins, - generateRuntimeImage, - taskHelper); + generateRuntimeImage); try { image.readAllEntries(archives); // write to modular image image.writeImage(archives, byteOrder); - } catch (RuntimeImageLinkException e) { - // readAllEntries() might throw this exception. - // Propagate as IOException with appropriate message for - // jlink runs from the run-time image. This handles better - // error messages for the case of modified files in the run-time - // image. - throw image.newIOException(e); + } catch (UncheckedIOException e) { + // When linking from the run-time image, readAllEntries() might + // throw this exception for a modified runtime. Unpack and + // re-throw as IOException. + throw e.getCause(); } finally { // Close all archives for (Archive a : archives) { @@ -200,11 +193,6 @@ private void writeImage(Set archives, ResourcePool result = null; try (DataOutputStream out = plugins.getJImageFileOutputStream()) { result = generateJImage(allContent, writer, plugins, out, generateRuntimeImage); - } catch (RuntimeImageLinkException e) { - // Propagate as IOException with appropriate message for - // jlink runs from the run-time image. This handles better - // error messages for the case of --patch-module. - throw newIOException(e); } //Handle files. @@ -218,18 +206,6 @@ private void writeImage(Set archives, } } - private IOException newIOException(RuntimeImageLinkException e) throws IOException { - if (JlinkTask.DEBUG) { - e.printStackTrace(); - } - String message = switch (e.getReason()) { - case PATCH_MODULE -> helper.getMessage("err.runtime.link.patched.module", e.getFile()); - case MODIFIED_FILE -> helper.getMessage("err.runtime.link.modified.file", e.getFile()); - default -> throw new AssertionError("Unexpected value: " + e.getReason()); - }; - throw new IOException(message); - } - /** * Create a jimage based on content of the given ResourcePoolManager, * optionally creating a runtime that can be used for linking from the diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JRTArchive.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JRTArchive.java index 755afea8c60..df7d35ac777 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JRTArchive.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JRTArchive.java @@ -26,8 +26,6 @@ package jdk.tools.jlink.internal; import static jdk.tools.jlink.internal.LinkableRuntimeImage.RESPATH_PATTERN; -import static jdk.tools.jlink.internal.runtimelink.RuntimeImageLinkException.Reason.MODIFIED_FILE; -import static jdk.tools.jlink.internal.runtimelink.RuntimeImageLinkException.Reason.PATCH_MODULE; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -37,7 +35,6 @@ import java.lang.module.ModuleReference; import java.nio.charset.StandardCharsets; import java.nio.file.Files; -import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; import java.security.MessageDigest; @@ -56,7 +53,6 @@ import jdk.internal.util.OperatingSystem; import jdk.tools.jlink.internal.Archive.Entry.EntryType; import jdk.tools.jlink.internal.runtimelink.ResourceDiff; -import jdk.tools.jlink.internal.runtimelink.RuntimeImageLinkException; import jdk.tools.jlink.plugin.ResourcePoolEntry; import jdk.tools.jlink.plugin.ResourcePoolEntry.Type; @@ -223,7 +219,9 @@ private void addNonClassResources() { Path path = BASE.resolve(m.resPath); if (shaSumMismatch(path, m.hashOrTarget, m.symlink)) { if (errorOnModifiedFile) { - throw new RuntimeImageLinkException(path.toString(), MODIFIED_FILE); + String msg = taskHelper.getMessage("err.runtime.link.modified.file", path.toString()); + IOException cause = new IOException(msg); + throw new UncheckedIOException(cause); } else { taskHelper.warning("err.runtime.link.modified.file", path.toString()); } @@ -460,16 +458,7 @@ public long size() { // the underlying base path is a JrtPath with the // JrtFileSystem underneath which is able to handle // this size query. - try { - return Files.size(archive.getPath().resolve(resPath)); - } catch (NoSuchFileException file) { - // This indicates that we don't find the class in the - // modules image using the JRT FS provider. Yet, we find - // the class using the system module finder. Therefore, - // we have a patched module. Mention that module patching - // is not supported. - throw new RuntimeImageLinkException(file.getFile(), PATCH_MODULE); - } + return Files.size(archive.getPath().resolve(resPath)); } } catch (IOException e) { throw new UncheckedIOException(e); diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java index 15998d6b929..0eda0b5d455 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java @@ -63,6 +63,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.internal.module.ModuleBootstrap; import jdk.internal.module.ModulePath; import jdk.internal.module.ModuleReferenceImpl; import jdk.internal.module.ModuleResolution; @@ -73,7 +74,6 @@ import jdk.tools.jlink.internal.TaskHelper.BadArgs; import jdk.tools.jlink.internal.TaskHelper.Option; import jdk.tools.jlink.internal.TaskHelper.OptionsHelper; -import jdk.tools.jlink.internal.runtimelink.RuntimeImageLinkException; import jdk.tools.jlink.plugin.PluginException; /** @@ -309,7 +309,7 @@ int run(String[] args) { } cleanupOutput(outputPath); return EXIT_ERROR; - } catch (IllegalArgumentException | ResolutionException | RuntimeImageLinkException e) { + } catch (IllegalArgumentException | ResolutionException e) { log.println(taskHelper.getMessage("error.prefix") + " " + e.getMessage()); if (DEBUG) { e.printStackTrace(log); @@ -620,6 +620,12 @@ private static ImageHelper createImageProvider(JlinkConfiguration config, String msg = taskHelper.getMessage("err.runtime.link.jdk.jlink.prohibited"); throw new IllegalArgumentException(msg); } + // Do not permit linking from run-time image when the current image + // is being patched. + if (ModuleBootstrap.patcher().hasPatches()) { + String msg = taskHelper.getMessage("err.runtime.link.patched.module"); + throw new IllegalArgumentException(msg); + } // Print info message indicating linking from the run-time image if (verbose && log != null) { @@ -1039,7 +1045,7 @@ private static record ImageHelper(Set archives, @Override public ExecutableImage retrieve(ImagePluginStack stack) throws IOException { ExecutableImage image = ImageFileCreator.create(archives, - targetPlatform.arch().byteOrder(), stack, generateRuntimeImage, taskHelper); + targetPlatform.arch().byteOrder(), stack, generateRuntimeImage); if (packagedModulesPath != null) { // copy the packaged modules to the given path Files.createDirectories(packagedModulesPath); diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/RuntimeImageLinkException.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/RuntimeImageLinkException.java deleted file mode 100644 index 9f54fd63476..00000000000 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/runtimelink/RuntimeImageLinkException.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2024, Red Hat, Inc. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.tools.jlink.internal.runtimelink; - -import java.util.Objects; - -/** - * Exception thrown when linking from the run-time image - */ -public class RuntimeImageLinkException extends RuntimeException { - - private static final long serialVersionUID = -1848914673073119403L; - - public static enum Reason { - PATCH_MODULE, /* link exception due to patched module */ - MODIFIED_FILE, /* link exception due to modified file */ - } - - private final String file; - private final Reason reason; - - public RuntimeImageLinkException(String file, Reason reason) { - this.file = Objects.requireNonNull(file); - this.reason = Objects.requireNonNull(reason); - } - - public String getFile() { - return file; - } - - public Reason getReason() { - return reason; - } - - @Override - public String getMessage() { - return reason + ", file: " + file; - } -} diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties index 9e18177d9c8..b5880a35561 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/jlink.properties @@ -125,8 +125,8 @@ err.runtime.link.jdk.jlink.prohibited=This JDK does not contain packaged modules err.runtime.link.packaged.mods=This JDK has no packaged modules.\ \ --keep-packaged-modules is not supported err.runtime.link.modified.file={0} has been modified -err.runtime.link.patched.module=File {0} not found in the modules image.\ -\ --patch-module is not supported when linking from the run-time image +err.runtime.link.patched.module=jlink does not support linking from the run-time image\ +\ when running on a patched runtime with --patch-module err.empty.module.path=empty module path err.jlink.version.mismatch=jlink version {0}.{1} does not match target java.base version {2}.{3} err.automatic.module:automatic module cannot be used with jlink: {0} from {1} diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java index 378e3bb6d40..95a0b71c16d 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/java/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java @@ -382,7 +382,7 @@ private void scheduleLocal() { }; private List scheduleBlock(Collection nodes) { - List schedule = new ArrayList<>(); + LinkedHashSet schedule = new LinkedHashSet(); // Initialize ready priority queue with nodes without predecessors. Queue ready = new PriorityQueue<>(schedulePriority); @@ -407,7 +407,7 @@ private List scheduleBlock(Collection nodes) { } boolean allPredsScheduled = true; for (Node p : s.preds) { - if (!visited.contains(p)) { + if (!schedule.contains(p.inputNode)) { allPredsScheduled = false; break; } @@ -419,7 +419,7 @@ private List scheduleBlock(Collection nodes) { } } assert(schedule.size() == nodes.size()); - return schedule; + return new ArrayList(schedule); } // Return latest block that dominates all successors of n, or null if any diff --git a/test/failure_handler/src/share/conf/common.properties b/test/failure_handler/src/share/conf/common.properties index dd51dc1add9..5cd2c1c13ca 100644 --- a/test/failure_handler/src/share/conf/common.properties +++ b/test/failure_handler/src/share/conf/common.properties @@ -1,5 +1,5 @@ # -# Copyright (c) 2015, 2023, 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 @@ -34,7 +34,7 @@ onTimeout=\ jcmd.vm.classloader_stats jcmd.vm.stringtable \ jcmd.vm.symboltable jcmd.vm.uptime jcmd.vm.dynlibs \ jcmd.vm.system_properties jcmd.vm.info \ - jcmd.gc.heap_info jcmd.gc.class_histogram jcmd.gc.finalizer_info jcmd.thread.dump_to_file \ + jcmd.gc.heap_info jcmd.gc.class_histogram jcmd.gc.finalizer_info jcmd.thread.dump_to_file jcmd.thread.vthread_scheduler \ jstack jhsdb.jstack.live.default jhsdb.jstack.live.mixed jinfo.app=jinfo @@ -61,6 +61,8 @@ jcmd.thread.dump_to_file.args=%p Thread.dump_to_file -format=json JavaThread.dum jcmd.thread.dump_to_file.params.repeat=6 jcmd.thread.dump_to_file.params.successArtifacts=JavaThread.dump.%p.%iterCount +jcmd.thread.vthread_scheduler.args=%p Thread.vthread_scheduler + jstack.app=jstack jstack.args=-e -l %p jstack.params.repeat=6 diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index d04ed90ae07..d68c015496c 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -491,6 +491,7 @@ hotspot_cds_relocation = \ runtime/modules/PatchModule/PatchModuleClassList.java \ runtime/NMT \ serviceability/sa \ + -serviceability/sa/TestJhsdbJstackPrintVMLocks.java \ -runtime/cds/DeterministicDump.java hotspot_cds_verify_shared_spaces = \ diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVMOptions.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVMOptions.java index 05fdf7c06d6..0d75d16d2b0 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVMOptions.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVMOptions.java @@ -125,7 +125,7 @@ static void modulePathTests() throws Exception { "--module-path", goodModulePath + "/bad", "--add-modules", CDSModulePathUtils.TEST_MODULE, CDSModulePathUtils.MAIN_CLASS) - .assertAbnormalExit("Mismatched --add-modules module name(s)", + .assertAbnormalExit("Mismatched values for property jdk.module.addmods", "CDS archive has aot-linked classes. It cannot be used when archived full module graph is not used."); } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java index 2d8f90e61fe..7ce3e37cc8a 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java @@ -80,8 +80,8 @@ public static void main(String[] args) throws Exception { "-m", moduleOption, "-version"); oa.shouldHaveExitValue(0) - .shouldContain("Mismatched --add-modules module name(s).") - .shouldContain("dump time: jdk.jconsole runtime: jdk.incubator.vector") + .shouldContain("Mismatched values for property jdk.module.addmods") + .shouldContain("runtime jdk.incubator.vector dump time jdk.jconsole") .shouldContain(subgraphCannotBeUsed); // no module specified during runtime @@ -89,7 +89,7 @@ public static void main(String[] args) throws Exception { loggingOption, "-version"); oa.shouldHaveExitValue(0) - .shouldContain("Module jdk.httpserver specified during dump time but not during runtime") + .shouldContain("jdk.httpserver specified during dump time but not during runtime") .shouldContain(subgraphCannotBeUsed); // dump an archive without the --add-modules option @@ -109,7 +109,7 @@ public static void main(String[] args) throws Exception { "-m", moduleOption, "-version"); oa.shouldHaveExitValue(0) - .shouldContain("--add-modules module name(s) specified during runtime but not found in archive: jdk.jconsole") + .shouldContain("jdk.jconsole specified during runtime but not during dump time") // version of the jdk.httpserver module, e.g. java 22-ea .shouldMatch(versionPattern) .shouldContain(subgraphCannotBeUsed); diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/module/EnableNativeAccessCDS.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/module/EnableNativeAccessCDS.java new file mode 100644 index 00000000000..10c4000649b --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/module/EnableNativeAccessCDS.java @@ -0,0 +1,133 @@ +/* + * 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 8342089 + * @summary Test consistency of --enable-native-access option for CDS dump time and runtime + * @requires vm.cds.write.archived.java.heap + * @requires vm.flagless + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * @run driver EnableNativeAccessCDS + */ + +import jdk.test.lib.process.OutputAnalyzer; + +public class EnableNativeAccessCDS { + public static void main(String[] args) throws Exception { + final String module0 = "java.base"; + final String module1 = "jdk.httpserver"; + final String disabledOptimizedModule = "Disabling optimized module handling"; + final String loggingOption = "-Xlog:cds=debug"; + + String archiveName = TestCommon.getNewArchiveName("native-access"); + TestCommon.setCurrentArchiveName(archiveName); + + // dump a base archive with --enable-native-access=java.base + OutputAnalyzer oa = TestCommon.dumpBaseArchive( + archiveName, + loggingOption, + "--enable-native-access", module0, + "-version"); + oa.shouldHaveExitValue(0); + + // same module specified during runtime + oa = TestCommon.execCommon( + loggingOption, + "--enable-native-access", module0, + "-version"); + oa.shouldHaveExitValue(0) + .shouldContain("use_full_module_graph = true"); + + // different module specified during runtime + oa = TestCommon.execCommon( + loggingOption, + "--enable-native-access", module1, + "-version"); + oa.shouldHaveExitValue(0) + .shouldContain("Mismatched values for property jdk.module.enable.native.access: runtime jdk.httpserver dump time java.base") + .shouldContain(disabledOptimizedModule); + + // no module specified during runtime + oa = TestCommon.execCommon( + loggingOption, + "-version"); + oa.shouldHaveExitValue(0) + .shouldContain("Mismatched values for property jdk.module.enable.native.access: java.base specified during dump time but not during runtime") + .shouldContain(disabledOptimizedModule); + + // dump an archive without --enable-native-access option + archiveName = TestCommon.getNewArchiveName("no-native-access-modules"); + TestCommon.setCurrentArchiveName(archiveName); + oa = TestCommon.dumpBaseArchive( + archiveName, + loggingOption, + "-version"); + oa.shouldHaveExitValue(0); + + // run with --enable-native-access + oa = TestCommon.execCommon( + loggingOption, + "--enable-native-access", module0, + "-version"); + oa.shouldHaveExitValue(0) + .shouldContain("Mismatched values for property jdk.module.enable.native.access: java.base specified during runtime but not during dump time") + .shouldContain(disabledOptimizedModule); + + // dump an archive with multiple modules with native access + archiveName = TestCommon.getNewArchiveName("multiple-native-access-modules"); + TestCommon.setCurrentArchiveName(archiveName); + oa = TestCommon.dumpBaseArchive( + archiveName, + loggingOption, + "--enable-native-access", module0 + "," + module1, + "-version"); + oa.shouldHaveExitValue(0); + + // same module specified during runtime but in a different order + oa = TestCommon.execCommon( + loggingOption, + "--enable-native-access", module1 + "," + module0, + "-version"); + oa.shouldHaveExitValue(0) + .shouldContain("use_full_module_graph = true"); + + // same module specified during runtime but specifying --enable-native-access twice + oa = TestCommon.execCommon( + loggingOption, + "--enable-native-access", module0, + "--enable-native-access", module1, + "-version"); + oa.shouldHaveExitValue(0) + .shouldContain("use_full_module_graph = true"); + + // run with only one same module + oa = TestCommon.execCommon( + loggingOption, + "--enable-native-access", module0, + "-version"); + oa.shouldHaveExitValue(0) + .shouldContain("Mismatched values for property jdk.module.enable.native.access: runtime java.base dump time java.base,jdk.httpserver") + .shouldContain(disabledOptimizedModule); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/module/ModuleOption.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/module/ModuleOption.java index fa4fa5321ee..d9dcd593430 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/module/ModuleOption.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/module/ModuleOption.java @@ -70,7 +70,7 @@ public static void main(String[] args) throws Exception { "-m", "jdk.compiler/com.sun.tools.javac.Main", "-version"); oa.shouldHaveExitValue(0) - .shouldContain("Mismatched modules: runtime jdk.compiler dump time jdk.httpserver") + .shouldContain("Mismatched values for property jdk.module.main: runtime jdk.compiler dump time jdk.httpserver") .shouldContain(subgraphCannotBeUsed); // no module specified during runtime @@ -78,7 +78,7 @@ public static void main(String[] args) throws Exception { loggingOption, "-version"); oa.shouldHaveExitValue(0) - .shouldContain("Module jdk.httpserver specified during dump time but not during runtime") + .shouldContain("Mismatched values for property jdk.module.main: jdk.httpserver specified during dump time but not during runtime") .shouldContain(subgraphCannotBeUsed); // dump an archive without the module option @@ -96,7 +96,7 @@ public static void main(String[] args) throws Exception { "-m", moduleOption, "-version"); oa.shouldHaveExitValue(0) - .shouldContain("Module jdk.httpserver specified during runtime but not during dump time") + .shouldContain("Mismatched values for property jdk.module.main: jdk.httpserver specified during runtime but not during dump time") // version of the jdk.httpserver module, e.g. java 22-ea .shouldMatch(versionPattern) .shouldContain(subgraphCannotBeUsed); diff --git a/test/hotspot/jtreg/serviceability/dcmd/thread/VThreadCommandsTest.java b/test/hotspot/jtreg/serviceability/dcmd/thread/VThreadCommandsTest.java new file mode 100644 index 00000000000..de2b7249612 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/dcmd/thread/VThreadCommandsTest.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2023, 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 8337199 + * @summary Basic test for jcmd Thread.vthread_scheduler and Thread.vthread_pollers + * @requires vm.continuations + * @modules jdk.jcmd + * @library /test/lib + * @run junit/othervm VThreadCommandsTest + */ + +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.Executors; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinWorkerThread; +import java.util.concurrent.ScheduledThreadPoolExecutor; +import java.util.concurrent.atomic.AtomicBoolean; +import java.lang.management.ManagementFactory; +import jdk.management.VirtualThreadSchedulerMXBean; + +import jdk.test.lib.dcmd.PidJcmdExecutor; +import jdk.test.lib.process.OutputAnalyzer; +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +class VThreadCommandsTest { + + /** + * Thread.vthread_scheduler + */ + @Test + void testVThreadScheduler() { + // ensure default scheduler and timeout schedulers are initialized + Thread.startVirtualThread(() -> { }); + + jcmd("Thread.vthread_scheduler") + .shouldContain(Objects.toIdentityString(defaultScheduler())) + .shouldContain("Delayed task schedulers:") + .shouldContain("[0] " + ScheduledThreadPoolExecutor.class.getName()); + } + + /** + * Thread.vthread_pollers + */ + @Test + void testVThreadPollers() throws Exception { + // do blocking I/O op on a virtual thread to ensure poller mechanism is initialized + try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { + executor.submit(() -> { + try (var listener = new ServerSocket()) { + InetAddress lb = InetAddress.getLoopbackAddress(); + listener.bind(new InetSocketAddress(lb, 0)); + listener.setSoTimeout(200); + try (Socket s = listener.accept()) { + System.err.format("Connection from %s ??%n", s.getRemoteSocketAddress()); + } catch (SocketTimeoutException e) { + // expected + } + } + return null; + }).get(); + } + + jcmd("Thread.vthread_pollers") + .shouldContain("Read I/O pollers:") + .shouldContain("Write I/O pollers:") + .shouldMatch("^\\[0\\] sun\\.nio\\.ch\\..+ \\[registered = [\\d]+, owner = .+\\]$"); + } + + private OutputAnalyzer jcmd(String cmd) { + return new PidJcmdExecutor().execute(cmd); + } + + /** + * Returns the virtual thread default scheduler. This implementation works by finding + * all FJ worker threads and mapping them to their pool. VirtualThreadSchedulerMXBean + * is used to temporarily changing target parallelism to an "unique" value, make it + * possbile to find the right pool. + */ + private ForkJoinPool defaultScheduler() { + var done = new AtomicBoolean(); + Thread vthread = Thread.startVirtualThread(() -> { + while (!done.get()) { + Thread.onSpinWait(); + } + }); + var bean = ManagementFactory.getPlatformMXBean(VirtualThreadSchedulerMXBean.class); + int parallelism = bean.getParallelism(); + try { + bean.setParallelism(133); + return Thread.getAllStackTraces() + .keySet() + .stream() + .filter(ForkJoinWorkerThread.class::isInstance) + .map(t -> ((ForkJoinWorkerThread) t).getPool()) + .filter(p -> p.getParallelism() == 133) + .findAny() + .orElseThrow(); + } finally { + bean.setParallelism(parallelism); + done.set(true); + } + } +} diff --git a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002t.java b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002t.java index 694485e608e..e82b749c905 100644 --- a/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002t.java +++ b/test/hotspot/jtreg/vmTestbase/nsk/jdi/ThreadReference/stop/stop002t.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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 @@ -180,7 +180,7 @@ private int runIt(String args[]) { log.display("TEST #5: interrupted = " + Thread.interrupted()); // We don't expect the exception to be thrown when in vthread mode. if (!vthreadMode && t instanceof MyThrowable) { - log.display("TEST #5: Caught expected exception while in loop: " + t); + log.display("TEST #5: Caught expected exception while in sleep: " + t); } else { log.complain("TEST #5: Unexpected exception caught: " + t); t.printStackTrace(); diff --git a/test/jdk/ProblemList-Virtual.txt b/test/jdk/ProblemList-Virtual.txt index d7692b578cd..eabac31ca34 100644 --- a/test/jdk/ProblemList-Virtual.txt +++ b/test/jdk/ProblemList-Virtual.txt @@ -44,6 +44,8 @@ javax/management/remote/mandatory/connection/DeadLockTest.java 8309069 windows-x javax/management/remote/mandatory/connection/ConnectionTest.java 8308352 windows-x64 +java/util/concurrent/locks/StampedLock/OOMEInStampedLock.java 8345266 generic-all + ########## ## Tests incompatible with virtual test thread factory. ## There is no goal to run all test with virtual test thread factory. diff --git a/test/jdk/com/sun/net/httpserver/ExchangeAttributeTest.java b/test/jdk/com/sun/net/httpserver/ExchangeAttributeTest.java index 2ce3dfd016d..84c7837e0b3 100644 --- a/test/jdk/com/sun/net/httpserver/ExchangeAttributeTest.java +++ b/test/jdk/com/sun/net/httpserver/ExchangeAttributeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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,16 +23,19 @@ /* * @test - * @bug 8288109 + * @bug 8288109 8235786 * @summary Tests for HttpExchange set/getAttribute * @library /test/lib * @run junit/othervm ExchangeAttributeTest */ +import com.sun.net.httpserver.Filter; +import com.sun.net.httpserver.HttpContext; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; import jdk.test.lib.net.URIBuilder; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -53,44 +56,87 @@ public class ExchangeAttributeTest { - static final InetAddress LOOPBACK_ADDR = InetAddress.getLoopbackAddress(); - static final boolean ENABLE_LOGGING = true; - static final Logger logger = Logger.getLogger("com.sun.net.httpserver"); + private static final InetAddress LOOPBACK_ADDR = InetAddress.getLoopbackAddress(); + private static final boolean ENABLE_LOGGING = true; + private static final Logger logger = Logger.getLogger("com.sun.net.httpserver"); + + private static HttpServer server; @BeforeAll - public static void setup() { + public static void setup() throws Exception { if (ENABLE_LOGGING) { ConsoleHandler ch = new ConsoleHandler(); logger.setLevel(Level.ALL); ch.setLevel(Level.ALL); logger.addHandler(ch); } + server = HttpServer.create(new InetSocketAddress(LOOPBACK_ADDR, 0), 10); + server.createContext("/normal", new AttribHandler()); + final HttpContext filteredCtx = server.createContext("/filtered", new AttribHandler()); + filteredCtx.getFilters().add(new AttributeAddingFilter()); + server.start(); + System.out.println("Server started at " + server.getAddress()); + } + + @AfterAll + public static void afterAll() { + if (server != null) { + System.out.println("Stopping server " + server.getAddress()); + server.stop(0); + } } + /* + * Verifies that HttpExchange.setAttribute() allows for null value. + */ @Test - public void testExchangeAttributes() throws Exception { - var handler = new AttribHandler(); - var server = HttpServer.create(new InetSocketAddress(LOOPBACK_ADDR,0), 10); - server.createContext("/", handler); - server.start(); - try { - var client = HttpClient.newBuilder().proxy(NO_PROXY).build(); - var request = HttpRequest.newBuilder(uri(server, "")).build(); + public void testNullAttributeValue() throws Exception { + try (var client = HttpClient.newBuilder().proxy(NO_PROXY).build()) { + var request = HttpRequest.newBuilder(uri(server, "/normal", null)).build(); var response = client.send(request, HttpResponse.BodyHandlers.ofString()); assertEquals(200, response.statusCode()); - } finally { - server.stop(0); + } + } + + /* + * Verifies that an attribute set on one exchange is accessible to another exchange that + * belongs to the same HttpContext. + */ + @Test + public void testSharedAttribute() throws Exception { + try (var client = HttpClient.newBuilder().proxy(NO_PROXY).build()) { + final var firstReq = HttpRequest.newBuilder(uri(server, "/filtered", "firstreq")) + .build(); + System.out.println("issuing request " + firstReq); + final var firstResp = client.send(firstReq, HttpResponse.BodyHandlers.ofString()); + assertEquals(200, firstResp.statusCode()); + + // issue the second request + final var secondReq = HttpRequest.newBuilder(uri(server, "/filtered", "secondreq")) + .build(); + System.out.println("issuing request " + secondReq); + final var secondResp = client.send(secondReq, HttpResponse.BodyHandlers.ofString()); + assertEquals(200, secondResp.statusCode()); + + // verify that the filter was invoked for both the requests. the filter internally + // does the setAttribute() and getAttribute() and asserts that the attribute value + // set by the first exchange was available through the second exchange. + assertTrue(AttributeAddingFilter.filteredFirstReq, "Filter wasn't invoked for " + + firstReq.uri()); + assertTrue(AttributeAddingFilter.filteredSecondReq, "Filter wasn't invoked for " + + secondReq.uri()); } } // --- infra --- - static URI uri(HttpServer server, String path) throws URISyntaxException { + static URI uri(HttpServer server, String path, String query) throws URISyntaxException { return URIBuilder.newBuilder() .scheme("http") .loopback() .port(server.getAddress().getPort()) .path(path) + .query(query) .build(); } @@ -112,4 +158,54 @@ public void handle(HttpExchange exchange) throws IOException { } } } + + private static final class AttributeAddingFilter extends Filter { + + private static final String ATTR_NAME ="foo-bar"; + private static final String ATTR_VAL ="hello-world"; + private static volatile boolean filteredFirstReq; + private static volatile boolean filteredSecondReq; + + @Override + public void doFilter(final HttpExchange exchange, final Chain chain) throws IOException { + if (exchange.getRequestURI().getQuery().contains("firstreq")) { + filteredFirstReq = true; + // add a request attribute through the exchange, for this first request + // and at the same time verify that the attribute doesn't already exist + final Object attrVal = exchange.getAttribute(ATTR_NAME); + if (attrVal != null) { + throw new IOException("attribute " + ATTR_NAME + " with value: " + attrVal + + " unexpectedly present in exchange: " + exchange.getRequestURI()); + } + // set the value + exchange.setAttribute(ATTR_NAME, ATTR_VAL); + System.out.println(exchange.getRequestURI() + " set attribute " + + ATTR_NAME + "=" + ATTR_VAL); + } else if (exchange.getRequestURI().getQuery().contains("secondreq")) { + filteredSecondReq = true; + // verify the attribute is already set and the value is the expected one. + final Object attrVal = exchange.getAttribute(ATTR_NAME); + if (attrVal == null) { + throw new IOException("attribute " + ATTR_NAME + " is missing in exchange: " + + exchange.getRequestURI()); + } + if (!ATTR_VAL.equals(attrVal)) { + throw new IOException("unexpected value: " + attrVal + " for attribute " + + ATTR_NAME + " in exchange: " + exchange.getRequestURI()); + } + System.out.println(exchange.getRequestURI() + " found attribute " + + ATTR_NAME + "=" + attrVal); + } else { + // unexpected request + throw new IOException("unexpected request " + exchange.getRequestURI()); + } + // let the request proceed + chain.doFilter(exchange); + } + + @Override + public String description() { + return "AttributeAddingFilter"; + } + } } diff --git a/test/jdk/java/awt/Focus/UnaccessibleChoice/AccessibleChoiceTest.java b/test/jdk/java/awt/Focus/UnaccessibleChoice/AccessibleChoiceTest.java index 7f17c1978e4..c30e29edd7d 100644 --- a/test/jdk/java/awt/Focus/UnaccessibleChoice/AccessibleChoiceTest.java +++ b/test/jdk/java/awt/Focus/UnaccessibleChoice/AccessibleChoiceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 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,74 +23,75 @@ import java.awt.Button; import java.awt.Choice; +import java.awt.EventQueue; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import java.awt.Point; import java.awt.Robot; -import java.awt.Window; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.image.BufferedImage; import java.io.File; -import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import javax.imageio.ImageIO; -/** +/* * @test * @bug 4478780 * @key headful * @summary Tests that Choice can be accessed and controlled by keyboard. */ -public class AccessibleChoiceTest { - //Declare things used in the test, like buttons and labels here - Frame frame = new Frame("window owner"); - Window win = new Window(frame); - Choice choice = new Choice(); - Button def = new Button("default owner"); - CountDownLatch go = new CountDownLatch(1); - - public static void main(final String[] args) throws IOException { - AccessibleChoiceTest app = new AccessibleChoiceTest(); - app.test(); - } - private void test() throws IOException { +public class AccessibleChoiceTest { + static Frame frame; + static Choice choice; + static Button button; + static volatile CountDownLatch go; + static volatile Point loc; + static volatile int bWidth; + static volatile int bHeight; + + public static void main(final String[] args) throws Exception { try { - init(); - start(); + createAndShowUI(); + test(); } finally { - if (frame != null) frame.dispose(); - if (win != null) win.dispose(); + if (frame != null) { + EventQueue.invokeAndWait(() -> frame.dispose()); + } } } - public void init() { - win.setLayout (new FlowLayout ()); - win.add(def); - def.addFocusListener(new FocusAdapter() { + public static void createAndShowUI() throws Exception { + go = new CountDownLatch(1); + EventQueue.invokeAndWait(() -> { + frame = new Frame("Accessible Choice Test Frame"); + choice = new Choice(); + button = new Button("default owner"); + frame.setLayout(new FlowLayout()); + frame.add(button); + button.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent e) { go.countDown(); } }); - choice.add("One"); - choice.add("Two"); - win.add(choice); + choice.add("One"); + choice.add("Two"); + frame.add(choice); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + }); } - public void start () throws IOException { - frame.setVisible(true); - win.pack(); - win.setLocation(100, 200); - win.setVisible(true); - - Robot robot = null; + public static void test() throws Exception { + Robot robot; try { robot = new Robot(); } catch (Exception ex) { @@ -98,12 +99,17 @@ public void start () throws IOException { } robot.waitForIdle(); robot.delay(1000); - robot.setAutoDelay(150); robot.setAutoWaitForIdle(true); // Focus default button and wait till it gets focus - Point loc = def.getLocationOnScreen(); - robot.mouseMove(loc.x+2, loc.y+2); + EventQueue.invokeAndWait(() -> { + loc = button.getLocationOnScreen(); + bWidth = button.getWidth(); + bHeight = button.getHeight(); + }); + robot.mouseMove(loc.x + bWidth / 2, + loc.y + bHeight / 2); + robot.delay(500); robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); @@ -113,25 +119,30 @@ public void start () throws IOException { throw new RuntimeException("Interrupted !!!"); } - if (!def.isFocusOwner()) { + if (!button.isFocusOwner()) { throw new RuntimeException("Button doesn't have focus"); } + robot.delay(500); + // Press Tab key to move focus to Choice robot.keyPress(KeyEvent.VK_TAB); robot.keyRelease(KeyEvent.VK_TAB); robot.delay(500); - // Press Down key to select next item in the choice(Motif 2.1) + if (!choice.isFocusOwner()) { + throw new RuntimeException("Choice doesn't have focus"); + } + + // Press Down key to select next item in the choice // If bug exists we won't be able to do so robot.keyPress(KeyEvent.VK_DOWN); robot.keyRelease(KeyEvent.VK_DOWN); - robot.delay(500); - String osName = System.getProperty("os.name").toLowerCase(); if (osName.startsWith("mac")) { + robot.delay(500); robot.keyPress(KeyEvent.VK_DOWN); robot.keyRelease(KeyEvent.VK_DOWN); robot.delay(500); @@ -142,7 +153,7 @@ public void start () throws IOException { robot.delay(1000); // On success second item should be selected - if (choice.getSelectedItem() != choice.getItem(1)) { + if (!choice.getSelectedItem().equals(choice.getItem(1))) { // Print out os name to check if mac conditional is relevant System.err.println("Failed on os: " + osName); diff --git a/test/jdk/java/awt/datatransfer/Independence/IndependenceAWTTest.java b/test/jdk/java/awt/datatransfer/Independence/IndependenceAWTTest.java index 2ace3510d1f..990857182e7 100644 --- a/test/jdk/java/awt/datatransfer/Independence/IndependenceAWTTest.java +++ b/test/jdk/java/awt/datatransfer/Independence/IndependenceAWTTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -21,43 +21,67 @@ * questions. */ -import java.awt.*; -import java.awt.datatransfer.*; -import java.awt.event.*; -import java.util.Properties; /* * @test * @key headful + * @requires (os.family == "linux") * @summary To make sure that System & Primary clipboards should behave independently - * @author Jitender(jitender.singh@eng.sun.com) area=AWT - * @author dmitriy.ermashov@oracle.com * @library /lib/client * @build ExtendedRobot * @run main IndependenceAWTTest */ -public class IndependenceAWTTest { +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.EventQueue; +import java.awt.Frame; +import java.awt.HeadlessException; +import java.awt.Panel; +import java.awt.Point; +import java.awt.TextField; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.StringSelection; +import java.awt.datatransfer.Transferable; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.InputEvent; +import java.awt.event.MouseEvent; - Frame frame; - Panel panel; - TextField tf1, tf2, tf3; - Clipboard sClip, pClip; +public class IndependenceAWTTest { + private static Frame frame; + private static TextField tf1; + private static TextField tf2; + private static TextField tf3; + private static Clipboard systemClip; + private static Clipboard primaryClip; + private static ExtendedRobot robot; + private static volatile Point ttf1Center; + private static volatile Point glideStartLocation; public static void main (String[] args) throws Exception { - new IndependenceAWTTest().doTest(); + try { + robot = new ExtendedRobot(); + EventQueue.invokeAndWait(IndependenceAWTTest::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + test(); + } finally { + EventQueue.invokeAndWait(frame::dispose); + } } - public IndependenceAWTTest() { - - frame = new Frame(); + private static void createAndShowUI() { + frame = new Frame("IndependenceAWTTest"); frame.setSize(200, 200); // This textfield will be used to update the contents of clipboards tf1 = new TextField(); tf1.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent fe) { - tf1.setText("Clipboards_Independance_Testing"); + tf1.setText("Clipboards_Independence_Testing"); } }); @@ -65,7 +89,7 @@ public void focusGained(FocusEvent fe) { tf2 = new TextField(); tf3 = new TextField(); - panel = new Panel(); + Panel panel = new Panel(); panel.setLayout(new BorderLayout()); panel.add(tf2, BorderLayout.NORTH); @@ -73,38 +97,36 @@ public void focusGained(FocusEvent fe) { frame.add(tf1, BorderLayout.NORTH); frame.add(panel, BorderLayout.CENTER); + frame.setLocationRelativeTo(null); frame.setVisible(true); tf1.requestFocus(); } // Get System Selection i.e. Primary Clipboard - private void getPrimaryClipboard() { - Properties ps = System.getProperties(); - String operSys = ps.getProperty("os.name"); + private static void getPrimaryClipboard() { try { - pClip = Toolkit.getDefaultToolkit().getSystemSelection(); - if (pClip == null) - if ((operSys.substring(0,3)).equalsIgnoreCase("Win") || operSys.toLowerCase().contains("os x")) - System.out.println(operSys + "Operating system does not support system selection "); - else - throw new RuntimeException("Method getSystemSelection() is returning null on X11 platform"); - } catch(HeadlessException e) { + primaryClip = Toolkit.getDefaultToolkit().getSystemSelection(); + if (primaryClip == null) { + throw new RuntimeException("Method getSystemSelection() is returning null" + + " on Linux platform"); + } + } catch (HeadlessException e) { System.out.println("Headless exception thrown " + e); } } // Method to get the contents of both of the clipboards - public void getClipboardsContent() throws Exception { - sClip = Toolkit.getDefaultToolkit().getSystemClipboard(); + private static void getClipboardsContent() throws Exception { + systemClip = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable tp; Transferable ts; StringSelection content = new StringSelection(tf1.getText()); - sClip.setContents(content,content); + systemClip.setContents(content, content); - tp = pClip.getContents(this); - ts = sClip.getContents(this); + tp = primaryClip.getContents(null); + ts = systemClip.getContents(null); // Paste the contents of System clipboard on textfield tf2 while the paste the contents of // of primary clipboard on textfiled tf3 @@ -122,7 +144,7 @@ public void getClipboardsContent() throws Exception { } // Method to compare the Contents return by system & primary clipboard - public void compareText (boolean mustEqual) { + private static void compareText (boolean mustEqual) { if ((tf2.getText()).equals(tf3.getText())) { if (mustEqual) System.out.println("Selected text & clipboard contents are same\n"); @@ -136,40 +158,39 @@ public void compareText (boolean mustEqual) { } } - public void doTest() throws Exception { + private static void test() throws Exception { getPrimaryClipboard(); - ExtendedRobot robot = new ExtendedRobot(); - robot.waitForIdle(1000); - frame.setLocation(100, 100); - robot.waitForIdle(1000); - - if (pClip != null) { - Point ttf1Center = tf1.getLocationOnScreen(); - ttf1Center.translate(tf1.getWidth()/2, tf1.getHeight()/2); - - robot.glide(new Point(0, 0), ttf1Center); - robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.waitForIdle(20); - robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - robot.waitForIdle(20); - robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.waitForIdle(20); - robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - robot.waitForIdle(2000); - - getClipboardsContent(); - compareText(true); - - //Change the text selection to update the contents of primary clipboard - robot.mouseMove(ttf1Center); - robot.mousePress(MouseEvent.BUTTON1_MASK); - robot.delay(200); - robot.mouseMove(ttf1Center.x + 15, ttf1Center.y); - robot.mouseRelease(MouseEvent.BUTTON1_MASK); - robot.waitForIdle(2000); - - getClipboardsContent(); - compareText(false); - } + robot.waitForIdle(500); + + EventQueue.invokeAndWait(() -> { + Point center = tf1.getLocationOnScreen(); + center.translate(tf1.getWidth() / 2, tf1.getHeight() / 2); + ttf1Center = center; + + glideStartLocation = frame.getLocationOnScreen(); + glideStartLocation.x -= 10; + }); + + robot.glide(glideStartLocation, ttf1Center); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(20); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(500); + + getClipboardsContent(); + compareText(true); + + //Change the text selection to update the contents of primary clipboard + robot.mouseMove(ttf1Center); + robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK); + robot.delay(20); + robot.mouseMove(ttf1Center.x + 15, ttf1Center.y); + robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(500); + + getClipboardsContent(); + compareText(false); } } diff --git a/test/jdk/java/awt/datatransfer/Independence/IndependenceSwingTest.java b/test/jdk/java/awt/datatransfer/Independence/IndependenceSwingTest.java index 4ee7dea6a54..b2f594c13ae 100644 --- a/test/jdk/java/awt/datatransfer/Independence/IndependenceSwingTest.java +++ b/test/jdk/java/awt/datatransfer/Independence/IndependenceSwingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 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 @@ -21,8 +21,21 @@ * questions. */ -import javax.swing.*; -import java.awt.*; +/* + * @test + * @key headful + * @requires (os.family == "linux") + * @summary To make sure that System & Primary clipboards should behave independently + * @library /lib/client + * @build ExtendedRobot + * @run main IndependenceSwingTest + */ + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.HeadlessException; +import java.awt.Point; +import java.awt.Toolkit; import java.awt.datatransfer.Clipboard; import java.awt.datatransfer.DataFlavor; import java.awt.datatransfer.StringSelection; @@ -31,40 +44,44 @@ import java.awt.event.FocusEvent; import java.awt.event.InputEvent; import java.awt.event.MouseEvent; -import java.util.Properties; -/* - * @test - * @key headful - * @summary To make sure that System & Primary clipboards should behave independently - * @author Jitender(jitender.singh@eng.sun.com) area=AWT - * @author dmitriy.ermashov@oracle.com - * @library /lib/client - * @build ExtendedRobot - * @run main IndependenceSwingTest - */ +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.SwingUtilities; public class IndependenceSwingTest { - - JFrame frame; - JPanel panel; - JTextField tf1, tf2, tf3; - Clipboard sClip, pClip; + private static JFrame frame; + private static JTextField tf1; + private static JTextField tf2; + private static JTextField tf3; + private static Clipboard systemClip; + private static Clipboard primaryClip; + private static ExtendedRobot robot; + private static volatile Point ttf1Center; + private static volatile Point glideStartLocation; public static void main (String[] args) throws Exception { - new IndependenceSwingTest().doTest(); + try { + robot = new ExtendedRobot(); + SwingUtilities.invokeAndWait(IndependenceSwingTest::createAndShowUI); + robot.waitForIdle(); + robot.delay(1000); + test(); + } finally { + SwingUtilities.invokeAndWait(frame::dispose); + } } - public IndependenceSwingTest() { - - frame = new JFrame(); + private static void createAndShowUI() { + frame = new JFrame("IndependenceSwingTest"); frame.setSize(200, 200); // This textfield will be used to update the contents of clipboards tf1 = new JTextField(); tf1.addFocusListener(new FocusAdapter() { public void focusGained(FocusEvent fe) { - tf1.setText("Clipboards_Independance_Testing"); + tf1.setText("Clipboards_Independence_Testing"); } }); @@ -72,7 +89,7 @@ public void focusGained(FocusEvent fe) { tf2 = new JTextField(); tf3 = new JTextField(); - panel = new JPanel(); + JPanel panel = new JPanel(); panel.setLayout(new BorderLayout()); panel.add(tf2, BorderLayout.NORTH); @@ -80,38 +97,36 @@ public void focusGained(FocusEvent fe) { frame.add(tf1, BorderLayout.NORTH); frame.add(panel, BorderLayout.CENTER); + frame.setLocationRelativeTo(null); frame.setVisible(true); tf1.requestFocus(); } // Get System Selection i.e. Primary Clipboard - private void getPrimaryClipboard() { - Properties ps = System.getProperties(); - String operSys = ps.getProperty("os.name"); + private static void getPrimaryClipboard() { try { - pClip = Toolkit.getDefaultToolkit().getSystemSelection(); - if (pClip == null) - if ((operSys.substring(0,3)).equalsIgnoreCase("Win") || operSys.toLowerCase().contains("os x")) - System.out.println(operSys + "Operating system does not support system selection "); - else - throw new RuntimeException("Method getSystemSelection() is returning null on X11 platform"); - } catch(HeadlessException e) { + primaryClip = Toolkit.getDefaultToolkit().getSystemSelection(); + if (primaryClip == null) { + throw new RuntimeException("Method getSystemSelection() is returning null" + + " on Linux platform"); + } + } catch (HeadlessException e) { System.out.println("Headless exception thrown " + e); } } // Method to get the contents of both of the clipboards - public void getClipboardsContent() throws Exception { - sClip = Toolkit.getDefaultToolkit().getSystemClipboard(); + private static void getClipboardsContent() throws Exception { + systemClip = Toolkit.getDefaultToolkit().getSystemClipboard(); Transferable tp; Transferable ts; StringSelection content = new StringSelection(tf1.getText()); - sClip.setContents(content,content); + systemClip.setContents(content, content); - tp = pClip.getContents(this); - ts = sClip.getContents(this); + tp = primaryClip.getContents(null); + ts = systemClip.getContents(null); // Paste the contents of System clipboard on textfield tf2 while the paste the contents of // of primary clipboard on textfiled tf3 @@ -129,7 +144,7 @@ public void getClipboardsContent() throws Exception { } // Method to compare the Contents return by system & primary clipboard - public void compareText (boolean mustEqual) { + private static void compareText (boolean mustEqual) { if ((tf2.getText()).equals(tf3.getText())) { if (mustEqual) System.out.println("Selected text & clipboard contents are same\n"); @@ -143,40 +158,39 @@ public void compareText (boolean mustEqual) { } } - public void doTest() throws Exception { + private static void test() throws Exception { getPrimaryClipboard(); - ExtendedRobot robot = new ExtendedRobot(); - robot.waitForIdle(1000); - frame.setLocation(100, 100); - robot.waitForIdle(1000); - - if (pClip != null) { - Point ttf1Center = tf1.getLocationOnScreen(); - ttf1Center.translate(tf1.getWidth()/2, tf1.getHeight()/2); - - robot.glide(new Point(0, 0), ttf1Center); - robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.waitForIdle(20); - robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - robot.waitForIdle(20); - robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - robot.waitForIdle(20); - robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - robot.waitForIdle(2000); - - getClipboardsContent(); - compareText(true); - - //Change the text selection to update the contents of primary clipboard - robot.mouseMove(ttf1Center); - robot.mousePress(MouseEvent.BUTTON1_MASK); - robot.delay(200); - robot.mouseMove(ttf1Center.x + 15, ttf1Center.y); - robot.mouseRelease(MouseEvent.BUTTON1_MASK); - robot.waitForIdle(2000); - - getClipboardsContent(); - compareText(false); - } + robot.waitForIdle(500); + + SwingUtilities.invokeAndWait(() -> { + Point center = tf1.getLocationOnScreen(); + center.translate(tf1.getWidth() / 2, tf1.getHeight() / 2); + ttf1Center = center; + + glideStartLocation = frame.getLocationOnScreen(); + glideStartLocation.x -= 10; + }); + + robot.glide(glideStartLocation, ttf1Center); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(20); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(500); + + getClipboardsContent(); + compareText(true); + + //Change the text selection to update the contents of primary clipboard + robot.mouseMove(ttf1Center); + robot.mousePress(MouseEvent.BUTTON1_DOWN_MASK); + robot.delay(20); + robot.mouseMove(ttf1Center.x + 15, ttf1Center.y); + robot.mouseRelease(MouseEvent.BUTTON1_DOWN_MASK); + robot.waitForIdle(500); + + getClipboardsContent(); + compareText(false); } } diff --git a/test/jdk/java/foreign/TestIllegalLink.java b/test/jdk/java/foreign/TestIllegalLink.java index b5052b4346c..45239e3cb45 100644 --- a/test/jdk/java/foreign/TestIllegalLink.java +++ b/test/jdk/java/foreign/TestIllegalLink.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, 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 @@ -192,11 +192,6 @@ public static Object[][] types() { NO_OPTIONS, "has unexpected size" }, - { - FunctionDescriptor.ofVoid(), - new Linker.Option[]{Linker.Option.critical(false), Linker.Option.captureCallState("errno")}, - "Incompatible linker options: captureCallState, critical" - }, })); for (ValueLayout illegalLayout : List.of(C_CHAR, ValueLayout.JAVA_CHAR, C_BOOL, C_SHORT, C_FLOAT)) { diff --git a/test/jdk/java/foreign/TestStringEncoding.java b/test/jdk/java/foreign/TestStringEncoding.java index 4caef6fbd09..94732943b9d 100644 --- a/test/jdk/java/foreign/TestStringEncoding.java +++ b/test/jdk/java/foreign/TestStringEncoding.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 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 @@ -39,6 +39,7 @@ import java.util.Random; import java.util.function.UnaryOperator; +import jdk.internal.foreign.AbstractMemorySegmentImpl; import jdk.internal.foreign.StringSupport; import org.testng.annotations.*; @@ -53,6 +54,20 @@ public class TestStringEncoding { + @Test + public void emptySegment() { + for (Charset charset : standardCharsets()) { + for (Arena arena : arenas()) { + try (arena) { + var segment = arena.allocate(0); + var e = expectThrows(IndexOutOfBoundsException.class, () -> + segment.getString(0, charset)); + assertTrue(e.getMessage().contains("No null terminator found")); + } + } + } + } + @Test(dataProvider = "strings") public void testStrings(String testString) { for (Charset charset : Charset.availableCharsets().values()) { @@ -87,7 +102,6 @@ public void testStrings(String testString) { } } - @Test(dataProvider = "strings") public void testStringsHeap(String testString) { for (Charset charset : singleByteCharsets()) { @@ -198,8 +212,9 @@ public void testOffset(String testString) { try (arena) { MemorySegment inSegment = arena.allocateFrom(testString, charset); for (int i = 0; i < 3; i++) { + String expected = testString.substring(i); String actual = inSegment.getString(i, charset); - assertEquals(actual, testString.substring(i)); + assertEquals(actual, expected); } } } @@ -249,6 +264,32 @@ public void segmentationFault() { } } + // This test ensures that we do not address outside the segment even though there + // are odd bytes at the end. + @Test(dataProvider = "strings") + public void offBoundaryTrailingBytes(String testString) { + if (testString.length() < 3 || !containsOnlyRegularCharacters(testString)) { + return; + } + for (var charset : standardCharsets()) { + for (var arena: arenas()) { + try (arena) { + MemorySegment strSegment = arena.allocateFrom(testString, charset); + // Add an odd byte at the end + MemorySegment inSegment = arena.allocate(strSegment.byteSize() + 1); + // Make sure there are no null-terminators so that we will try to scan + // the entire segment. + inSegment.fill((byte) 1); + for (int i = 0; i < 4; i++) { + final int offset = i; + var e = expectThrows(IndexOutOfBoundsException.class, () -> inSegment.getString(offset, charset)); + assertTrue(e.getMessage().contains("No null terminator found")); + } + } + } + } + } + private static final int TEST_LENGTH_MAX = 277; private Random deterministicRandom() { @@ -271,9 +312,15 @@ public void chunked_strlen_byte() { } segment.setAtIndex(JAVA_BYTE, len, (byte) 0); for (int j = 0; j < len; j++) { - int actual = StringSupport.chunkedStrlenByte(segment, j); + int actual = StringSupport.strlenByte((AbstractMemorySegmentImpl) segment, j, segment.byteSize()); assertEquals(actual, len - j); } + // Test end offset + for (int j = 0; j < len - 1; j++) { + final long toOffset = j; + expectThrows(IndexOutOfBoundsException.class, () -> + StringSupport.strlenByte((AbstractMemorySegmentImpl) segment, 0, toOffset)); + } } } } @@ -295,7 +342,7 @@ public void chunked_strlen_short() { } segment.setAtIndex(JAVA_SHORT, len, (short) 0); for (int j = 0; j < len; j++) { - int actual = StringSupport.chunkedStrlenShort(segment, j * Short.BYTES); + int actual = StringSupport.strlenShort((AbstractMemorySegmentImpl) segment, j * Short.BYTES, segment.byteSize()); assertEquals(actual, (len - j) * Short.BYTES); } } @@ -319,7 +366,7 @@ public void strlen_int() { } segment.setAtIndex(JAVA_INT, len, 0); for (int j = 0; j < len; j++) { - int actual = StringSupport.strlenInt(segment, j * Integer.BYTES); + int actual = StringSupport.strlenInt((AbstractMemorySegmentImpl) segment, j * Integer.BYTES, segment.byteSize()); assertEquals(actual, (len - j) * Integer.BYTES); } } diff --git a/test/jdk/java/foreign/capturecallstate/TestCaptureCallState.java b/test/jdk/java/foreign/capturecallstate/TestCaptureCallState.java index 51c91ce0f96..7b34ef76add 100644 --- a/test/jdk/java/foreign/capturecallstate/TestCaptureCallState.java +++ b/test/jdk/java/foreign/capturecallstate/TestCaptureCallState.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -61,12 +61,18 @@ public class TestCaptureCallState extends NativeTestHelper { } } - private record SaveValuesCase(String nativeTarget, FunctionDescriptor nativeDesc, String threadLocalName, Consumer resultCheck) {} + private record SaveValuesCase(String nativeTarget, FunctionDescriptor nativeDesc, String threadLocalName, + Consumer resultCheck, boolean critical) {} @Test(dataProvider = "cases") public void testSavedThreadLocal(SaveValuesCase testCase) throws Throwable { - Linker.Option stl = Linker.Option.captureCallState(testCase.threadLocalName()); - MethodHandle handle = downcallHandle(testCase.nativeTarget(), testCase.nativeDesc(), stl); + List options = new ArrayList<>(); + options.add(Linker.Option.captureCallState(testCase.threadLocalName())); + if (testCase.critical()) { + options.add(Linker.Option.critical(false)); + } + MethodHandle handle = downcallHandle(testCase.nativeTarget(), testCase.nativeDesc(), + options.toArray(Linker.Option[]::new)); StructLayout capturedStateLayout = Linker.Option.captureStateLayout(); VarHandle errnoHandle = capturedStateLayout.varHandle(groupElement(testCase.threadLocalName())); @@ -86,9 +92,14 @@ public void testSavedThreadLocal(SaveValuesCase testCase) throws Throwable { @Test(dataProvider = "invalidCaptureSegmentCases") public void testInvalidCaptureSegment(MemorySegment captureSegment, - Class expectedExceptionType, String expectedExceptionMessage) { - Linker.Option stl = Linker.Option.captureCallState("errno"); - MethodHandle handle = downcallHandle("set_errno_V", FunctionDescriptor.ofVoid(C_INT), stl); + Class expectedExceptionType, String expectedExceptionMessage, + Linker.Option[] extraOptions) { + List options = new ArrayList<>(); + options.add(Linker.Option.captureCallState("errno")); + for (Linker.Option extra : extraOptions) { + options.add(extra); + } + MethodHandle handle = downcallHandle("set_errno_V", FunctionDescriptor.ofVoid(C_INT), options.toArray(Linker.Option[]::new)); try { int testValue = 42; @@ -103,32 +114,39 @@ public void testInvalidCaptureSegment(MemorySegment captureSegment, public static Object[][] cases() { List cases = new ArrayList<>(); - cases.add(new SaveValuesCase("set_errno_V", FunctionDescriptor.ofVoid(JAVA_INT), "errno", o -> {})); - cases.add(new SaveValuesCase("set_errno_I", FunctionDescriptor.of(JAVA_INT, JAVA_INT), "errno", o -> assertEquals((int) o, 42))); - cases.add(new SaveValuesCase("set_errno_D", FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT), "errno", o -> assertEquals((double) o, 42.0))); - - cases.add(structCase("SL", Map.of(JAVA_LONG.withName("x"), 42L))); - cases.add(structCase("SLL", Map.of(JAVA_LONG.withName("x"), 42L, - JAVA_LONG.withName("y"), 42L))); - cases.add(structCase("SLLL", Map.of(JAVA_LONG.withName("x"), 42L, - JAVA_LONG.withName("y"), 42L, - JAVA_LONG.withName("z"), 42L))); - cases.add(structCase("SD", Map.of(JAVA_DOUBLE.withName("x"), 42D))); - cases.add(structCase("SDD", Map.of(JAVA_DOUBLE.withName("x"), 42D, - JAVA_DOUBLE.withName("y"), 42D))); - cases.add(structCase("SDDD", Map.of(JAVA_DOUBLE.withName("x"), 42D, - JAVA_DOUBLE.withName("y"), 42D, - JAVA_DOUBLE.withName("z"), 42D))); - - if (IS_WINDOWS) { - cases.add(new SaveValuesCase("SetLastError", FunctionDescriptor.ofVoid(JAVA_INT), "GetLastError", o -> {})); - cases.add(new SaveValuesCase("WSASetLastError", FunctionDescriptor.ofVoid(JAVA_INT), "WSAGetLastError", o -> {})); + for (boolean critical : new boolean[]{ true, false }) { + cases.add(new SaveValuesCase("set_errno_V", FunctionDescriptor.ofVoid(JAVA_INT), + "errno", o -> {}, critical)); + cases.add(new SaveValuesCase("set_errno_I", FunctionDescriptor.of(JAVA_INT, JAVA_INT), + "errno", o -> assertEquals((int) o, 42), critical)); + cases.add(new SaveValuesCase("set_errno_D", FunctionDescriptor.of(JAVA_DOUBLE, JAVA_INT), + "errno", o -> assertEquals((double) o, 42.0), critical)); + + cases.add(structCase("SL", Map.of(JAVA_LONG.withName("x"), 42L), critical)); + cases.add(structCase("SLL", Map.of(JAVA_LONG.withName("x"), 42L, + JAVA_LONG.withName("y"), 42L), critical)); + cases.add(structCase("SLLL", Map.of(JAVA_LONG.withName("x"), 42L, + JAVA_LONG.withName("y"), 42L, + JAVA_LONG.withName("z"), 42L), critical)); + cases.add(structCase("SD", Map.of(JAVA_DOUBLE.withName("x"), 42D), critical)); + cases.add(structCase("SDD", Map.of(JAVA_DOUBLE.withName("x"), 42D, + JAVA_DOUBLE.withName("y"), 42D), critical)); + cases.add(structCase("SDDD", Map.of(JAVA_DOUBLE.withName("x"), 42D, + JAVA_DOUBLE.withName("y"), 42D, + JAVA_DOUBLE.withName("z"), 42D), critical)); + + if (IS_WINDOWS) { + cases.add(new SaveValuesCase("SetLastError", FunctionDescriptor.ofVoid(JAVA_INT), + "GetLastError", o -> {}, critical)); + cases.add(new SaveValuesCase("WSASetLastError", FunctionDescriptor.ofVoid(JAVA_INT), + "WSAGetLastError", o -> {}, critical)); + } } return cases.stream().map(tc -> new Object[] {tc}).toArray(Object[][]::new); } - static SaveValuesCase structCase(String name, Map fields) { + static SaveValuesCase structCase(String name, Map fields, boolean critical) { StructLayout layout = MemoryLayout.structLayout(fields.keySet().toArray(MemoryLayout[]::new)); Consumer check = o -> {}; @@ -139,16 +157,19 @@ static SaveValuesCase structCase(String name, Map fields) check = check.andThen(o -> assertEquals(fieldHandle.get(o, 0L), value)); } - return new SaveValuesCase("set_errno_" + name, FunctionDescriptor.of(layout, JAVA_INT), "errno", check); + return new SaveValuesCase("set_errno_" + name, FunctionDescriptor.of(layout, JAVA_INT), + "errno", check, critical); } @DataProvider public static Object[][] invalidCaptureSegmentCases() { return new Object[][]{ - {Arena.ofAuto().allocate(1), IndexOutOfBoundsException.class, ".*Out of bound access on segment.*"}, - {MemorySegment.NULL, IllegalArgumentException.class, ".*Capture segment is NULL.*"}, + {Arena.ofAuto().allocate(1), IndexOutOfBoundsException.class, ".*Out of bound access on segment.*", new Linker.Option[0]}, + {MemorySegment.NULL, IllegalArgumentException.class, ".*Capture segment is NULL.*", new Linker.Option[0]}, {Arena.ofAuto().allocate(Linker.Option.captureStateLayout().byteSize() + 3).asSlice(3), // misaligned - IllegalArgumentException.class, ".*Target offset incompatible with alignment constraints.*"}, + IllegalArgumentException.class, ".*Target offset incompatible with alignment constraints.*", new Linker.Option[0]}, + {MemorySegment.ofArray(new byte[(int) Linker.Option.captureStateLayout().byteSize()]), // misaligned + IllegalArgumentException.class, ".*Target offset incompatible with alignment constraints.*", new Linker.Option[0]}, }; } } diff --git a/test/jdk/java/foreign/critical/TestCritical.java b/test/jdk/java/foreign/critical/TestCritical.java index ab5d6017aba..60b76623b0e 100644 --- a/test/jdk/java/foreign/critical/TestCritical.java +++ b/test/jdk/java/foreign/critical/TestCritical.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -45,12 +45,16 @@ import java.util.ArrayList; import java.util.List; import java.util.function.IntFunction; +import java.util.stream.Collectors; import java.util.stream.Stream; import static org.testng.Assert.assertEquals; public class TestCritical extends NativeTestHelper { + static final MemoryLayout CAPTURE_STATE_LAYOUT = Linker.Option.captureStateLayout(); + static final VarHandle ERRNO_HANDLE = CAPTURE_STATE_LAYOUT.varHandle(MemoryLayout.PathElement.groupElement("errno")); + static { System.loadLibrary("Critical"); } @@ -87,11 +91,16 @@ public void testWithReturnBuffer() throws Throwable { } public record AllowHeapCase(IntFunction newArraySegment, ValueLayout elementLayout, - String fName, FunctionDescriptor fDesc, boolean readOnly) {} + String fName, FunctionDescriptor fDesc, boolean readOnly, boolean captureErrno) {} @Test(dataProvider = "allowHeapCases") public void testAllowHeap(AllowHeapCase testCase) throws Throwable { - MethodHandle handle = downcallHandle(testCase.fName(), testCase.fDesc(), Linker.Option.critical(true)); + List options = new ArrayList<>(); + options.add(Linker.Option.critical(true)); + if (testCase.captureErrno()) { + options.add(Linker.Option.captureCallState("errno")); + } + MethodHandle handle = downcallHandle(testCase.fName(), testCase.fDesc(), options.toArray(Linker.Option[]::new)); int elementCount = 10; MemorySegment heapSegment = testCase.newArraySegment().apply(elementCount); if (testCase.readOnly()) { @@ -101,29 +110,36 @@ public void testAllowHeap(AllowHeapCase testCase) throws Throwable { try (Arena arena = Arena.ofConfined()) { TestValue[] tvs = genTestArgs(testCase.fDesc(), arena); - Object[] args = Stream.of(tvs).map(TestValue::value).toArray(); + List args = Stream.of(tvs).map(TestValue::value).collect(Collectors.toCollection(ArrayList::new)); + MemorySegment captureSegment = testCase.captureErrno() + ? MemorySegment.ofArray(new int[((int) CAPTURE_STATE_LAYOUT.byteSize() + 3) / 4]) + : null; // inject our custom last three arguments - args[args.length - 1] = (int) sequence.byteSize(); + args.set(args.size() - 1, (int) sequence.byteSize()); TestValue sourceSegment = genTestValue(sequence, arena); - args[args.length - 2] = sourceSegment.value(); - args[args.length - 3] = heapSegment; + args.set(args.size() - 2, sourceSegment.value()); + args.set(args.size() - 3, heapSegment); + if (testCase.captureErrno()) { + args.add(0, captureSegment); + } if (handle.type().parameterType(0) == SegmentAllocator.class) { - Object[] newArgs = new Object[args.length + 1]; - newArgs[0] = arena; - System.arraycopy(args, 0, newArgs, 1, args.length); - args = newArgs; + args.add(0, arena); } Object o = handle.invokeWithArguments(args); - if (o != null) { tvs[0].check(o); } // check that writes went through to array sourceSegment.check(heapSegment); + + if (testCase.captureErrno()) { + int errno = (int) ERRNO_HANDLE.get(captureSegment, 0L); + assertEquals(errno, 42); + } } } @@ -149,14 +165,16 @@ public Object[][] allowHeapCases() { List cases = new ArrayList<>(); - for (HeapSegmentFactory hsf : HeapSegmentFactory.values()) { - cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_void", voidDesc, false)); - cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_int", intDesc, false)); - cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_return_buffer", L2Desc, false)); - cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_imr", L3Desc, false)); - cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_void_stack", stackDesc, false)); - // readOnly - cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_void", voidDesc, true)); + for (boolean doCapture : new boolean[]{ true, false }) { + for (HeapSegmentFactory hsf : HeapSegmentFactory.values()) { + cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_void", voidDesc, false, doCapture)); + cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_int", intDesc, false, doCapture)); + cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_return_buffer", L2Desc, false, doCapture)); + cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_imr", L3Desc, false, doCapture)); + cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_void_stack", stackDesc, false, doCapture)); + // readOnly + cases.add(new AllowHeapCase(hsf.newArray, hsf.elementLayout, "test_allow_heap_void", voidDesc, true, doCapture)); + } } return cases.stream().map(e -> new Object[]{ e }).toArray(Object[][]::new); diff --git a/test/jdk/java/foreign/critical/libCritical.c b/test/jdk/java/foreign/critical/libCritical.c index cc03db3c43c..c901df0a368 100644 --- a/test/jdk/java/foreign/critical/libCritical.c +++ b/test/jdk/java/foreign/critical/libCritical.c @@ -53,12 +53,14 @@ EXPORT void test_allow_heap_void(unsigned char* heapArr, unsigned char* nativeAr for (int i = 0; i < numBytes; i++) { heapArr[i] = nativeArr[i]; } + errno = 42; } EXPORT int test_allow_heap_int(int a0, unsigned char* heapArr, unsigned char* nativeArr, int numBytes) { for (int i = 0; i < numBytes; i++) { heapArr[i] = nativeArr[i]; } + errno = 42; return a0; } @@ -71,6 +73,7 @@ EXPORT struct L2 test_allow_heap_return_buffer(struct L2 a0, unsigned char* heap for (int i = 0; i < numBytes; i++) { heapArr[i] = nativeArr[i]; } + errno = 42; return a0; } @@ -84,6 +87,7 @@ EXPORT struct L3 test_allow_heap_imr(struct L3 a0, unsigned char* heapArr, unsig for (int i = 0; i < numBytes; i++) { heapArr[i] = nativeArr[i]; } + errno = 42; return a0; } @@ -94,4 +98,5 @@ EXPORT void test_allow_heap_void_stack(long long a0, long long a1, long long a2, for (int i = 0; i < numBytes; i++) { heapArr[i] = nativeArr[i]; } + errno = 42; } diff --git a/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessJarManifest.java b/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessJarManifest.java index d75e827fbc6..aa923b5a623 100644 --- a/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessJarManifest.java +++ b/test/jdk/java/foreign/enablenativeaccess/TestEnableNativeAccessJarManifest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -21,7 +21,7 @@ * questions. */ -/** +/* * @test * @summary Basic test for Enable-Native-Access attribute in the * manifest of a main application JAR @@ -78,7 +78,6 @@ public void testEnableNativeAccessInJarManifest(String action, String cls, Resul // java -jar test.jar List command = new ArrayList<>(List.of( - "--enable-preview", "-Djava.library.path=" + System.getProperty("java.library.path") )); command.addAll(vmArgs); diff --git a/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java b/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java index fadcdf1ba24..4ca0eb7bb82 100644 --- a/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java +++ b/test/jdk/java/foreign/passheapsegment/TestPassHeapSegment.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 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 @@ -31,8 +31,7 @@ import org.testng.annotations.Test; import java.io.IOException; -import java.lang.foreign.FunctionDescriptor; -import java.lang.foreign.MemorySegment; +import java.lang.foreign.*; import java.lang.invoke.MethodHandle; import static java.lang.foreign.ValueLayout.ADDRESS; @@ -51,6 +50,19 @@ public void testNoHeapArgs() throws Throwable { handle.invoke(segment); // should throw } + @Test(expectedExceptions = IllegalArgumentException.class, + expectedExceptionsMessageRegExp = ".*Heap segment not allowed.*") + public void testNoHeapCaptureCallState() throws Throwable { + MethodHandle handle = downcallHandle("test_args", FunctionDescriptor.ofVoid(ADDRESS), + Linker.Option.captureCallState("errno")); + try (Arena arena = Arena.ofConfined()) { + assert Linker.Option.captureStateLayout().byteAlignment() % 4 == 0; + MemorySegment captureHeap = MemorySegment.ofArray(new int[(int) Linker.Option.captureStateLayout().byteSize() / 4]); + MemorySegment segment = arena.allocateFrom(C_CHAR, new byte[]{ 0, 1, 2 }); + handle.invoke(captureHeap, segment); // should throw for captureHeap + } + } + @Test(dataProvider = "specs") public void testNoHeapReturns(boolean spec) throws IOException, InterruptedException { runInNewProcess(Runner.class, spec) diff --git a/test/jdk/java/io/FileInputStream/Available.java b/test/jdk/java/io/FileInputStream/Available.java index 8759d8d1d27..e5b5b8825d3 100644 --- a/test/jdk/java/io/FileInputStream/Available.java +++ b/test/jdk/java/io/FileInputStream/Available.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 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 @@ -23,25 +23,38 @@ /* * @test - * @bug 4129479 - * @summary Test if available would throw an IOException - * when the stream is closed. + * @bug 4129479 8342086 + * @summary Test that available throws an IOException if the stream is + * closed, and that available works correctly with the NUL + * device on Windows + * @run junit Available */ -import java.io.*; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.condition.EnabledOnOs; +import org.junit.jupiter.api.condition.OS; +import static org.junit.jupiter.api.Assertions.*; public class Available { - public static void main(String args[]) throws Exception { + @Test + void throwAfterClose() throws IOException { File file = new File(System.getProperty("test.src", "."), "Available.java"); FileInputStream fis = new FileInputStream(file); fis.close(); - try { - fis.available(); - throw new Exception - ("available should throw an exception after stream is closed"); - } - catch (IOException e) { - } + assertThrows(IOException.class, () -> fis.available()); + } + + @Test + @EnabledOnOs(OS.WINDOWS) + void nulDevice() throws IOException { + File file = new File("nul"); + FileInputStream fis = new FileInputStream(file); + int n = fis.available(); + assertEquals(0, n, "available() returned non-zero value"); } } diff --git a/test/jdk/java/net/IDNTest.java b/test/jdk/java/net/IDNTest.java new file mode 100644 index 00000000000..aa58e472bf3 --- /dev/null +++ b/test/jdk/java/net/IDNTest.java @@ -0,0 +1,48 @@ +/* + * 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.net.IDN; + +import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.*; + +/* + * @test + * @bug 7038838 + * @summary verify the behaviour of the methods on java.net.IDN class + * @run junit IDNTest + */ +public class IDNTest { + + /* + * Verify that various methods on the IDN class throw a NullPointerException + * for any null parameter. + */ + @Test + public void testNullPointerException() throws Exception { + assertThrows(NullPointerException.class, () -> IDN.toASCII(null)); + assertThrows(NullPointerException.class, () -> IDN.toASCII(null, 0)); + assertThrows(NullPointerException.class, () -> IDN.toUnicode(null)); + assertThrows(NullPointerException.class, () -> IDN.toUnicode(null, 0)); + } +} \ No newline at end of file diff --git a/test/jdk/java/net/Socket/ConnectFailTest.java b/test/jdk/java/net/Socket/ConnectFailTest.java new file mode 100644 index 00000000000..7cc46ce4a4d --- /dev/null +++ b/test/jdk/java/net/Socket/ConnectFailTest.java @@ -0,0 +1,171 @@ +/* + * 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 jdk.test.lib.Utils; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.nio.channels.SocketChannel; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/* + * @test + * @bug 8343791 + * @summary verifies that `connect()` failures throw the expected exception and leave socket in the expected state + * @library /test/lib + * @run junit ConnectFailTest + */ +class ConnectFailTest { + + private static final int DEAD_SERVER_PORT = 0xDEAD; + + private static final InetSocketAddress REFUSING_SOCKET_ADDRESS = Utils.refusingEndpoint(); + + private static final InetSocketAddress UNRESOLVED_ADDRESS = + InetSocketAddress.createUnresolved("no.such.host", DEAD_SERVER_PORT); + + @Test + void testUnresolvedAddress() { + assertTrue(UNRESOLVED_ADDRESS.isUnresolved()); + } + + /** + * Verifies that an unbound socket is closed when {@code connect()} fails. + */ + @ParameterizedTest + @MethodSource("sockets") + void testUnboundSocket(Socket socket) throws IOException { + try (socket) { + assertFalse(socket.isBound()); + assertFalse(socket.isConnected()); + assertThrows(IOException.class, () -> socket.connect(REFUSING_SOCKET_ADDRESS)); + assertTrue(socket.isClosed()); + } + } + + /** + * Verifies that a bound socket is closed when {@code connect()} fails. + */ + @ParameterizedTest + @MethodSource("sockets") + void testBoundSocket(Socket socket) throws IOException { + try (socket) { + socket.bind(new InetSocketAddress(0)); + assertTrue(socket.isBound()); + assertFalse(socket.isConnected()); + assertThrows(IOException.class, () -> socket.connect(REFUSING_SOCKET_ADDRESS)); + assertTrue(socket.isClosed()); + } + } + + /** + * Verifies that a connected socket is not closed when {@code connect()} fails. + */ + @ParameterizedTest + @MethodSource("sockets") + void testConnectedSocket(Socket socket) throws Throwable { + try (socket; ServerSocket serverSocket = createEphemeralServerSocket()) { + socket.connect(serverSocket.getLocalSocketAddress()); + try (Socket _ = serverSocket.accept()) { + assertTrue(socket.isBound()); + assertTrue(socket.isConnected()); + SocketException exception = assertThrows( + SocketException.class, + () -> socket.connect(REFUSING_SOCKET_ADDRESS)); + assertEquals("Already connected", exception.getMessage()); + assertFalse(socket.isClosed()); + } + } + } + + /** + * Verifies that an unbound socket is closed when {@code connect()} is invoked using an unresolved address. + */ + @ParameterizedTest + @MethodSource("sockets") + void testUnboundSocketWithUnresolvedAddress(Socket socket) throws IOException { + try (socket) { + assertFalse(socket.isBound()); + assertFalse(socket.isConnected()); + assertThrows(UnknownHostException.class, () -> socket.connect(UNRESOLVED_ADDRESS)); + assertTrue(socket.isClosed()); + } + } + + /** + * Verifies that a bound socket is closed when {@code connect()} is invoked using an unresolved address. + */ + @ParameterizedTest + @MethodSource("sockets") + void testBoundSocketWithUnresolvedAddress(Socket socket) throws IOException { + try (socket) { + socket.bind(new InetSocketAddress(0)); + assertTrue(socket.isBound()); + assertFalse(socket.isConnected()); + assertThrows(UnknownHostException.class, () -> socket.connect(UNRESOLVED_ADDRESS)); + assertTrue(socket.isClosed()); + } + } + + /** + * Verifies that a connected socket is not closed when {@code connect()} is invoked using an unresolved address. + */ + @ParameterizedTest + @MethodSource("sockets") + void testConnectedSocketWithUnresolvedAddress(Socket socket) throws Throwable { + try (socket; ServerSocket serverSocket = createEphemeralServerSocket()) { + socket.connect(serverSocket.getLocalSocketAddress()); + try (Socket _ = serverSocket.accept()) { + assertTrue(socket.isBound()); + assertTrue(socket.isConnected()); + assertThrows(IOException.class, () -> socket.connect(UNRESOLVED_ADDRESS)); + assertFalse(socket.isClosed()); + } + } + } + + static List sockets() throws Exception { + Socket socket = new Socket(); + @SuppressWarnings("resource") + Socket channelSocket = SocketChannel.open().socket(); + return List.of(socket, channelSocket); + } + + private static ServerSocket createEphemeralServerSocket() throws IOException { + return new ServerSocket(0, 0, InetAddress.getLoopbackAddress()); + } + +} diff --git a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java index cb3d4dde914..d143e025dd5 100644 --- a/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java +++ b/test/jdk/java/util/Locale/LanguageSubtagRegistryTest.java @@ -25,9 +25,9 @@ * @test * @bug 8025703 8040211 8191404 8203872 8222980 8225435 8241082 8242010 8247432 * 8258795 8267038 8287180 8302512 8304761 8306031 8308021 8313702 8318322 - * 8327631 8332424 8334418 + * 8327631 8332424 8334418 8344589 * @summary Checks the IANA language subtag registry data update - * (LSR Revision: 2024-06-14) with Locale and Locale.LanguageRange + * (LSR Revision: 2024-11-19) with Locale and Locale.LanguageRange * class methods. * @run main LanguageSubtagRegistryTest */ diff --git a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java index 6e12b0eae2c..d92a7bc4aa3 100644 --- a/test/jdk/java/util/concurrent/tck/JSR166TestCase.java +++ b/test/jdk/java/util/concurrent/tck/JSR166TestCase.java @@ -39,7 +39,10 @@ * @summary Conformance testing variant of JSR-166 tck tests. * @build * * @modules java.management java.base/jdk.internal.util - * @run junit/othervm/timeout=1000 -Xdump:system+java+snap:events=systhrow,filter=java/lang/Exception,msg_filter=*JUnit* JSR166TestCase + * @run junit/othervm/timeout=1000 + * -Xdump:system+java+snap:events=throw+systhrow,filter=java/lang/Exception,msg_filter=*JUnit* + * -Xdump:system+java+snap:events=throw+systhrow,filter=junit/framework/AssertionFailedError + * JSR166TestCase */ /* @@ -53,7 +56,8 @@ * --add-opens java.base/java.lang=ALL-UNNAMED * -Djsr166.testImplementationDetails=true * -Djava.util.concurrent.ForkJoinPool.common.parallelism=0 - * -Xdump:system+java+snap:events=systhrow,filter=java/lang/Exception,msg_filter=*JUnit* + * -Xdump:system+java+snap:events=throw+systhrow,filter=java/lang/Exception,msg_filter=*JUnit* + * -Xdump:system+java+snap:events=throw+systhrow,filter=junit/framework/AssertionFailedError * JSR166TestCase * @run junit/othervm/timeout=1000 * --add-opens java.base/java.util.concurrent=ALL-UNNAMED @@ -61,7 +65,8 @@ * -Djsr166.testImplementationDetails=true * -Djava.util.concurrent.ForkJoinPool.common.parallelism=1 * -Djava.util.secureRandomSeed=true - * -Xdump:system+java+snap:events=systhrow,filter=java/lang/Exception,msg_filter=*JUnit* + * -Xdump:system+java+snap:events=throw+systhrow,filter=java/lang/Exception,msg_filter=*JUnit* + * -Xdump:system+java+snap:events=throw+systhrow,filter=junit/framework/AssertionFailedError * JSR166TestCase */ @@ -76,7 +81,8 @@ * --add-opens java.base/java.util.concurrent=ALL-UNNAMED * --add-opens java.base/java.lang=ALL-UNNAMED * -Djsr166.testImplementationDetails=true - * -Xdump:system+java+snap:events=systhrow,filter=java/lang/Exception,msg_filter=*JUnit* + * -Xdump:system+java+snap:events=throw+systhrow,filter=java/lang/Exception,msg_filter=*JUnit* + * -Xdump:system+java+snap:events=throw+systhrow,filter=junit/framework/AssertionFailedError * JSR166TestCase */ diff --git a/test/jdk/javax/swing/Action/8133039/bug8133039.java b/test/jdk/javax/swing/Action/8133039/bug8133039.java index f36b1b1ab10..48de406aaaf 100644 --- a/test/jdk/javax/swing/Action/8133039/bug8133039.java +++ b/test/jdk/javax/swing/Action/8133039/bug8133039.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 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 @@ -39,8 +39,8 @@ * @bug 8133039 * @summary Provide public API to sun.swing.UIAction#isEnabled(Object) * @modules java.desktop/sun.swing - * @author Alexander Scherbatiy */ + public class bug8133039 { private static volatile int ACTION_PERFORMED_CALLS = 0; @@ -91,6 +91,7 @@ private static void testPopupAction() throws Exception { Robot robot = new Robot(); robot.setAutoDelay(100); robot.waitForIdle(); + robot.delay(1000); robot.keyPress(KeyEvent.VK_A); robot.keyRelease(KeyEvent.VK_A); diff --git a/test/jdk/javax/swing/JButton/PressedButtonRightClickTest.java b/test/jdk/javax/swing/JButton/PressedButtonRightClickTest.java deleted file mode 100644 index 8f3da452c21..00000000000 --- a/test/jdk/javax/swing/JButton/PressedButtonRightClickTest.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 - * 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.AWTException; -import java.awt.BorderLayout; -import java.awt.EventQueue; -import java.awt.Point; -import java.awt.Robot; -import java.awt.event.InputEvent; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.SwingUtilities; - -/* - * @test - * @key headful - * @bug 8049069 - * @summary Tests whether right mouse click releases a pressed JButton - */ - -public class PressedButtonRightClickTest { - - private static Robot testRobot; - private static JFrame myFrame; - private static JButton myButton; - - public static void main(String[] args) throws Throwable { - - SwingUtilities.invokeAndWait(PressedButtonRightClickTest::constructTestUI); - - try { - testRobot = new Robot(); - } catch (AWTException ex) { - throw new RuntimeException("Exception in Robot creation"); - } - - testRobot.waitForIdle(); - testRobot.delay(500); - - // Method performing auto test operation - try { - test(); - } finally { - EventQueue.invokeAndWait(PressedButtonRightClickTest::disposeTestUI); - } - } - - private static void test() { - Point loc = myFrame.getLocationOnScreen(); - - testRobot.mouseMove((loc.x + 100), (loc.y + 100)); - - // Press the left mouse button - System.out.println("press BUTTON1_DOWN_MASK"); - testRobot.mousePress(InputEvent.BUTTON1_DOWN_MASK); - myButton.setText("Left button pressed"); - testRobot.delay(500); - - // Press the right mouse button - System.out.println("press BUTTON3_DOWN_MASK"); - testRobot.mousePress(InputEvent.BUTTON3_DOWN_MASK); - myButton.setText("Left button pressed + Right button pressed"); - testRobot.delay(500); - - // Release the right mouse button - System.out.println("release BUTTON3_DOWN_MASK"); - testRobot.mouseRelease(InputEvent.BUTTON3_DOWN_MASK); - myButton.setText("Right button released"); - testRobot.waitForIdle(); - testRobot.delay(500); - - // Test whether the button is still pressed - boolean pressed = myButton.getModel().isPressed(); - System.out.println("release BUTTON1_DOWN_MASK"); - testRobot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); - if (!pressed) { - disposeTestUI(); - throw new RuntimeException("Test Failed!"); - } - } - - private static void disposeTestUI() { - myFrame.setVisible(false); - myFrame.dispose(); - } - - public static void constructTestUI() { - myFrame = new JFrame(); - myFrame.setLayout(new BorderLayout()); - myButton = new JButton("Whatever"); - myButton.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - System.out.println(e); - } - - @Override - public void mousePressed(MouseEvent e) { - System.out.println(e); - } - - @Override - public void mouseReleased(MouseEvent e) { - System.out.println(e); - } - - @Override - public void mouseEntered(MouseEvent e) { - System.out.println(e); - } - - @Override - public void mouseExited(MouseEvent e) { - System.out.println(e); - } - }); - myFrame.add(myButton, BorderLayout.CENTER); - myFrame.setSize(400, 300); - myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - myFrame.setLocationRelativeTo(null); - myFrame.setVisible(true); - } -} - diff --git a/test/jdk/javax/swing/JButton/bug4490179.java b/test/jdk/javax/swing/JButton/bug4490179.java index e36e01e2d95..bf2df9e7bcc 100644 --- a/test/jdk/javax/swing/JButton/bug4490179.java +++ b/test/jdk/javax/swing/JButton/bug4490179.java @@ -23,7 +23,7 @@ /* * @test - * @bug 4490179 + * @bug 4490179 8049069 * @summary Tests that JButton only responds to left mouse clicks. * @key headful * @run main bug4490179 diff --git a/test/jdk/tools/jlink/ImageFileCreatorTest.java b/test/jdk/tools/jlink/ImageFileCreatorTest.java index b6466c6a4d9..52a878e566a 100644 --- a/test/jdk/tools/jlink/ImageFileCreatorTest.java +++ b/test/jdk/tools/jlink/ImageFileCreatorTest.java @@ -224,6 +224,6 @@ public void storeFiles(ResourcePool content) { ImagePluginStack stack = new ImagePluginStack(noopBuilder, Collections.emptyList(), null, false); - ImageFileCreator.create(archives, ByteOrder.nativeOrder(), stack, false, null); + ImageFileCreator.create(archives, ByteOrder.nativeOrder(), stack, false); } } diff --git a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java index 90abe14c214..777ce302ce7 100644 --- a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java +++ b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java @@ -78,7 +78,7 @@ public boolean test(OutputAnalyzer t) { } analyzer.stdoutShouldContain(modifiedFile.toString() + " has been modified"); // Verify the error message is reasonable - analyzer.stdoutShouldNotContain("jdk.tools.jlink.internal.RunImageLinkException"); + analyzer.stdoutShouldNotContain("IOException"); analyzer.stdoutShouldNotContain("java.lang.IllegalArgumentException"); } diff --git a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java index 935d80dee4f..c871024f37c 100644 --- a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java +++ b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java @@ -70,6 +70,6 @@ void testAndAssert(Path modifiedFile, Helper helper, Path initialImage) throws E // verify we get the warning message out.stdoutShouldMatch("Warning: .* has been modified"); out.stdoutShouldNotContain("java.lang.IllegalArgumentException"); - out.stdoutShouldNotContain("jdk.tools.jlink.internal.RunImageLinkException"); + out.stdoutShouldNotContain("IOException"); } } diff --git a/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java index f83c4c698f1..d4654ec98bd 100644 --- a/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java @@ -97,10 +97,10 @@ public boolean test(OutputAnalyzer t) { if (analyzer.getExitValue() == 0) { throw new AssertionError("Expected jlink to fail due to patched module!"); } - analyzer.stdoutShouldContain("MyJlinkPatchInteger.class not found in the modules image."); - analyzer.stdoutShouldContain("--patch-module is not supported"); + analyzer.stdoutShouldContain("jlink does not support linking from the run-time image"); + analyzer.stdoutShouldContain(" when running on a patched runtime with --patch-module"); // Verify the error message is reasonable - analyzer.stdoutShouldNotContain("jdk.tools.jlink.internal.RunImageLinkException"); + analyzer.stdoutShouldNotContain("IOException"); analyzer.stdoutShouldNotContain("java.lang.IllegalArgumentException"); } diff --git a/test/jdk/sun/security/action/Generify.java b/test/jdk/tools/sincechecker/modules/java.scripting/JavaScriptingCheckSince.java similarity index 57% rename from test/jdk/sun/security/action/Generify.java rename to test/jdk/tools/sincechecker/modules/java.scripting/JavaScriptingCheckSince.java index 4ddbc299a47..06458b07907 100644 --- a/test/jdk/sun/security/action/Generify.java +++ b/test/jdk/tools/sincechecker/modules/java.scripting/JavaScriptingCheckSince.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. + * 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 @@ -23,26 +23,8 @@ /* * @test - * @bug 5057136 - * @summary Generify sun.security.action.GetPropertyAction and friends - * @modules java.base/sun.security.action + * @bug 8343780 + * @summary Test for `@since` in java.scripting module + * @library /test/lib /test/jdk/tools/sincechecker + * @run main SinceChecker java.scripting */ - -import java.security.*; -import sun.security.action.*; - -public class Generify { - - public static void main(String[] args) throws Exception { - - System.setProperty("property", "propertyvalue"); - - String prop = AccessController.doPrivileged - (new GetPropertyAction("property")); - if (prop.equals("propertyvalue")) { - System.out.println("property test passed"); - } else { - throw new SecurityException("property test failed"); - } - } -} diff --git a/test/jdk/tools/sincechecker/modules/jdk.dynalink/JdkDynalinkCheckSince.java b/test/jdk/tools/sincechecker/modules/jdk.dynalink/JdkDynalinkCheckSince.java new file mode 100644 index 00000000000..5d38713eb0a --- /dev/null +++ b/test/jdk/tools/sincechecker/modules/jdk.dynalink/JdkDynalinkCheckSince.java @@ -0,0 +1,30 @@ +/* + * 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 8343780 + * @summary Test for `@since` in jdk.dynalik module + * @library /test/lib /test/jdk/tools/sincechecker + * @run main SinceChecker jdk.dynalink + */ diff --git a/test/jdk/tools/sincechecker/modules/jdk.jartool/JdkJartoolCheckSince.java b/test/jdk/tools/sincechecker/modules/jdk.jartool/JdkJartoolCheckSince.java new file mode 100644 index 00000000000..628aa8d2f34 --- /dev/null +++ b/test/jdk/tools/sincechecker/modules/jdk.jartool/JdkJartoolCheckSince.java @@ -0,0 +1,30 @@ +/* + * 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 8343780 + * @summary Test for `@since` in jdk.jartool module + * @library /test/lib /test/jdk/tools/sincechecker + * @run main SinceChecker jdk.jartool + */ diff --git a/test/jdk/tools/sincechecker/modules/jdk.jlink/JdkJlinkCheckSince.java b/test/jdk/tools/sincechecker/modules/jdk.jlink/JdkJlinkCheckSince.java new file mode 100644 index 00000000000..effeb778a3a --- /dev/null +++ b/test/jdk/tools/sincechecker/modules/jdk.jlink/JdkJlinkCheckSince.java @@ -0,0 +1,30 @@ +/* + * 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 8343780 + * @summary Test for `@since` in jdk.jlink module + * @library /test/lib /test/jdk/tools/sincechecker + * @run main SinceChecker jdk.jlink + */ diff --git a/test/jdk/tools/sincechecker/modules/jdk.jsobject/JdkJsobjectCheckSince.java b/test/jdk/tools/sincechecker/modules/jdk.jsobject/JdkJsobjectCheckSince.java new file mode 100644 index 00000000000..705c7259b71 --- /dev/null +++ b/test/jdk/tools/sincechecker/modules/jdk.jsobject/JdkJsobjectCheckSince.java @@ -0,0 +1,30 @@ +/* + * 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 8343780 + * @summary Test for `@since` in jdk.jsobject module + * @library /test/lib /test/jdk/tools/sincechecker + * @run main SinceChecker jdk.jsobject + */ diff --git a/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/ExpectedValues.java b/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/ExpectedValues.java index 752ebc844eb..f5e23f65e88 100644 --- a/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/ExpectedValues.java +++ b/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/ExpectedValues.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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,7 +26,7 @@ @Retention(RetentionPolicy.RUNTIME) public @interface ExpectedValues { - char tag(); + int tag(); String name(); String[] values(); } diff --git a/test/langtools/tools/javac/patterns/T8343932.java b/test/langtools/tools/javac/patterns/T8343932.java new file mode 100644 index 00000000000..346d0d6f79c --- /dev/null +++ b/test/langtools/tools/javac/patterns/T8343932.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 8343932 + * @summary Error when parsing qualified generic type test pattern in switch + * @compile T8343932.java + */ +public class T8343932 { + abstract sealed class J permits X.S, A {} + final class A extends J {} + + public class X { + final class S extends J { + abstract sealed class J permits XX.SS, AA {} + final class AA extends J {} + + public class XX { + final class SS extends J {} + } + } + + static int test(J ji) { + return switch (ji) { + case A a -> 42; + case X.S e -> 4200; // level 1 + }; + } + + static int test(X.S.J ji) { + return switch (ji) { + case X.S.AA a -> 42; + case X.S.XX.SS e -> 4200; // level 2 + }; + } + } +} \ No newline at end of file diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/InternalStrLen.java b/test/micro/org/openjdk/bench/java/lang/foreign/InternalStrLen.java index 2db15bfe265..b7867efd771 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/InternalStrLen.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/InternalStrLen.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ */ package org.openjdk.bench.java.lang.foreign; +import jdk.internal.foreign.AbstractMemorySegmentImpl; +import jdk.internal.foreign.StringSupport; import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.BenchmarkMode; import org.openjdk.jmh.annotations.Fork; @@ -43,20 +45,20 @@ import java.util.stream.Stream; import static java.lang.foreign.ValueLayout.*; -import static jdk.internal.foreign.StringSupport.*; @BenchmarkMode(Mode.AverageTime) @Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS) @Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) @State(Scope.Benchmark) @OutputTimeUnit(TimeUnit.NANOSECONDS) -@Fork(value = 3, jvmArgs = {"--add-exports=java.base/jdk.internal.foreign=ALL-UNNAMED", "--enable-native-access=ALL-UNNAMED", "--enable-preview"}) +@Fork(value = 3, jvmArgs = {"--add-exports=java.base/jdk.internal.foreign=ALL-UNNAMED", + "--enable-native-access=ALL-UNNAMED"}) public class InternalStrLen { - private MemorySegment singleByteSegment; - private MemorySegment singleByteSegmentMisaligned; - private MemorySegment doubleByteSegment; - private MemorySegment quadByteSegment; + private AbstractMemorySegmentImpl singleByteSegment; + private AbstractMemorySegmentImpl singleByteSegmentMisaligned; + private AbstractMemorySegmentImpl doubleByteSegment; + private AbstractMemorySegmentImpl quadByteSegment; @Param({"1", "4", "16", "251", "1024"}) int size; @@ -64,10 +66,9 @@ public class InternalStrLen { @Setup public void setup() { var arena = Arena.ofAuto(); - singleByteSegment = arena.allocate((size + 1L) * Byte.BYTES); - singleByteSegmentMisaligned = arena.allocate((size + 1L) * Byte.BYTES); - doubleByteSegment = arena.allocate((size + 1L) * Short.BYTES); - quadByteSegment = arena.allocate((size + 1L) * Integer.BYTES); + singleByteSegment = (AbstractMemorySegmentImpl) arena.allocate((size + 1L) * Byte.BYTES); + doubleByteSegment = (AbstractMemorySegmentImpl) arena.allocate((size + 1L) * Short.BYTES); + quadByteSegment = (AbstractMemorySegmentImpl) arena.allocate((size + 1L) * Integer.BYTES); Stream.of(singleByteSegment, doubleByteSegment, quadByteSegment) .forEach(s -> IntStream.range(0, (int) s.byteSize() - 1) .forEach(i -> s.set( @@ -78,7 +79,7 @@ public void setup() { singleByteSegment.set(ValueLayout.JAVA_BYTE, singleByteSegment.byteSize() - Byte.BYTES, (byte) 0); doubleByteSegment.set(ValueLayout.JAVA_SHORT, doubleByteSegment.byteSize() - Short.BYTES, (short) 0); quadByteSegment.set(ValueLayout.JAVA_INT, quadByteSegment.byteSize() - Integer.BYTES, 0); - singleByteSegmentMisaligned = arena.allocate(singleByteSegment.byteSize() + 1). + singleByteSegmentMisaligned = (AbstractMemorySegmentImpl) arena.allocate(singleByteSegment.byteSize() + 1). asSlice(1); MemorySegment.copy(singleByteSegment, 0, singleByteSegmentMisaligned, 0, singleByteSegment.byteSize()); } @@ -105,22 +106,22 @@ public int elementQuad() { @Benchmark public int chunkedSingle() { - return chunkedStrlenByte(singleByteSegment, 0); + return StringSupport.strlenByte(singleByteSegment, 0, singleByteSegment.byteSize()); } @Benchmark public int chunkedSingleMisaligned() { - return chunkedStrlenByte(singleByteSegmentMisaligned, 0); + return StringSupport.strlenByte(singleByteSegmentMisaligned, 0, singleByteSegment.byteSize()); } @Benchmark public int chunkedDouble() { - return chunkedStrlenShort(doubleByteSegment, 0); + return StringSupport.strlenShort(doubleByteSegment, 0, doubleByteSegment.byteSize()); } @Benchmark public int changedElementQuad() { - return strlenInt(quadByteSegment, 0); + return StringSupport.strlenInt(quadByteSegment, 0, quadByteSegment.byteSize()); } // These are the legacy methods diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/ToJavaStringTest.java b/test/micro/org/openjdk/bench/java/lang/foreign/ToJavaStringTest.java index 02b1a47d03f..f38a1481158 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/ToJavaStringTest.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/ToJavaStringTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 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 @@ -43,7 +43,7 @@ @Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) @State(Scope.Benchmark) @OutputTimeUnit(TimeUnit.NANOSECONDS) -@Fork(value = 3, jvmArgs = { "--enable-native-access=ALL-UNNAMED", "--enable-preview", "-Djava.library.path=micro/native" }) +@Fork(value = 3, jvmArgs = { "--enable-native-access=ALL-UNNAMED", "-Djava.library.path=micro/native" }) public class ToJavaStringTest { private MemorySegment strSegment;