diff --git a/make/devkit/createAutoconfBundle.sh b/make/devkit/createAutoconfBundle.sh index 861a0a47242c0..7363b9cd8a71a 100644 --- a/make/devkit/createAutoconfBundle.sh +++ b/make/devkit/createAutoconfBundle.sh @@ -1,6 +1,6 @@ #!/bin/bash -e # -# Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -25,50 +25,70 @@ # # Create a bundle in the current directory, containing what's needed to run -# the 'autoconf' program by the OpenJDK build. +# the 'autoconf' program by the OpenJDK build. To override TARGET_PLATFORM +# just set the variable before running this script. # Autoconf depends on m4, so download and build that first. AUTOCONF_VERSION=2.69 M4_VERSION=1.4.18 PACKAGE_VERSION=1.0.1 -TARGET_PLATFORM=linux_x86 +case `uname -s` in + Darwin) + os=macosx + ;; + Linux) + os=linux + ;; + CYGWIN*) + os=cygwin + ;; +esac +case `uname -m` in + arm64|aarch64) + arch=aarch64 + ;; + amd64|x86_64|x64) + arch=x64 + ;; +esac +TARGET_PLATFORM=${TARGET_PLATFORM:="${os}_${arch}"} + MODULE_NAME=autoconf-$TARGET_PLATFORM-$AUTOCONF_VERSION+$PACKAGE_VERSION BUNDLE_NAME=$MODULE_NAME.tar.gz -TMPDIR=`mktemp -d -t autoconfbundle-XXXX` -trap "rm -rf \"$TMPDIR\"" EXIT +SCRIPT_DIR="$(cd "$(dirname $0)" > /dev/null && pwd)" +OUTPUT_ROOT="${SCRIPT_DIR}/../../build/autoconf" -ORIG_DIR=`pwd` -cd $TMPDIR -OUTPUT_DIR=$TMPDIR/$MODULE_NAME -mkdir -p $OUTPUT_DIR/usr +cd $OUTPUT_ROOT +IMAGE_DIR=$OUTPUT_ROOT/$MODULE_NAME +mkdir -p $IMAGE_DIR/usr # Download and build m4 if test "x$TARGET_PLATFORM" = xcygwin_x64; then # On cygwin 64-bit, just copy the cygwin .exe file - mkdir -p $OUTPUT_DIR/usr/bin - cp /usr/bin/m4 $OUTPUT_DIR/usr/bin + mkdir -p $IMAGE_DIR/usr/bin + cp /usr/bin/m4 $IMAGE_DIR/usr/bin elif test "x$TARGET_PLATFORM" = xcygwin_x86; then # On cygwin 32-bit, just copy the cygwin .exe file - mkdir -p $OUTPUT_DIR/usr/bin - cp /usr/bin/m4 $OUTPUT_DIR/usr/bin + mkdir -p $IMAGE_DIR/usr/bin + cp /usr/bin/m4 $IMAGE_DIR/usr/bin elif test "x$TARGET_PLATFORM" = xlinux_x64; then M4_VERSION=1.4.13-5 wget http://yum.oracle.com/repo/OracleLinux/OL6/latest/x86_64/getPackage/m4-$M4_VERSION.el6.x86_64.rpm - cd $OUTPUT_DIR - rpm2cpio ../m4-$M4_VERSION.el6.x86_64.rpm | cpio -d -i + cd $IMAGE_DIR + rpm2cpio $OUTPUT_ROOT/m4-$M4_VERSION.el6.x86_64.rpm | cpio -d -i elif test "x$TARGET_PLATFORM" = xlinux_x86; then M4_VERSION=1.4.13-5 wget http://yum.oracle.com/repo/OracleLinux/OL6/latest/i386/getPackage/m4-$M4_VERSION.el6.i686.rpm - cd $OUTPUT_DIR - rpm2cpio ../m4-$M4_VERSION.el6.i686.rpm | cpio -d -i + cd $IMAGE_DIR + rpm2cpio $OUTPUT_ROOT/m4-$M4_VERSION.el6.i686.rpm | cpio -d -i else wget https://ftp.gnu.org/gnu/m4/m4-$M4_VERSION.tar.gz tar xzf m4-$M4_VERSION.tar.gz cd m4-$M4_VERSION - ./configure --prefix=$OUTPUT_DIR/usr + ./configure --prefix=$IMAGE_DIR/usr CFLAGS="-w -Wno-everything" make make install cd .. @@ -79,15 +99,14 @@ fi wget https://ftp.gnu.org/gnu/autoconf/autoconf-$AUTOCONF_VERSION.tar.gz tar xzf autoconf-$AUTOCONF_VERSION.tar.gz cd autoconf-$AUTOCONF_VERSION -./configure --prefix=$OUTPUT_DIR/usr M4=$OUTPUT_DIR/usr/bin/m4 +./configure --prefix=$IMAGE_DIR/usr M4=$IMAGE_DIR/usr/bin/m4 make make install cd .. -perl -pi -e "s!$OUTPUT_DIR/!./!" $OUTPUT_DIR/usr/bin/auto* $OUTPUT_DIR/usr/share/autoconf/autom4te.cfg -cp $OUTPUT_DIR/usr/share/autoconf/autom4te.cfg $OUTPUT_DIR/autom4te.cfg +perl -pi -e "s!$IMAGE_DIR/!./!" $IMAGE_DIR/usr/bin/auto* $IMAGE_DIR/usr/share/autoconf/autom4te.cfg -cat > $OUTPUT_DIR/autoconf << EOF +cat > $IMAGE_DIR/autoconf << EOF #!/bin/bash # Get an absolute path to this script this_script_dir=\`dirname \$0\` @@ -100,17 +119,10 @@ export AUTOHEADER="\$this_script_dir/usr/bin/autoheader" export AC_MACRODIR="\$this_script_dir/usr/share/autoconf" export autom4te_perllibdir="\$this_script_dir/usr/share/autoconf" -autom4te_cfg=\$this_script_dir/usr/share/autoconf/autom4te.cfg -cp \$this_script_dir/autom4te.cfg \$autom4te_cfg - -echo 'begin-language: "M4sugar"' >> \$autom4te_cfg -echo "args: --prepend-include '"\$this_script_dir/usr/share/autoconf"'" >> \$autom4te_cfg -echo 'end-language: "M4sugar"' >> \$autom4te_cfg +PREPEND_INCLUDE="--prepend-include \$this_script_dir/usr/share/autoconf" -exec \$this_script_dir/usr/bin/autoconf "\$@" +exec \$this_script_dir/usr/bin/autoconf \$PREPEND_INCLUDE "\$@" EOF -chmod +x $OUTPUT_DIR/autoconf -cd $OUTPUT_DIR -tar -cvzf ../$BUNDLE_NAME * -cd .. -cp $BUNDLE_NAME "$ORIG_DIR" +chmod +x $IMAGE_DIR/autoconf +cd $IMAGE_DIR +tar -cvzf $OUTPUT_ROOT/$BUNDLE_NAME * diff --git a/make/test/JtregNativeHotspot.gmk b/make/test/JtregNativeHotspot.gmk index 8916eee90d7bc..97f2f12cb7639 100644 --- a/make/test/JtregNativeHotspot.gmk +++ b/make/test/JtregNativeHotspot.gmk @@ -885,7 +885,7 @@ BUILD_HOTSPOT_JTREG_EXECUTABLES_JDK_LIBS_exedaemonDestroy := java.base:libjvm ifeq ($(call isTargetOs, windows), true) BUILD_HOTSPOT_JTREG_EXECUTABLES_CFLAGS_exeFPRegs := -MT - BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c libMonitorWithDeadObjectTest.c libTestPsig.c exeGetCreatedJavaVMs.c + BUILD_HOTSPOT_JTREG_EXCLUDE += exesigtest.c libterminatedThread.c libTestJNI.c libCompleteExit.c libMonitorWithDeadObjectTest.c libTestPsig.c exeGetCreatedJavaVMs.c libTestUnloadedClass.cpp BUILD_HOTSPOT_JTREG_LIBRARIES_JDK_LIBS_libnativeStack := java.base:libjvm BUILD_HOTSPOT_JTREG_LIBRARIES_JDK_LIBS_libVThreadEventTest := java.base:libjvm else @@ -1526,6 +1526,7 @@ else BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libCompleteExit += -lpthread BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libMonitorWithDeadObjectTest += -lpthread BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libnativeStack += -lpthread + BUILD_HOTSPOT_JTREG_LIBRARIES_LIBS_libTestUnloadedClass += -lpthread BUILD_HOTSPOT_JTREG_LIBRARIES_JDK_LIBS_libVThreadEventTest := java.base:libjvm BUILD_HOTSPOT_JTREG_EXECUTABLES_LIBS_exeGetCreatedJavaVMs := -lpthread BUILD_HOTSPOT_JTREG_EXECUTABLES_JDK_LIBS_exeGetCreatedJavaVMs := java.base:libjvm diff --git a/src/hotspot/share/classfile/classLoaderExt.cpp b/src/hotspot/share/classfile/classLoaderExt.cpp index 78e29f990d7d1..3cd7dd7cd3ba6 100644 --- a/src/hotspot/share/classfile/classLoaderExt.cpp +++ b/src/hotspot/share/classfile/classLoaderExt.cpp @@ -213,6 +213,15 @@ void ClassLoaderExt::process_jar_manifest(JavaThread* current, ClassPathEntry* e char sep = os::file_separator()[0]; const char* dir_name = entry->name(); const char* dir_tail = strrchr(dir_name, sep); +#ifdef _WINDOWS + // On Windows, we also support forward slash as the file separator when locating entries in the classpath entry. + const char* dir_tail2 = strrchr(dir_name, '/'); + if (dir_tail == nullptr) { + dir_tail = dir_tail2; + } else if (dir_tail2 != nullptr && dir_tail2 > dir_tail) { + dir_tail = dir_tail2; + } +#endif int dir_len; if (dir_tail == nullptr) { dir_len = 0; diff --git a/src/hotspot/share/prims/jvmtiEnv.cpp b/src/hotspot/share/prims/jvmtiEnv.cpp index a36d12059a96a..097ce33154051 100644 --- a/src/hotspot/share/prims/jvmtiEnv.cpp +++ b/src/hotspot/share/prims/jvmtiEnv.cpp @@ -3132,7 +3132,9 @@ JvmtiEnv::GetFieldName(fieldDescriptor* fdesc_ptr, char** name_ptr, char** signa // declaring_class_ptr - pre-checked for null jvmtiError JvmtiEnv::GetFieldDeclaringClass(fieldDescriptor* fdesc_ptr, jclass* declaring_class_ptr) { - + // As for the GetFieldDeclaringClass method, the XSL generated C++ code that calls it has + // a jclass of the relevant class or a subclass of it, which is fine in terms of ensuring + // the holder is kept alive. *declaring_class_ptr = get_jni_class_non_null(fdesc_ptr->field_holder()); return JVMTI_ERROR_NONE; } /* end GetFieldDeclaringClass */ @@ -3210,7 +3212,9 @@ JvmtiEnv::GetMethodName(Method* method, char** name_ptr, char** signature_ptr, c jvmtiError JvmtiEnv::GetMethodDeclaringClass(Method* method, jclass* declaring_class_ptr) { NULL_CHECK(method, JVMTI_ERROR_INVALID_METHODID); - (*declaring_class_ptr) = get_jni_class_non_null(method->method_holder()); + Klass* k = method->method_holder(); + Handle holder(Thread::current(), k->klass_holder()); // keep the klass alive + (*declaring_class_ptr) = get_jni_class_non_null(k); return JVMTI_ERROR_NONE; } /* end GetMethodDeclaringClass */ diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp index a05d69980931c..167ca557cde31 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp @@ -599,6 +599,7 @@ JvmtiEnvBase::jvf_for_thread_and_depth(JavaThread* java_thread, jint depth) { jclass JvmtiEnvBase::get_jni_class_non_null(Klass* k) { assert(k != nullptr, "k != null"); + assert(k->is_loader_alive(), "Must be alive"); Thread *thread = Thread::current(); return (jclass)jni_reference(Handle(thread, k->java_mirror())); } diff --git a/src/java.base/share/classes/java/io/ObjectInputFilter.java b/src/java.base/share/classes/java/io/ObjectInputFilter.java index e40a24072060d..879820761c129 100644 --- a/src/java.base/share/classes/java/io/ObjectInputFilter.java +++ b/src/java.base/share/classes/java/io/ObjectInputFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1218,8 +1218,7 @@ private static boolean matchesPackage(Class c, String pkg) { } /** - * Returns the pattern used to create this filter. - * @return the pattern used to create this filter + * {@return the pattern used to create this filter} */ @Override public String toString() { diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java index 74c34d80a7beb..983b80d2bc673 100644 --- a/src/java.base/share/classes/java/io/ObjectInputStream.java +++ b/src/java.base/share/classes/java/io/ObjectInputStream.java @@ -3859,8 +3859,7 @@ private int readUTFChar(StringBuilder sbuf, long utflen) } /** - * Returns the number of bytes read from the input stream. - * @return the number of bytes read from the input stream + * {@return the number of bytes read from the input stream} */ long getBytesRead() { return in.getBytesRead(); diff --git a/src/java.base/share/classes/java/lang/annotation/Retention.java b/src/java.base/share/classes/java/lang/annotation/Retention.java index daf5f6e9b23d3..a8afc76ac79f7 100644 --- a/src/java.base/share/classes/java/lang/annotation/Retention.java +++ b/src/java.base/share/classes/java/lang/annotation/Retention.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2020, 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 @@ -45,8 +45,7 @@ @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { /** - * Returns the retention policy. - * @return the retention policy + * {@return the retention policy} */ RetentionPolicy value(); } diff --git a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java index cb1f3707db68c..9fadc2f0f56d1 100644 --- a/src/java.base/share/classes/java/lang/foreign/MemorySegment.java +++ b/src/java.base/share/classes/java/lang/foreign/MemorySegment.java @@ -1285,6 +1285,14 @@ MemorySegment reinterpret(long newSize, * sequences with this charset's default replacement string. The {@link * java.nio.charset.CharsetDecoder} class should be used when more control * over the decoding process is required. + *

+ * Getting a string from a segment with a known byte offset and + * known byte length can be done like so: + * {@snippet lang=java : + * byte[] bytes = new byte[length]; + * MemorySegment.copy(segment, JAVA_BYTE, offset, bytes, 0, length); + * return new String(bytes, charset); + * } * * @param offset offset in bytes (relative to this segment address) at which this * access operation will occur diff --git a/src/java.base/share/classes/java/nio/charset/MalformedInputException.java b/src/java.base/share/classes/java/nio/charset/MalformedInputException.java index 37e20040dd554..c36f81f9153d9 100644 --- a/src/java.base/share/classes/java/nio/charset/MalformedInputException.java +++ b/src/java.base/share/classes/java/nio/charset/MalformedInputException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,16 +56,14 @@ public MalformedInputException(int inputLength) { } /** - * Returns the length of the input. - * @return the length of the input + * {@return the length of the input} */ public int getInputLength() { return inputLength; } /** - * Returns the message. - * @return the message + * {@return the message} */ public String getMessage() { return "Input length = " + inputLength; diff --git a/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java b/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java index c5fddd1684fd1..857c519974d7c 100644 --- a/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java +++ b/src/java.base/share/classes/java/nio/charset/UnmappableCharacterException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,16 +56,14 @@ public UnmappableCharacterException(int inputLength) { } /** - * Returns the length of the input. - * @return the length of the input + * {@return the length of the input} */ public int getInputLength() { return inputLength; } /** - * Returns the message. - * @return the message + * {@return the message} */ public String getMessage() { return "Input length = " + inputLength; diff --git a/src/java.base/share/classes/java/time/format/TextStyle.java b/src/java.base/share/classes/java/time/format/TextStyle.java index ec49da271adc7..2a1f8b896cab4 100644 --- a/src/java.base/share/classes/java/time/format/TextStyle.java +++ b/src/java.base/share/classes/java/time/format/TextStyle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,8 +137,7 @@ public boolean isStandalone() { } /** - * Returns the stand-alone style with the same size. - * @return the stand-alone style with the same size + * {@return the stand-alone style with the same size} */ public TextStyle asStandalone() { return TextStyle.values()[ordinal() | 1]; diff --git a/src/java.base/share/classes/java/util/SplittableRandom.java b/src/java.base/share/classes/java/util/SplittableRandom.java index cb1801f56805d..686fe66da2f53 100644 --- a/src/java.base/share/classes/java/util/SplittableRandom.java +++ b/src/java.base/share/classes/java/util/SplittableRandom.java @@ -47,7 +47,7 @@ *

  • Series of generated values pass the DieHarder suite testing * independence and uniformity properties of random number generators. * (Most recently validated with version + * href="https://webhome.phy.duke.edu/~rgb/General/dieharder.php"> version * 3.31.1.) These tests validate only the methods for certain * types and ranges, but similar properties are expected to hold, at * least approximately, for others as well. The period diff --git a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java index 6d6d9efad0398..f5a2ce4d9b4cc 100644 --- a/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java +++ b/src/java.base/share/classes/java/util/concurrent/SynchronousQueue.java @@ -477,8 +477,7 @@ public Spliterator spliterator() { } /** - * Returns a zero-length array. - * @return a zero-length array + * {@return a zero-length array} */ public Object[] toArray() { return new Object[0]; diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java index d8cb9869afecd..c6671deaa2eb5 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicBoolean.java @@ -176,8 +176,7 @@ public final boolean getAndSet(boolean newValue) { } /** - * Returns the String representation of the current value. - * @return the String representation of the current value + * {@return the String representation of the current value} */ public String toString() { return Boolean.toString(get()); diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java index 4f08ed3f64b68..4ebd758ccc7a3 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicInteger.java @@ -340,8 +340,7 @@ public final int accumulateAndGet(int x, } /** - * Returns the String representation of the current value. - * @return the String representation of the current value + * {@return the String representation of the current value} */ public String toString() { return Integer.toString(get()); diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java index 676788e4204ab..7e253ead3354f 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerArray.java @@ -366,8 +366,7 @@ public final int accumulateAndGet(int i, int x, } /** - * Returns the String representation of the current values of array. - * @return the String representation of the current values of array + * {@return the String representation of the current values of array} */ public String toString() { int iMax = array.length - 1; diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java index e446df8fd3e0c..d0e50b0fda885 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLong.java @@ -341,8 +341,7 @@ public final long accumulateAndGet(long x, } /** - * Returns the String representation of the current value. - * @return the String representation of the current value + * {@return the String representation of the current value} */ public String toString() { return Long.toString(get()); diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java index af2ff6729fd77..2145c79579971 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongArray.java @@ -366,8 +366,7 @@ public final long accumulateAndGet(int i, long x, } /** - * Returns the String representation of the current values of array. - * @return the String representation of the current values of array + * {@return the String representation of the current values of array} */ public String toString() { int iMax = array.length - 1; diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java index b2c692df5e7c7..da445da61badc 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReference.java @@ -269,8 +269,7 @@ public final V accumulateAndGet(V x, } /** - * Returns the String representation of the current value. - * @return the String representation of the current value + * {@return the String representation of the current value} */ public String toString() { return String.valueOf(get()); diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java index f85fb9376ad93..e8238320e2179 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java @@ -297,8 +297,7 @@ public final E accumulateAndGet(int i, E x, } /** - * Returns the String representation of the current values of array. - * @return the String representation of the current values of array + * {@return the String representation of the current values of array} */ public String toString() { int iMax = array.length - 1; diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java index d04b8253ee76d..eb837a0fd29ad 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/DoubleAccumulator.java @@ -189,8 +189,7 @@ public double getThenReset() { } /** - * Returns the String representation of the current value. - * @return the String representation of the current value + * {@return the String representation of the current value} */ public String toString() { return Double.toString(get()); diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java b/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java index be96853ce0921..0d48a686cf2a1 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/LongAccumulator.java @@ -183,8 +183,7 @@ public long getThenReset() { } /** - * Returns the String representation of the current value. - * @return the String representation of the current value + * {@return the String representation of the current value} */ public String toString() { return Long.toString(get()); diff --git a/src/java.base/share/classes/java/util/jar/Manifest.java b/src/java.base/share/classes/java/util/jar/Manifest.java index c0e30707a35ee..d584503329336 100644 --- a/src/java.base/share/classes/java/util/jar/Manifest.java +++ b/src/java.base/share/classes/java/util/jar/Manifest.java @@ -119,8 +119,7 @@ public Manifest(Manifest man) { } /** - * Returns the main Attributes for the Manifest. - * @return the main Attributes for the Manifest + * {@return the main Attributes for the Manifest} */ public Attributes getMainAttributes() { return attr; diff --git a/src/java.base/share/classes/java/util/zip/Deflater.java b/src/java.base/share/classes/java/util/zip/Deflater.java index 56d0978dbc00d..a23f8395c2178 100644 --- a/src/java.base/share/classes/java/util/zip/Deflater.java +++ b/src/java.base/share/classes/java/util/zip/Deflater.java @@ -782,8 +782,7 @@ public int deflate(ByteBuffer output, int flush) { } /** - * Returns the ADLER-32 value of the uncompressed data. - * @return the ADLER-32 value of the uncompressed data + * {@return the ADLER-32 value of the uncompressed data} */ public int getAdler() { synchronized (zsRef) { diff --git a/src/java.base/share/classes/java/util/zip/Inflater.java b/src/java.base/share/classes/java/util/zip/Inflater.java index 22ab21d88c0b0..109208bd9ad8c 100644 --- a/src/java.base/share/classes/java/util/zip/Inflater.java +++ b/src/java.base/share/classes/java/util/zip/Inflater.java @@ -282,8 +282,7 @@ public boolean needsInput() { } /** - * Returns true if a preset dictionary is needed for decompression. - * @return true if a preset dictionary is needed for decompression + * {@return true if a preset dictionary is needed for decompression} * @see Inflater#setDictionary */ public boolean needsDictionary() { @@ -293,10 +292,8 @@ public boolean needsDictionary() { } /** - * Returns true if the end of the compressed data stream has been - * reached. - * @return true if the end of the compressed data stream has been - * reached + * {@return true if the end of the compressed data stream has been + * reached} */ public boolean finished() { synchronized (zsRef) { @@ -602,8 +599,7 @@ public int inflate(ByteBuffer output) throws DataFormatException { } /** - * Returns the ADLER-32 value of the uncompressed data. - * @return the ADLER-32 value of the uncompressed data + * {@return the ADLER-32 value of the uncompressed data} */ public int getAdler() { synchronized (zsRef) { diff --git a/src/java.base/share/classes/java/util/zip/ZipEntry.java b/src/java.base/share/classes/java/util/zip/ZipEntry.java index d97760d950ab3..8c8bfeb322960 100644 --- a/src/java.base/share/classes/java/util/zip/ZipEntry.java +++ b/src/java.base/share/classes/java/util/zip/ZipEntry.java @@ -138,8 +138,7 @@ public ZipEntry(ZipEntry e) { } /** - * Returns the name of the entry. - * @return the name of the entry + * {@return the name of the entry} */ public String getName() { return name; diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index 80126bc79734d..333e3d0184976 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -498,8 +498,7 @@ public int available() throws IOException { } /** - * Returns the path name of the ZIP file. - * @return the path name of the ZIP file + * {@return the path name of the ZIP file} */ public String getName() { return filePath; @@ -560,8 +559,7 @@ public Iterator asIterator() { } /** - * Returns an enumeration of the ZIP file entries. - * @return an enumeration of the ZIP file entries + * {@return an enumeration of the ZIP file entries} * @throws IllegalStateException if the ZIP file has been closed */ public Enumeration entries() { 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 41ae247293d3f..30e146a82f49b 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java +++ b/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java @@ -207,15 +207,6 @@ private static long mismatch(AbstractMemorySegmentImpl src, long srcFromOffset, } } int remaining = length - offset; - // 0...XXX000 - for (; remaining >= 8; remaining -= 8) { - final long s = SCOPED_MEMORY_ACCESS.getLongUnaligned(src.sessionImpl(), src.unsafeGetBase(), src.unsafeGetOffset() + srcFromOffset + offset, !Architecture.isLittleEndian()); - final long d = SCOPED_MEMORY_ACCESS.getLongUnaligned(dst.sessionImpl(), dst.unsafeGetBase(), dst.unsafeGetOffset() + dstFromOffset + offset, !Architecture.isLittleEndian()); - if (s != d) { - return start + offset + mismatch(s, d); - } - offset += 8; - } // 0...0X00 if (remaining >= 4) { diff --git a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java index 4d10584fa09ba..44a2c4efb0694 100644 --- a/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java +++ b/src/jdk.crypto.cryptoki/share/classes/sun/security/pkcs11/SunPKCS11.java @@ -27,7 +27,7 @@ import java.io.*; import java.util.*; - +import java.util.stream.Collectors; import java.security.*; import java.security.interfaces.*; @@ -1272,7 +1272,11 @@ private void initToken(CK_SLOT_INFO slotInfo) throws PKCS11Exception { CKM_SHA3_512_RSA_PKCS_PSS); } } + long[] supportedMechanisms = p11.C_GetMechanismList(slotID); + Set supportedMechSet = + Arrays.stream(supportedMechanisms).boxed().collect + (Collectors.toCollection(HashSet::new)); // Create a map from the various Descriptors to the "most // preferred" mechanism that was defined during the @@ -1281,10 +1285,9 @@ private void initToken(CK_SLOT_INFO slotInfo) throws PKCS11Exception { // the earliest entry. When asked for "DES/CBC/PKCS5Padding", we // return a CKM_DES_CBC_PAD. final Map supportedAlgs = - new HashMap(); + new HashMap(); - for (int i = 0; i < supportedMechanisms.length; i++) { - long longMech = supportedMechanisms[i]; + for (long longMech : supportedMechanisms) { CK_MECHANISM_INFO mechInfo = token.getMechanismInfo(longMech); if (showInfo) { System.out.println("Mechanism " + @@ -1331,13 +1334,19 @@ private void initToken(CK_SLOT_INFO slotInfo) throws PKCS11Exception { for (Descriptor d : ds) { Integer oldMech = supportedAlgs.get(d); if (oldMech == null) { + // check all required mechs are supported if (d.requiredMechs != null) { - // Check that other mechanisms required for the - // service are supported before listing it as - // available for the first time. - for (int requiredMech : d.requiredMechs) { - if (token.getMechanismInfo( - requiredMech & 0xFFFFFFFFL) == null) { + for (int reqMech : d.requiredMechs) { + long longReqMech = reqMech & 0xFFFFFFFFL; + if (!config.isEnabled(longReqMech) || + !supportedMechSet.contains(longReqMech) || + brokenMechanisms.contains(longReqMech)) { + if (showInfo) { + System.out.println("DISABLED " + d.type + + " " + d.algorithm + + " due to no support for req'd mech " + + Functions.getMechanismName(longReqMech)); + } continue descLoop; } } @@ -1350,7 +1359,7 @@ private void initToken(CK_SLOT_INFO slotInfo) throws PKCS11Exception { (d.type == SIG && (mechInfo.flags & CKF_SIGN) == 0)) { if (showInfo) { - System.out.println("DISABLED " + d.type + + System.out.println("DISABLED " + d.type + " " + d.algorithm + " due to partial support"); } @@ -1374,7 +1383,6 @@ private void initToken(CK_SLOT_INFO slotInfo) throws PKCS11Exception { } } } - } // register algorithms in provider diff --git a/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java b/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java index f0d797c09aedf..560f42d0467da 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, 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 @@ -30,6 +30,7 @@ * @run driver/timeout=240 ClassPathAttr */ +import jdk.test.lib.Platform; import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.process.OutputAnalyzer; import java.io.File; @@ -82,6 +83,76 @@ static void testNormalOps() throws Exception { output.shouldMatch("checking shared classpath entry: .*cpattr2.jar"); output.shouldMatch("checking shared classpath entry: .*cpattr3.jar"); }); + + // Test handling of forward slash ('/') file separator when locating entries + // in the classpath entry on Windows. + // Skip the following test when CDS dynamic dump is enabled due to some + // issue when converting a relative path to real path. + if (Platform.isWindows() && !CDSTestUtils.DYNAMIC_DUMP) { + // Test with relative path + // Find the index to the dir before the jar file. + int idx = jar1.lastIndexOf(File.separator); + idx = jar1.substring(0, idx - 1).lastIndexOf(File.separator); + // Setup jar directory and names. + String jarDir = jar1.substring(0, idx); + String jar1Name = jar1.substring(idx + 1); + String jar4Name = jar4.substring(idx + 1); + String newCp = jar1Name.replace("\\", "/") + File.pathSeparator + jar4Name.replace("\\", "/"); + + OutputAnalyzer out = TestCommon.testDump(jarDir, newCp, classlist, "-Xlog:class+path=info"); + if (i == 1) { + out.shouldMatch("opened:.*cpattr1.jar"); // first jar on -cp + } else { + // first jar on -cp with long Class-Path: attribute + out.shouldMatch("opened:.*cpattr1_long.jar"); + } + // one of the jar in the Class-Path: attribute of cpattr1.jar + out.shouldMatch("opened:.*cpattr2.jar"); + + TestCommon.runWithRelativePath( + jarDir.replace("\\", "/"), + "-Xlog:class+path,class+load", + "-cp", newCp, + "CpAttr1") + .assertNormalExit(output -> { + output.shouldMatch("checking shared classpath entry: .*cpattr2.jar"); + output.shouldMatch("checking shared classpath entry: .*cpattr3.jar"); + }); + + // Go one directory up. + int idx2 = jar1.substring(0, idx - 1).lastIndexOf(File.separator); + if (idx2 != -1) { + // Setup jar directory and names. + jarDir = jar1.substring(0, idx2); + // Set relative path to jar containing '\' and '/' file separators + // e.g. d1\d2/A.jar + jar1Name = jar1.substring(idx2 + 1).replace("\\", "/"); + jar4Name = jar4.substring(idx2 + 1).replace("\\", "/"); + jar1Name = jar1Name.replaceFirst("/", "\\\\"); + jar4Name = jar4Name.replaceFirst("/", "\\\\"); + + newCp = jar1Name + File.pathSeparator + jar4Name; + out = TestCommon.testDump(jarDir, newCp, classlist, "-Xlog:class+path=info"); + if (i == 1) { + out.shouldMatch("opened:.*cpattr1.jar"); // first jar on -cp + } else { + // first jar on -cp with long Class-Path: attribute + out.shouldMatch("opened:.*cpattr1_long.jar"); + } + // one of the jar in the Class-Path: attribute of cpattr1.jar + out.shouldMatch("opened:.*cpattr2.jar"); + + TestCommon.runWithRelativePath( + jarDir.replace("\\", "/"), + "-Xlog:class+path,class+load", + "-cp", newCp, + "CpAttr1") + .assertNormalExit(output -> { + output.shouldMatch("checking shared classpath entry: .*cpattr2.jar"); + output.shouldMatch("checking shared classpath entry: .*cpattr3.jar"); + }); + } + } } // test duplicate jars in the "Class-path" attribute in the jar manifest diff --git a/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/TestUnloadedClass.java b/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/TestUnloadedClass.java new file mode 100644 index 0000000000000..dafec97111e2f --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/TestUnloadedClass.java @@ -0,0 +1,106 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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 8339725 + * @summary Stress test GetMethodDeclaringClass + * @requires vm.jvmti + * @requires (os.family == "linux") + * @library /test/lib + * @run driver/timeout=300 TestUnloadedClass + */ + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.Utils; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.Platform; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStream; +import java.lang.reflect.Constructor; + +public class TestUnloadedClass { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("TestUnloadedClass"), + "-Xmx50m", + "Test"); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + if (!Platform.isDebugBuild()) { + output.shouldContain("OutOfMemoryError"); + } + } +} + +class Test { + public static void main(String[] args) throws Exception { + long last = System.nanoTime(); + for (int i = 0;;i++) { + if (Platform.isDebugBuild() && i >= 1000) { + // Debug build costs too much time to OOM so limit the loop iteration + break; + } + CustomClassLoader loader = new CustomClassLoader(); + Class k = loader.findClass("MyClass"); + Constructor c = k.getDeclaredConstructor(); + c.setAccessible(true); + c.newInstance(); + + // call gc every ~1 second. + if ((System.nanoTime() - last) >= 1e9) { + System.gc(); + last = System.nanoTime(); + } + } + } +} + +class CustomClassLoader extends ClassLoader { + static byte[] BYTES; + + static { + try (InputStream in = CustomClassLoader.class.getResourceAsStream("MyClass.class")) { + try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + byte[] buf = new byte[4096]; + int len; + while ((len = in.read(buf)) != -1) { + baos.write(buf, 0, len); + } + BYTES = baos.toByteArray(); + } + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + @Override + public Class findClass(String name) throws ClassNotFoundException { + return defineClass(name, BYTES, 0, BYTES.length); + } +} + +class MyClass { +} diff --git a/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/libTestUnloadedClass.cpp b/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/libTestUnloadedClass.cpp new file mode 100644 index 0000000000000..c32b787d57894 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/GetMethodDeclaringClass/libTestUnloadedClass.cpp @@ -0,0 +1,129 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * Copyright (c) 2024, Alibaba Group Holding Limited. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * 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. + */ + +#include + +#include +#include +#include +#include +#include +#include + +static jvmtiEnv *_jvmti; +static JavaVM *_jvm; + +#define BUFFER_SIZE 100000 +static std::atomic ring_buffer[BUFFER_SIZE]; + +void get_method_details(jmethodID method) { + jclass method_class; + char *class_name = NULL; + if (_jvmti->GetMethodDeclaringClass(method, &method_class) == JVMTI_ERROR_NONE) { + if (_jvmti->GetClassSignature(method_class, &class_name, NULL) == JVMTI_ERROR_NONE) { + _jvmti->Deallocate((unsigned char *)class_name); + } + } +} + +void* read_ringbuffer(void* arg) { + JNIEnv *env; + _jvm->AttachCurrentThreadAsDaemon((void **)&env, NULL); + for (;;) { + jmethodID id = ring_buffer[rand() % BUFFER_SIZE].load(std::memory_order_relaxed); + if (id != (jmethodID)0) { + get_method_details(id); + } + } + return NULL; +} + +static void JNICALL ClassPrepareCallback(jvmtiEnv *jvmti_env, + JNIEnv *jni_env, + jthread thread, + jclass klass) { + static bool reader_created = false; + static int ring_buffer_idx = 0; + + char *class_name = NULL; + if (jvmti_env->GetClassSignature(klass, &class_name, NULL) != JVMTI_ERROR_NONE) { + return; + } + // We only care MyClass and only one thread loads it + bool is_my_class = strcmp(class_name, "LMyClass;") == 0; + jvmti_env->Deallocate((unsigned char *)class_name); + if (!is_my_class) { + return; + } + + if (!reader_created) { + pthread_t tid; + pthread_create(&tid, NULL, read_ringbuffer, NULL); + reader_created = true; + } + + jint method_count; + jmethodID *methods; + if (jvmti_env->GetClassMethods(klass, &method_count, &methods) == JVMTI_ERROR_NONE) { + ring_buffer[ring_buffer_idx++].store(methods[0], std::memory_order_relaxed); + ring_buffer_idx = ring_buffer_idx % BUFFER_SIZE; + jvmti_env->Deallocate((unsigned char *)methods); + } +} + +JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) { + for (int i = 0; i < BUFFER_SIZE; i++) { + ring_buffer[i].store(0, std::memory_order_relaxed); + } + + jvmtiEventCallbacks callbacks; + jvmtiError error; + + _jvm = jvm; + + if (jvm->GetEnv((void **)&_jvmti, JVMTI_VERSION_1_0) != JNI_OK) { + fprintf(stderr, "Unable to access JVMTI!\n"); + return JNI_ERR; + } + + // Set up the event callbacks + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.ClassPrepare = &ClassPrepareCallback; + + // Register the callbacks + error = _jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); + if (error != JVMTI_ERROR_NONE) { + fprintf(stderr, "Error setting event callbacks: %d\n", error); + return JNI_ERR; + } + + // Enable the ClassPrepare event + error = _jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL); + if (error != JVMTI_ERROR_NONE) { + fprintf(stderr, "Error enabling ClassPrepare event: %d\n", error); + return JNI_ERR; + } + + return JNI_OK; +} diff --git a/test/jdk/java/awt/dnd/DropActionChangeTest.java b/test/jdk/java/awt/dnd/DropActionChangeTest.java index 7cb1019a44de7..2bfbb44bbfd38 100644 --- a/test/jdk/java/awt/dnd/DropActionChangeTest.java +++ b/test/jdk/java/awt/dnd/DropActionChangeTest.java @@ -21,17 +21,17 @@ * questions. */ -import javax.swing.JFrame; import java.awt.AWTEvent; import java.awt.Component; import java.awt.EventQueue; import java.awt.Frame; import java.awt.Panel; import java.awt.Point; +import java.awt.Rectangle; import java.awt.Robot; +import java.awt.Toolkit; import java.awt.datatransfer.StringSelection; import java.awt.dnd.DnDConstants; -import java.awt.dnd.DragGestureEvent; import java.awt.dnd.DragGestureListener; import java.awt.dnd.DragSource; import java.awt.dnd.DragSourceAdapter; @@ -43,9 +43,13 @@ import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.AWTEventListener; -import java.awt.event.MouseEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.io.File; +import java.util.concurrent.atomic.AtomicReference; +import javax.imageio.ImageIO; +import javax.swing.JFrame; /* @test @@ -56,28 +60,24 @@ */ public class DropActionChangeTest extends JFrame implements AWTEventListener { - Robot robot; - Frame frame; + private static Robot robot; + private static Frame frame; + private static volatile DropActionChangeTest test; Panel panel; private volatile boolean failed; private volatile boolean dropEnd; private volatile Component clickedComponent; private final Object LOCK = new Object(); - static final int FRAME_ACTIVATION_TIMEOUT = 3000; - static final int DROP_COMPLETION_TIMEOUT = 5000; + static final int DROP_COMPLETION_TIMEOUT = 8000; static final int MOUSE_RELEASE_TIMEOUT = 2000; public static void main(String[] args) throws Exception { - DropActionChangeTest test = new DropActionChangeTest(); + EventQueue.invokeAndWait(() -> test = new DropActionChangeTest()); EventQueue.invokeAndWait(test::init); try { test.start(); } finally { - EventQueue.invokeAndWait(() -> { - if (test.frame != null) { - test.frame.dispose(); - } - }); + EventQueue.invokeAndWait(DropActionChangeTest::disposeFrame); } } @@ -97,10 +97,12 @@ public void init() { final DragSourceListener dsl = new DragSourceAdapter() { public void dragDropEnd(DragSourceDropEvent e) { - System.err.println("DragSourseListener.dragDropEnd(): " + + System.err.println("DragSourceListener.dragDropEnd(): " + "drop action=" + e.getDropAction()); if (e.getDropAction() != DnDConstants.ACTION_MOVE) { - System.err.println("FAILURE: wrong drop action:" + e.getDropAction()); + System.err.println("FAILURE: wrong drop action:" + + e.getDropAction() + ", It should be " + + DnDConstants.ACTION_MOVE); failed = true; } synchronized (LOCK) { @@ -110,11 +112,7 @@ public void dragDropEnd(DragSourceDropEvent e) { } }; - DragGestureListener dgl = new DragGestureListener() { - public void dragGestureRecognized(DragGestureEvent dge) { - dge.startDrag(null, new StringSelection("test"), dsl); - } - }; + DragGestureListener dgl = dge -> dge.startDrag(null, new StringSelection("test"), dsl); new DragSource().createDefaultDragGestureRecognizer(panel, DnDConstants.ACTION_COPY_OR_MOVE, dgl); @@ -142,11 +140,25 @@ public void drop(DropTargetDropEvent e) { frame.setVisible(true); } + private static void disposeFrame() { + if (frame != null) { + frame.dispose(); + } + if (test != null) { + test.dispose(); + } + } + public void start() { try { robot = new Robot(); + robot.setAutoDelay(100); + robot.waitForIdle(); + robot.delay(500); - Point startPoint = panel.getLocationOnScreen(); + AtomicReference startPointRef = new AtomicReference<>(); + EventQueue.invokeAndWait(()-> startPointRef.set(panel.getLocationOnScreen())); + Point startPoint = startPointRef.get(); startPoint.translate(50, 50); if (!pointInComponent(robot, startPoint, panel)) { @@ -163,15 +175,18 @@ public void start() { synchronized (LOCK) { robot.keyPress(KeyEvent.VK_CONTROL); robot.mouseMove(startPoint.x, startPoint.y); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); Util.doDrag(robot, startPoint, medPoint); + robot.delay(500); robot.keyRelease(KeyEvent.VK_CONTROL); Util.doDrag(robot, medPoint, endPoint); - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.delay(500); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); LOCK.wait(DROP_COMPLETION_TIMEOUT); } if (!dropEnd) { - System.err.println("DragSourseListener.dragDropEnd() was not called, returning"); + captureScreen("No_Drop_End_"); + System.err.println("DragSourceListener.dragDropEnd() was not called, returning"); return; } } catch (Throwable e) { @@ -179,10 +194,22 @@ public void start() { } if (failed) { - throw new RuntimeException("wrong drop action!"); + captureScreen("Wrong_Drop_Action_"); + throw new RuntimeException("Wrong drop action!"); } - System.err.println("test passed!"); + System.err.println("Test passed!"); + } + + private static void captureScreen(String str) { + try { + final Rectangle screenBounds = new Rectangle( + Toolkit.getDefaultToolkit().getScreenSize()); + ImageIO.write(robot.createScreenCapture(screenBounds), "png", + new File(str + "Failure_Screen.png")); + } catch (Exception e) { + e.printStackTrace(); + } } public void reset() { @@ -203,9 +230,9 @@ boolean pointInComponent(Robot robot, Point p, Component comp) robot.waitForIdle(); reset(); robot.mouseMove(p.x, p.y); - robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mousePress(InputEvent.BUTTON1_DOWN_MASK); synchronized (LOCK) { - robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK); LOCK.wait(MOUSE_RELEASE_TIMEOUT); } @@ -227,15 +254,11 @@ public static int sign(int n) { } public static void doDrag(Robot robot, Point startPoint, Point endPoint) { + robot.waitForIdle(); for (Point p = new Point(startPoint); !p.equals(endPoint); p.translate(Util.sign(endPoint.x - p.x), Util.sign(endPoint.y - p.y))) { robot.mouseMove(p.x, p.y); - try { - Thread.sleep(100); - } catch (InterruptedException e) { - e.printStackTrace(); - } } } -} +} \ No newline at end of file diff --git a/test/jdk/sun/security/pkcs11/Provider/RequiredMechCheck.cfg b/test/jdk/sun/security/pkcs11/Provider/RequiredMechCheck.cfg new file mode 100644 index 0000000000000..906e4a3a3625e --- /dev/null +++ b/test/jdk/sun/security/pkcs11/Provider/RequiredMechCheck.cfg @@ -0,0 +1,14 @@ +name = NSS + +showInfo = true + +slot = 1 + +library = ${pkcs11test.nss.lib} + +disabledMechanisms = { + CKM_SHA224_HMAC + CKM_SHA256_HMAC +} + +nssArgs = "configdir='${pkcs11test.nss.db}' certPrefix='' keyPrefix=''" diff --git a/test/jdk/sun/security/pkcs11/Provider/RequiredMechCheck.java b/test/jdk/sun/security/pkcs11/Provider/RequiredMechCheck.java new file mode 100644 index 0000000000000..11fb562a82548 --- /dev/null +++ b/test/jdk/sun/security/pkcs11/Provider/RequiredMechCheck.java @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8335288 + * @library /test/lib .. + * @modules jdk.crypto.cryptoki + * @summary check that if any required mech is unavailable, then the + * mechanism will be unavailable as well. + * @run testng/othervm RequiredMechCheck + */ +import java.nio.file.Path; +import java.security.Provider; +import java.security.NoSuchAlgorithmException; +import javax.crypto.Cipher; +import javax.crypto.Mac; +import javax.crypto.SecretKeyFactory; + +import jtreg.SkippedException; +import org.testng.SkipException; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class RequiredMechCheck extends PKCS11Test { + + private static record TestData(String serviceType, String algo, + boolean disabled) {} + + private static TestData[] testValues = { + new TestData("MAC", "HmacPBESHA1", false), + new TestData("MAC", "HmacPBESHA224", true), + new TestData("MAC", "HmacPBESHA256", true), + new TestData("MAC", "HmacPBESHA384", false), + new TestData("MAC", "HmacPBESHA512", false), + new TestData("SKF", "PBEWithHmacSHA1AndAES_128", false), + new TestData("SKF", "PBEWithHmacSHA224AndAES_128", true), + new TestData("SKF", "PBEWithHmacSHA256AndAES_128", true), + new TestData("SKF", "PBEWithHmacSHA384AndAES_128", false), + new TestData("SKF", "PBEWithHmacSHA512AndAES_128", false), + new TestData("CIP", "PBEWithHmacSHA1AndAES_128", false), + new TestData("CIP", "PBEWithHmacSHA224AndAES_128", true), + new TestData("CIP", "PBEWithHmacSHA256AndAES_128", true), + new TestData("CIP", "PBEWithHmacSHA384AndAES_128", false), + new TestData("CIP", "PBEWithHmacSHA512AndAES_128", false), + }; + + @BeforeClass + public void setUp() throws Exception { + Path configPath = Path.of(BASE).resolve("RequiredMechCheck.cfg"); + System.setProperty("CUSTOM_P11_CONFIG", configPath.toString()); + } + + @Test + public void test() throws Exception { + try { + main(new RequiredMechCheck()); + } catch (SkippedException se) { + throw new SkipException("One or more tests are skipped"); + } + } + + public void main(Provider p) throws Exception { + for (TestData td : testValues) { + String desc = td.serviceType + " " + td.algo; + Object t; + try { + switch (td.serviceType) { + case "MAC": + t = Mac.getInstance(td.algo, p); + break; + case "SKF": + t = SecretKeyFactory.getInstance(td.algo, p); + break; + case "CIP": + t = Cipher.getInstance(td.algo, p); + break; + default: + throw new RuntimeException("Unsupported Test Type!"); + } + + if (td.disabled) { + throw new RuntimeException("Fail, no NSAE for " + desc); + } else { + System.out.println("Ok, getInstance() works for " + desc); + } + } catch (NoSuchAlgorithmException e) { + if (td.disabled) { + System.out.println("Ok, NSAE thrown for " + desc); + } else { + throw new RuntimeException("Unexpected Ex for " + desc, e); + } + } + } + } +}