diff --git a/.hgignore b/.hgignore index aec0e31d131..9aab81ce35d 100644 --- a/.hgignore +++ b/.hgignore @@ -1,5 +1,6 @@ ^build/ ^dist/ +^.idea/ nbproject/private/ ^webrev ^.hgtip diff --git a/.hgtags b/.hgtags index 7f711e51df0..5618d206183 100644 --- a/.hgtags +++ b/.hgtags @@ -360,3 +360,4 @@ c84d0cce090e161d736de69e941830adf8c2f87a jdk-9+114 8d78fb40648dd221ce4ef19f9d5aa41ee1a3a884 jdk-9+115 84aba7335005a3a47751dcf1f37935f97df9f99a jdk-9+116 82b8d12a553f5617737c238cec060281d52e351c jdk-9+117 +7c04fcb12bd4a31570a238e663fa846dfa5ec3b8 jdk-9+118 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index bd47c1a0596..08fd371176c 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -360,3 +360,4 @@ f900d5afd9c83a0df8f36161c27c5e4c86a66f4c jdk-9+111 09617ce980b99d49abfd54dacfed353c47e2a115 jdk-9+115 6743a8e0cab7b5f6f4a0575f6664892f0ab740af jdk-9+116 e882bcdbdac436523f3d5681611d3118a3804ea7 jdk-9+117 +047f95de8f918d8ff5e8cd2636a2abb5c3c8adb8 jdk-9+118 diff --git a/common/autoconf/flags.m4 b/common/autoconf/flags.m4 index 7789f01450e..bdcec6208f3 100644 --- a/common/autoconf/flags.m4 +++ b/common/autoconf/flags.m4 @@ -768,7 +768,7 @@ AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER], $2CFLAGS_JDK="${$2CFLAGS_JDK} -fno-strict-aliasing" ;; esac - TOOLCHAIN_CHECK_COMPILER_VERSION(VERSION: 6, IF_AT_LEAST: FLAGS_SETUP_GCC6_COMPILER_FLAGS) + TOOLCHAIN_CHECK_COMPILER_VERSION(VERSION: 6, PREFIX: $2, IF_AT_LEAST: FLAGS_SETUP_GCC6_COMPILER_FLAGS) elif test "x$TOOLCHAIN_TYPE" = xclang; then $2JVM_CFLAGS="[$]$2JVM_CFLAGS -D_GNU_SOURCE" @@ -964,7 +964,7 @@ AC_DEFUN([FLAGS_SETUP_COMPILER_FLAGS_FOR_JDK_HELPER], -Wunused-value -Woverloaded-virtual" if test "x$TOOLCHAIN_TYPE" = xgcc; then - TOOLCHAIN_CHECK_COMPILER_VERSION(VERSION: [4.8], + TOOLCHAIN_CHECK_COMPILER_VERSION(VERSION: [4.8], PREFIX: $2, IF_AT_LEAST: [ # These flags either do not work or give spurious warnings prior to gcc 4.8. $2JVM_CFLAGS="[$]$2JVM_CFLAGS -Wno-format-zero-length -Wtype-limits -Wuninitialized" @@ -1411,9 +1411,15 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_MISC], DISABLE_WARNING_PREFIX= fi CFLAGS_WARNINGS_ARE_ERRORS="-Werror" - # Repeate the check for the BUILD_CC + # Repeate the check for the BUILD_CC and BUILD_CXX. Need to also reset + # CFLAGS since any target specific flags will likely not work with the + # build compiler CC_OLD="$CC" + CXX_OLD="$CXX" CC="$BUILD_CC" + CXX="$BUILD_CXX" + CFLAGS_OLD="$CFLAGS" + CFLAGS="" FLAGS_COMPILER_CHECK_ARGUMENTS(ARGUMENT: [-Wno-this-is-a-warning-that-do-not-exist], IF_TRUE: [BUILD_CC_CAN_DISABLE_WARNINGS=true], IF_FALSE: [BUILD_CC_CAN_DISABLE_WARNINGS=false] @@ -1424,6 +1430,8 @@ AC_DEFUN_ONCE([FLAGS_SETUP_COMPILER_FLAGS_MISC], BUILD_CC_DISABLE_WARNING_PREFIX= fi CC="$CC_OLD" + CXX="$CXX_OLD" + CFLAGS="$CFLAGS_OLD" ;; clang) DISABLE_WARNING_PREFIX="-Wno-" diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh index 548ab680d2a..f40198f8da3 100644 --- a/common/autoconf/generated-configure.sh +++ b/common/autoconf/generated-configure.sh @@ -4900,6 +4900,8 @@ TOOLCHAIN_MINIMUM_VERSION_xlc="" # Prepare the system so that TOOLCHAIN_CHECK_COMPILER_VERSION can be called. # Must have CC_VERSION_NUMBER and CXX_VERSION_NUMBER. +# $1 - optional variable prefix for compiler and version variables (BUILD_) +# $2 - optional variable prefix for comparable variable (OPENJDK_BUILD_) # Check if the configured compiler (C and C++) is of a specific version or @@ -4909,6 +4911,7 @@ TOOLCHAIN_MINIMUM_VERSION_xlc="" # VERSION: The version string to check against the found version # IF_AT_LEAST: block to run if the compiler is at least this version (>=) # IF_OLDER_THAN: block to run if the compiler is older than this version (<) +# PREFIX: Optional variable prefix for compiler to compare version for (OPENJDK_BUILD_) @@ -5073,7 +5076,7 @@ VS_SDK_PLATFORM_NAME_2013= #CUSTOM_AUTOCONF_INCLUDE # Do not change or remove the following line, it is needed for consistency checks: -DATE_WHEN_GENERATED=1462806878 +DATE_WHEN_GENERATED=1462970869 ############################################################################### # @@ -34795,19 +34798,19 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu if test "x$CC_VERSION_NUMBER" != "x$CXX_VERSION_NUMBER"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C and C++ compiler has different version numbers, $CC_VERSION_NUMBER vs $CXX_VERSION_NUMBER." >&5 -$as_echo "$as_me: WARNING: C and C++ compiler has different version numbers, $CC_VERSION_NUMBER vs $CXX_VERSION_NUMBER." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C and C++ compiler have different version numbers, $CC_VERSION_NUMBER vs $CXX_VERSION_NUMBER." >&5 +$as_echo "$as_me: WARNING: C and C++ compiler have different version numbers, $CC_VERSION_NUMBER vs $CXX_VERSION_NUMBER." >&2;} { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: This typically indicates a broken setup, and is not supported" >&5 $as_echo "$as_me: WARNING: This typically indicates a broken setup, and is not supported" >&2;} fi # We only check CC_VERSION_NUMBER since we assume CXX_VERSION_NUMBER is equal. - if [[ "$CC_VERSION_NUMBER" =~ (.*\.){3} ]] ; then + if [[ "[$]CC_VERSION_NUMBER" =~ (.*\.){3} ]] ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C compiler version number has more than three parts (X.Y.Z): $CC_VERSION_NUMBER. Comparisons might be wrong." >&5 $as_echo "$as_me: WARNING: C compiler version number has more than three parts (X.Y.Z): $CC_VERSION_NUMBER. Comparisons might be wrong." >&2;} fi - if [[ "$CC_VERSION_NUMBER" =~ [0-9]{6} ]] ; then + if [[ "[$]CC_VERSION_NUMBER" =~ [0-9]{6} ]] ; then { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C compiler version number has a part larger than 99999: $CC_VERSION_NUMBER. Comparisons might be wrong." >&5 $as_echo "$as_me: WARNING: C compiler version number has a part larger than 99999: $CC_VERSION_NUMBER. Comparisons might be wrong." >&2;} fi @@ -34850,6 +34853,13 @@ $as_echo "$as_me: WARNING: C compiler version number has a part larger than 9999 + + + + + + + @@ -34897,6 +34907,8 @@ $as_echo "$as_me: WARNING: You are using $TOOLCHAIN_TYPE older than $TOOLCHAIN_M + + fi # @@ -46475,6 +46487,268 @@ $as_echo "$as_me: Rewriting BUILD_STRIP to \"$new_complete\"" >&6;} BUILD_LDCXX="$BUILD_CXX" PATH="$OLDPATH" + + + COMPILER=$BUILD_CC + COMPILER_NAME=BuildC + + if test "x$TOOLCHAIN_TYPE" = xsolstudio; then + # cc -V output typically looks like + # cc: Sun C 5.12 Linux_i386 2011/11/16 + COMPILER_VERSION_OUTPUT=`$COMPILER -V 2>&1` + # Check that this is likely to be the Solaris Studio cc. + $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "^.*: Sun $COMPILER_NAME" > /dev/null + if test $? -ne 0; then + ALT_VERSION_OUTPUT=`$COMPILER --version 2>&1` + { $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&5 +$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with -V was: \"$COMPILER_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running with -V was: \"$COMPILER_VERSION_OUTPUT\"" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with --version was: \"$ALT_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running with --version was: \"$ALT_VERSION_OUTPUT\"" >&6;} + as_fn_error $? "A $TOOLCHAIN_TYPE compiler is required. Try setting --with-tools-dir." "$LINENO" 5 + fi + # Remove usage instructions (if present), and + # collapse compiler output into a single line + COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/ *[Uu]sage:.*//'` + COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e "s/^.*[ ,\t]$COMPILER_NAME[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/"` + elif test "x$TOOLCHAIN_TYPE" = xxlc; then + # xlc -qversion output typically looks like + # IBM XL C/C++ for AIX, V11.1 (5724-X13) + # Version: 11.01.0000.0015 + COMPILER_VERSION_OUTPUT=`$COMPILER -qversion 2>&1` + # Check that this is likely to be the IBM XL C compiler. + $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "IBM XL C" > /dev/null + if test $? -ne 0; then + ALT_VERSION_OUTPUT=`$COMPILER --version 2>&1` + { $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&5 +$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with -qversion was: \"$COMPILER_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running with -qversion was: \"$COMPILER_VERSION_OUTPUT\"" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with --version was: \"$ALT_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running with --version was: \"$ALT_VERSION_OUTPUT\"" >&6;} + as_fn_error $? "A $TOOLCHAIN_TYPE compiler is required. Try setting --with-tools-dir." "$LINENO" 5 + fi + # Collapse compiler output into a single line + COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT` + COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/^.*, V\([1-9][0-9.]*\).*$/\1/'` + elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then + # There is no specific version flag, but all output starts with a version string. + # First line typically looks something like: + # Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 + COMPILER_VERSION_OUTPUT=`$COMPILER 2>&1 | $HEAD -n 1 | $TR -d '\r'` + # Check that this is likely to be Microsoft CL.EXE. + $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "Microsoft.*Compiler" > /dev/null + if test $? -ne 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&5 +$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running it was: \"$COMPILER_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running it was: \"$COMPILER_VERSION_OUTPUT\"" >&6;} + as_fn_error $? "A $TOOLCHAIN_TYPE compiler is required. Try setting --with-tools-dir." "$LINENO" 5 + fi + # Collapse compiler output into a single line + COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT` + COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/^.*ersion.\([1-9][0-9.]*\) .*$/\1/'` + elif test "x$TOOLCHAIN_TYPE" = xgcc; then + # gcc --version output typically looks like + # gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 + # Copyright (C) 2013 Free Software Foundation, Inc. + # This is free software; see the source for copying conditions. There is NO + # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + COMPILER_VERSION_OUTPUT=`$COMPILER --version 2>&1` + # Check that this is likely to be GCC. + $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "Free Software Foundation" > /dev/null + if test $? -ne 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&5 +$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with --version was: \"$COMPILER_VERSION\"" >&5 +$as_echo "$as_me: The result from running with --version was: \"$COMPILER_VERSION\"" >&6;} + as_fn_error $? "A $TOOLCHAIN_TYPE compiler is required. Try setting --with-tools-dir." "$LINENO" 5 + fi + # Remove Copyright and legalese from version string, and + # collapse into a single line + COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/ *Copyright .*//'` + COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/^.* \([1-9]\.[0-9.]*\)[^0-9.].*$/\1/'` + elif test "x$TOOLCHAIN_TYPE" = xclang; then + # clang --version output typically looks like + # Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) + # clang version 3.3 (tags/RELEASE_33/final) + # or + # Debian clang version 3.2-7ubuntu1 (tags/RELEASE_32/final) (based on LLVM 3.2) + # Target: x86_64-pc-linux-gnu + # Thread model: posix + COMPILER_VERSION_OUTPUT=`$COMPILER --version 2>&1` + # Check that this is likely to be clang + $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "clang" > /dev/null + if test $? -ne 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&5 +$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with --version was: \"$COMPILER_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running with --version was: \"$COMPILER_VERSION_OUTPUT\"" >&6;} + as_fn_error $? "A $TOOLCHAIN_TYPE compiler is required. Try setting --with-tools-dir." "$LINENO" 5 + fi + # Collapse compiler output into a single line + COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT` + COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/^.* version \([1-9][0-9.]*\).*$/\1/'` + else + as_fn_error $? "Unknown toolchain type $TOOLCHAIN_TYPE." "$LINENO" 5 + fi + # This sets CC_VERSION_NUMBER or CXX_VERSION_NUMBER. (This comment is a grep marker) + BUILD_CC_VERSION_NUMBER="$COMPILER_VERSION_NUMBER" + # This sets CC_VERSION_STRING or CXX_VERSION_STRING. (This comment is a grep marker) + BUILD_CC_VERSION_STRING="$COMPILER_VERSION_STRING" + + { $as_echo "$as_me:${as_lineno-$LINENO}: Using $TOOLCHAIN_TYPE $COMPILER_NAME compiler version $COMPILER_VERSION_NUMBER [$COMPILER_VERSION_STRING]" >&5 +$as_echo "$as_me: Using $TOOLCHAIN_TYPE $COMPILER_NAME compiler version $COMPILER_VERSION_NUMBER [$COMPILER_VERSION_STRING]" >&6;} + + + COMPILER=$BUILD_CXX + COMPILER_NAME=BuildC++ + + if test "x$TOOLCHAIN_TYPE" = xsolstudio; then + # cc -V output typically looks like + # cc: Sun C 5.12 Linux_i386 2011/11/16 + COMPILER_VERSION_OUTPUT=`$COMPILER -V 2>&1` + # Check that this is likely to be the Solaris Studio cc. + $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "^.*: Sun $COMPILER_NAME" > /dev/null + if test $? -ne 0; then + ALT_VERSION_OUTPUT=`$COMPILER --version 2>&1` + { $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&5 +$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with -V was: \"$COMPILER_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running with -V was: \"$COMPILER_VERSION_OUTPUT\"" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with --version was: \"$ALT_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running with --version was: \"$ALT_VERSION_OUTPUT\"" >&6;} + as_fn_error $? "A $TOOLCHAIN_TYPE compiler is required. Try setting --with-tools-dir." "$LINENO" 5 + fi + # Remove usage instructions (if present), and + # collapse compiler output into a single line + COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/ *[Uu]sage:.*//'` + COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e "s/^.*[ ,\t]$COMPILER_NAME[ ,\t]\([1-9]\.[0-9][0-9]*\).*/\1/"` + elif test "x$TOOLCHAIN_TYPE" = xxlc; then + # xlc -qversion output typically looks like + # IBM XL C/C++ for AIX, V11.1 (5724-X13) + # Version: 11.01.0000.0015 + COMPILER_VERSION_OUTPUT=`$COMPILER -qversion 2>&1` + # Check that this is likely to be the IBM XL C compiler. + $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "IBM XL C" > /dev/null + if test $? -ne 0; then + ALT_VERSION_OUTPUT=`$COMPILER --version 2>&1` + { $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&5 +$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with -qversion was: \"$COMPILER_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running with -qversion was: \"$COMPILER_VERSION_OUTPUT\"" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with --version was: \"$ALT_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running with --version was: \"$ALT_VERSION_OUTPUT\"" >&6;} + as_fn_error $? "A $TOOLCHAIN_TYPE compiler is required. Try setting --with-tools-dir." "$LINENO" 5 + fi + # Collapse compiler output into a single line + COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT` + COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/^.*, V\([1-9][0-9.]*\).*$/\1/'` + elif test "x$TOOLCHAIN_TYPE" = xmicrosoft; then + # There is no specific version flag, but all output starts with a version string. + # First line typically looks something like: + # Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 + COMPILER_VERSION_OUTPUT=`$COMPILER 2>&1 | $HEAD -n 1 | $TR -d '\r'` + # Check that this is likely to be Microsoft CL.EXE. + $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "Microsoft.*Compiler" > /dev/null + if test $? -ne 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&5 +$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running it was: \"$COMPILER_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running it was: \"$COMPILER_VERSION_OUTPUT\"" >&6;} + as_fn_error $? "A $TOOLCHAIN_TYPE compiler is required. Try setting --with-tools-dir." "$LINENO" 5 + fi + # Collapse compiler output into a single line + COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT` + COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/^.*ersion.\([1-9][0-9.]*\) .*$/\1/'` + elif test "x$TOOLCHAIN_TYPE" = xgcc; then + # gcc --version output typically looks like + # gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 + # Copyright (C) 2013 Free Software Foundation, Inc. + # This is free software; see the source for copying conditions. There is NO + # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + COMPILER_VERSION_OUTPUT=`$COMPILER --version 2>&1` + # Check that this is likely to be GCC. + $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "Free Software Foundation" > /dev/null + if test $? -ne 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&5 +$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with --version was: \"$COMPILER_VERSION\"" >&5 +$as_echo "$as_me: The result from running with --version was: \"$COMPILER_VERSION\"" >&6;} + as_fn_error $? "A $TOOLCHAIN_TYPE compiler is required. Try setting --with-tools-dir." "$LINENO" 5 + fi + # Remove Copyright and legalese from version string, and + # collapse into a single line + COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/ *Copyright .*//'` + COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/^.* \([1-9]\.[0-9.]*\)[^0-9.].*$/\1/'` + elif test "x$TOOLCHAIN_TYPE" = xclang; then + # clang --version output typically looks like + # Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn) + # clang version 3.3 (tags/RELEASE_33/final) + # or + # Debian clang version 3.2-7ubuntu1 (tags/RELEASE_32/final) (based on LLVM 3.2) + # Target: x86_64-pc-linux-gnu + # Thread model: posix + COMPILER_VERSION_OUTPUT=`$COMPILER --version 2>&1` + # Check that this is likely to be clang + $ECHO "$COMPILER_VERSION_OUTPUT" | $GREP "clang" > /dev/null + if test $? -ne 0; then + { $as_echo "$as_me:${as_lineno-$LINENO}: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&5 +$as_echo "$as_me: The $COMPILER_NAME compiler (located as $COMPILER) does not seem to be the required $TOOLCHAIN_TYPE compiler." >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: The result from running with --version was: \"$COMPILER_VERSION_OUTPUT\"" >&5 +$as_echo "$as_me: The result from running with --version was: \"$COMPILER_VERSION_OUTPUT\"" >&6;} + as_fn_error $? "A $TOOLCHAIN_TYPE compiler is required. Try setting --with-tools-dir." "$LINENO" 5 + fi + # Collapse compiler output into a single line + COMPILER_VERSION_STRING=`$ECHO $COMPILER_VERSION_OUTPUT` + COMPILER_VERSION_NUMBER=`$ECHO $COMPILER_VERSION_OUTPUT | \ + $SED -e 's/^.* version \([1-9][0-9.]*\).*$/\1/'` + else + as_fn_error $? "Unknown toolchain type $TOOLCHAIN_TYPE." "$LINENO" 5 + fi + # This sets CC_VERSION_NUMBER or CXX_VERSION_NUMBER. (This comment is a grep marker) + BUILD_CXX_VERSION_NUMBER="$COMPILER_VERSION_NUMBER" + # This sets CC_VERSION_STRING or CXX_VERSION_STRING. (This comment is a grep marker) + BUILD_CXX_VERSION_STRING="$COMPILER_VERSION_STRING" + + { $as_echo "$as_me:${as_lineno-$LINENO}: Using $TOOLCHAIN_TYPE $COMPILER_NAME compiler version $COMPILER_VERSION_NUMBER [$COMPILER_VERSION_STRING]" >&5 +$as_echo "$as_me: Using $TOOLCHAIN_TYPE $COMPILER_NAME compiler version $COMPILER_VERSION_NUMBER [$COMPILER_VERSION_STRING]" >&6;} + + + if test "x$BUILD_CC_VERSION_NUMBER" != "x$BUILD_CXX_VERSION_NUMBER"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C and C++ compiler have different version numbers, $BUILD_CC_VERSION_NUMBER vs $BUILD_CXX_VERSION_NUMBER." >&5 +$as_echo "$as_me: WARNING: C and C++ compiler have different version numbers, $BUILD_CC_VERSION_NUMBER vs $BUILD_CXX_VERSION_NUMBER." >&2;} + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: This typically indicates a broken setup, and is not supported" >&5 +$as_echo "$as_me: WARNING: This typically indicates a broken setup, and is not supported" >&2;} + fi + + # We only check CC_VERSION_NUMBER since we assume CXX_VERSION_NUMBER is equal. + if [[ "[$]BUILD_CC_VERSION_NUMBER" =~ (.*\.){3} ]] ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C compiler version number has more than three parts (X.Y.Z): $BUILD_CC_VERSION_NUMBER. Comparisons might be wrong." >&5 +$as_echo "$as_me: WARNING: C compiler version number has more than three parts (X.Y.Z): $BUILD_CC_VERSION_NUMBER. Comparisons might be wrong." >&2;} + fi + + if [[ "[$]BUILD_CC_VERSION_NUMBER" =~ [0-9]{6} ]] ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: C compiler version number has a part larger than 99999: $BUILD_CC_VERSION_NUMBER. Comparisons might be wrong." >&5 +$as_echo "$as_me: WARNING: C compiler version number has a part larger than 99999: $BUILD_CC_VERSION_NUMBER. Comparisons might be wrong." >&2;} + fi + + OPENJDK_BUILD_COMPARABLE_ACTUAL_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$BUILD_CC_VERSION_NUMBER"` + else # If we are not cross compiling, use the normal target compilers for # building the build platform executables. @@ -49122,6 +49396,18 @@ $as_echo "$supports" >&6; } + + + + + + + + + + + + @@ -49711,6 +49997,8 @@ $as_echo "$supports" >&6; } + + elif test "x$TOOLCHAIN_TYPE" = xclang; then JVM_CFLAGS="$JVM_CFLAGS -D_GNU_SOURCE" @@ -49935,6 +50223,18 @@ $as_echo "$supports" >&6; } + + + + + + + + + + + + @@ -49987,6 +50287,8 @@ $as_echo "$supports" >&6; } + + fi if ! [[ " $JVM_VARIANTS " =~ " zero " ]] && ! [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then # Non-zero builds have stricter warnings @@ -50440,6 +50742,18 @@ $as_echo "$supports" >&6; } + + + + + + + + + + + + @@ -50469,7 +50783,7 @@ $as_echo "$supports" >&6; } # Version comparison method inspired by http://stackoverflow.com/a/24067243 COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$REFERENCE_VERSION"` - if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then + if test $OPENJDK_BUILD_COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then : else @@ -50488,6 +50802,8 @@ $as_echo "$supports" >&6; } + + elif test "x$TOOLCHAIN_TYPE" = xclang; then OPENJDK_BUILD_JVM_CFLAGS="$OPENJDK_BUILD_JVM_CFLAGS -D_GNU_SOURCE" @@ -50712,6 +51028,18 @@ $as_echo "$supports" >&6; } + + + + + + + + + + + + @@ -50741,7 +51069,7 @@ $as_echo "$supports" >&6; } # Version comparison method inspired by http://stackoverflow.com/a/24067243 COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", $1, $2, $3) }' <<< "$REFERENCE_VERSION"` - if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then + if test $OPENJDK_BUILD_COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then : # These flags either do not work or give spurious warnings prior to gcc 4.8. @@ -50764,6 +51092,8 @@ $as_echo "$supports" >&6; } + + fi if ! [[ " $JVM_VARIANTS " =~ " zero " ]] && ! [[ " $JVM_VARIANTS " =~ " zeroshark " ]] ; then # Non-zero builds have stricter warnings @@ -51918,9 +52248,15 @@ $as_echo "$supports" >&6; } DISABLE_WARNING_PREFIX= fi CFLAGS_WARNINGS_ARE_ERRORS="-Werror" - # Repeate the check for the BUILD_CC + # Repeate the check for the BUILD_CC and BUILD_CXX. Need to also reset + # CFLAGS since any target specific flags will likely not work with the + # build compiler CC_OLD="$CC" + CXX_OLD="$CXX" CC="$BUILD_CC" + CXX="$BUILD_CXX" + CFLAGS_OLD="$CFLAGS" + CFLAGS="" @@ -52198,6 +52534,8 @@ $as_echo "$supports" >&6; } BUILD_CC_DISABLE_WARNING_PREFIX= fi CC="$CC_OLD" + CXX="$CXX_OLD" + CFLAGS="$CFLAGS_OLD" ;; clang) DISABLE_WARNING_PREFIX="-Wno-" diff --git a/common/autoconf/toolchain.m4 b/common/autoconf/toolchain.m4 index 7e7a07c5d8b..c93d487a870 100644 --- a/common/autoconf/toolchain.m4 +++ b/common/autoconf/toolchain.m4 @@ -59,23 +59,25 @@ TOOLCHAIN_MINIMUM_VERSION_xlc="" # Prepare the system so that TOOLCHAIN_CHECK_COMPILER_VERSION can be called. # Must have CC_VERSION_NUMBER and CXX_VERSION_NUMBER. +# $1 - optional variable prefix for compiler and version variables (BUILD_) +# $2 - optional variable prefix for comparable variable (OPENJDK_BUILD_) AC_DEFUN([TOOLCHAIN_PREPARE_FOR_VERSION_COMPARISONS], [ - if test "x$CC_VERSION_NUMBER" != "x$CXX_VERSION_NUMBER"; then - AC_MSG_WARN([C and C++ compiler has different version numbers, $CC_VERSION_NUMBER vs $CXX_VERSION_NUMBER.]) + if test "x[$]$1CC_VERSION_NUMBER" != "x[$]$1CXX_VERSION_NUMBER"; then + AC_MSG_WARN([C and C++ compiler have different version numbers, [$]$1CC_VERSION_NUMBER vs [$]$1CXX_VERSION_NUMBER.]) AC_MSG_WARN([This typically indicates a broken setup, and is not supported]) fi # We only check CC_VERSION_NUMBER since we assume CXX_VERSION_NUMBER is equal. - if [ [[ "$CC_VERSION_NUMBER" =~ (.*\.){3} ]] ]; then - AC_MSG_WARN([C compiler version number has more than three parts (X.Y.Z): $CC_VERSION_NUMBER. Comparisons might be wrong.]) + if [ [[ "[$]$1CC_VERSION_NUMBER" =~ (.*\.){3} ]] ]; then + AC_MSG_WARN([C compiler version number has more than three parts (X.Y.Z): [$]$1CC_VERSION_NUMBER. Comparisons might be wrong.]) fi - if [ [[ "$CC_VERSION_NUMBER" =~ [0-9]{6} ]] ]; then - AC_MSG_WARN([C compiler version number has a part larger than 99999: $CC_VERSION_NUMBER. Comparisons might be wrong.]) + if [ [[ "[$]$1CC_VERSION_NUMBER" =~ [0-9]{6} ]] ]; then + AC_MSG_WARN([C compiler version number has a part larger than 99999: [$]$1CC_VERSION_NUMBER. Comparisons might be wrong.]) fi - COMPARABLE_ACTUAL_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", [$]1, [$]2, [$]3) }' <<< "$CC_VERSION_NUMBER"` + $2COMPARABLE_ACTUAL_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", [$]1, [$]2, [$]3) }' <<< "[$]$1CC_VERSION_NUMBER"` ]) # Check if the configured compiler (C and C++) is of a specific version or @@ -85,8 +87,9 @@ AC_DEFUN([TOOLCHAIN_PREPARE_FOR_VERSION_COMPARISONS], # VERSION: The version string to check against the found version # IF_AT_LEAST: block to run if the compiler is at least this version (>=) # IF_OLDER_THAN: block to run if the compiler is older than this version (<) +# PREFIX: Optional variable prefix for compiler to compare version for (OPENJDK_BUILD_) BASIC_DEFUN_NAMED([TOOLCHAIN_CHECK_COMPILER_VERSION], - [*VERSION IF_AT_LEAST IF_OLDER_THAN], [$@], + [*VERSION PREFIX IF_AT_LEAST IF_OLDER_THAN], [$@], [ # Need to assign to a variable since m4 is blocked from modifying parts in []. REFERENCE_VERSION=ARG_VERSION @@ -102,7 +105,7 @@ BASIC_DEFUN_NAMED([TOOLCHAIN_CHECK_COMPILER_VERSION], # Version comparison method inspired by http://stackoverflow.com/a/24067243 COMPARABLE_REFERENCE_VERSION=`$AWK -F. '{ printf("%05d%05d%05d\n", [$]1, [$]2, [$]3) }' <<< "$REFERENCE_VERSION"` - if test $COMPARABLE_ACTUAL_VERSION -ge $COMPARABLE_REFERENCE_VERSION ; then + if test [$]ARG_PREFIX[COMPARABLE_ACTUAL_VERSION] -ge $COMPARABLE_REFERENCE_VERSION ; then : ARG_IF_AT_LEAST else @@ -808,6 +811,10 @@ AC_DEFUN_ONCE([TOOLCHAIN_SETUP_BUILD_COMPILERS], BUILD_LDCXX="$BUILD_CXX" PATH="$OLDPATH" + + TOOLCHAIN_EXTRACT_COMPILER_VERSION(BUILD_CC, [BuildC]) + TOOLCHAIN_EXTRACT_COMPILER_VERSION(BUILD_CXX, [BuildC++]) + TOOLCHAIN_PREPARE_FOR_VERSION_COMPARISONS([BUILD_], [OPENJDK_BUILD_]) else # If we are not cross compiling, use the normal target compilers for # building the build platform executables. diff --git a/common/bin/idea.sh b/common/bin/idea.sh new file mode 100644 index 00000000000..911d309c070 --- /dev/null +++ b/common/bin/idea.sh @@ -0,0 +1,199 @@ +#!/bin/sh +# +# Copyright (c) 2009, 2014, 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. +# + +# Shell script for generating an IDEA project from a given list of modules + +usage() { + echo "usage: $0 [-h|--help] [-v|--verbose] [-o|--output <path>] [modules]+" + exit 1 +} + +SCRIPT_DIR=`dirname $0` +PWD=`pwd` +cd $SCRIPT_DIR; SCRIPT_DIR=`pwd` +cd ../../; TOP=`pwd`; cd $PWD + +IDEA_OUTPUT=$TOP/.idea +VERBOSE="false" +while [ $# -gt 0 ] +do + case $1 in + -h | --help ) + usage + ;; + + -v | --vebose ) + VERBOSE="true" + ;; + + -o | --output ) + IDEA_OUTPUT=$2 + shift + ;; + + -*) # bad option + usage + ;; + + * ) # non option + break + ;; + esac + shift +done + +mkdir $IDEA_OUTPUT || exit 1 +cd $IDEA_OUTPUT; IDEA_OUTPUT=`pwd` + +IDEA_MAKE="$TOP/make/idea" +IDEA_TEMPLATE="$IDEA_MAKE/template" +IML_TEMPLATE="$IDEA_TEMPLATE/jdk.iml" +ANT_TEMPLATE="$IDEA_TEMPLATE/ant.xml" +IDEA_IML="$IDEA_OUTPUT/jdk.iml" +IDEA_ANT="$IDEA_OUTPUT/ant.xml" + +if [ "$VERBOSE" = "true" ] ; then + echo "output dir: $IDEA_OUTPUT" + echo "idea template dir: $IDEA_TEMPLATE" +fi + +if [ ! -f "$IML_TEMPLATE" ] ; then + echo "FATAL: cannot find $IML_TEMPLATE" >&2; exit 1 +fi + +if [ ! -f "$ANT_TEMPLATE" ] ; then + echo "FATAL: cannot find $ANT_TEMPLATE" >&2; exit 1 +fi + +cp -r "$IDEA_TEMPLATE"/* "$IDEA_OUTPUT" +cd $TOP ; make -f "$IDEA_MAKE/idea.gmk" -I make/common idea MAKEOVERRIDES= OUT=$IDEA_OUTPUT/env.cfg MODULES="$*" || exit 1 +cd $SCRIPT_DIR + +. $IDEA_OUTPUT/env.cfg + +# Expect MODULE_ROOTS, MODULE_NAMES, BOOT_JDK & SPEC to be set +if [ "x$MODULE_ROOTS" = "x" ] ; then + echo "FATAL: MODULE_ROOTS is empty" >&2; exit 1 +fi + +if [ "x$MODULE_NAMES" = "x" ] ; then + echo "FATAL: MODULE_NAMES is empty" >&2; exit 1 +fi + +if [ "x$BOOT_JDK" = "x" ] ; then + echo "FATAL: BOOT_JDK is empty" >&2; exit 1 +fi + +if [ "x$SPEC" = "x" ] ; then + echo "FATAL: SPEC is empty" >&2; exit 1 +fi + +SOURCE_FOLDER=" <sourceFolder url=\"file://\$MODULE_DIR\$/####\" isTestSource=\"false\" />" +SOURCE_FOLDERS_DONE="false" + +addSourceFolder() { + root=$@ + relativePath="`echo "$root" | sed -e s@"$TOP/\(.*$\)"@"\1"@`" + folder="`echo "$SOURCE_FOLDER" | sed -e s@"\(.*/\)####\(.*\)"@"\1$relativePath\2"@`" + printf "%s\n" "$folder" >> $IDEA_IML +} + +### Generate project iml +RELATIVE_BUILD_DIR="`dirname $SPEC | sed -e s@"$TOP/\(.*$\)"@"\1"@`" +rm -f $IDEA_IML +while IFS= read -r line +do + if echo "$line" | egrep "^ .* <sourceFolder.*####" > /dev/null ; then + if [ "$SOURCE_FOLDERS_DONE" = "false" ] ; then + SOURCE_FOLDERS_DONE="true" + for root in $MODULE_ROOTS; do + addSourceFolder $root + done + fi + elif echo "$line" | egrep "^ .* <excludeFolder.*####" > /dev/null ; then + ul="`echo "$line" | sed -e s@"\(.*/\)####\(.*\)"@"\1$RELATIVE_BUILD_DIR\2"@`" + printf "%s\n" "$ul" >> $IDEA_IML + else + printf "%s\n" "$line" >> $IDEA_IML + fi +done < "$IML_TEMPLATE" + + +MODULE_NAME=" <property name=\"module.name\" value=\"####\" />" + +addModuleName() { + mn="`echo "$MODULE_NAME" | sed -e s@"\(.*\)####\(.*\)"@"\1$MODULE_NAMES\2"@`" + printf "%s\n" "$mn" >> $IDEA_ANT +} + +BUILD_DIR=" <property name=\"build.target.dir\" value=\"####\" />" + +addBuildDir() { + DIR=`dirname $SPEC` + mn="`echo "$BUILD_DIR" | sed -e s@"\(.*\)####\(.*\)"@"\1$DIR\2"@`" + printf "%s\n" "$mn" >> $IDEA_ANT +} + +### Generate ant.xml + +rm -f $IDEA_ANT +while IFS= read -r line +do + if echo "$line" | egrep "^ .* <property name=\"module.name\"" > /dev/null ; then + addModuleName + elif echo "$line" | egrep "^ .* <property name=\"build.target.dir\"" > /dev/null ; then + addBuildDir + else + printf "%s\n" "$line" >> $IDEA_ANT + fi +done < "$ANT_TEMPLATE" + +### Compile the custom Logger + +CLASSES=$IDEA_OUTPUT/classes + +if [ "x$ANT_HOME" = "x" ] ; then + # try some common locations, before giving up + if [ -f "/usr/share/ant/lib/ant.jar" ] ; then + ANT_HOME="/usr/share/ant" + elif [ -f "/usr/local/Cellar/ant/1.9.4/libexec/lib/ant.jar" ] ; then + ANT_HOME="/usr/local/Cellar/ant/1.9.4/libexec" + else + echo "FATAL: cannot find ant. Try setting ANT_HOME." >&2; exit 1 + fi +fi +CP=$ANT_HOME/lib/ant.jar +rm -rf $CLASSES; mkdir $CLASSES + +if [ "x$CYGPATH" = "x" ] ; then ## CYGPATH may be set in env.cfg + JAVAC_SOURCE_FILE=$IDEA_OUTPUT/src/idea/JdkIdeaAntLogger.java + JAVAC_CLASSES=$CLASSES + JAVAC_CP=$CP +else + JAVAC_SOURCE_FILE=`cygpath -am $IDEA_OUTPUT/src/idea/JdkIdeaAntLogger.java` + JAVAC_CLASSES=`cygpath -am $CLASSES` + JAVAC_CP=`cygpath -am $CP` +fi + +$BOOT_JDK/bin/javac -d $JAVAC_CLASSES -cp $JAVAC_CP $JAVAC_SOURCE_FILE diff --git a/common/bin/jib.sh b/common/bin/jib.sh index 454d78ce1d7..ea52385537b 100644 --- a/common/bin/jib.sh +++ b/common/bin/jib.sh @@ -89,7 +89,7 @@ install_jib() { fi if command -v curl > /dev/null; then - getcmd="curl -s" + getcmd="curl -s -L --retry 3 --retry-delay 5" elif command -v wget > /dev/null; then getcmd="wget --quiet -O -" else diff --git a/corba/.hgtags b/corba/.hgtags index 7a705d44659..feea5f070eb 100644 --- a/corba/.hgtags +++ b/corba/.hgtags @@ -360,3 +360,4 @@ cc30faa2da498c478e89ab062ff160653ca1b170 jdk-9+113 7bab1b1b36824924b1c657a8419369ba93d198d3 jdk-9+115 7dfa7377a5e601b8f740741a9a80e04c72dd04d6 jdk-9+116 7a1b36bf2fe55a9a7732489ccdd326c910329a7e jdk-9+117 +8c2c2d17f7ce92a31c9ccb44a122ec62f5a85ace jdk-9+118 diff --git a/hotspot/.hgtags b/hotspot/.hgtags index d308ce9a4c0..c2bf9fb792d 100644 --- a/hotspot/.hgtags +++ b/hotspot/.hgtags @@ -520,3 +520,4 @@ b64432bae5271735fd53300b2005b713e98ef411 jdk-9+114 88dd08d7be0fe7fb9f1914b1628f0aae9bf56e25 jdk-9+115 61a214186dae6811dd989e9165e42f7dbf02acde jdk-9+116 88170d3642905b9e6cac03e8efcc976885a7e6da jdk-9+117 +9b1075cac08dc836ec32e7b368415cbe3aceaf8c jdk-9+118 diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index 5166478e5e7..834e1ae88fc 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -3387,14 +3387,14 @@ bool force_verify_field_access(Klass* current_class, Klass* field_class, AccessF return (!access.is_private() && InstanceKlass::cast(current_class)->is_same_class_package(field_class)); } -// Return the first non-null class loader up the execution stack, or null -// if only code from the null class loader is on the stack. +// Return the first user-defined class loader up the execution stack, or null +// if only code from the bootstrap or platform class loader is on the stack. JVM_ENTRY(jobject, JVM_LatestUserDefinedLoader(JNIEnv *env)) for (vframeStream vfst(thread); !vfst.at_end(); vfst.next()) { vfst.skip_reflection_related_frames(); // Only needed for 1.4 reflection oop loader = vfst.method()->method_holder()->class_loader(); - if (loader != NULL) { + if (loader != NULL && !SystemDictionary::is_platform_class_loader(loader)) { return JNIHandles::make_local(env, loader); } } diff --git a/hotspot/test/Makefile b/hotspot/test/Makefile index 3468e65bcac..1dfecd6bce1 100644 --- a/hotspot/test/Makefile +++ b/hotspot/test/Makefile @@ -120,24 +120,33 @@ endif TEST_ROOT := $(shell pwd) # Root of all test results -ifdef ALT_OUTPUTDIR - ABS_BUILD_ROOT = $(ALT_OUTPUTDIR) +ifdef TEST_OUTPUT_DIR + $(shell $(MKDIR) -p $(TEST_OUTPUT_DIR)/jtreg) + ABS_TEST_OUTPUT_DIR := \ + $(shell $(CD) $(TEST_OUTPUT_DIR)/jtreg && $(PWD)) else - ABS_BUILD_ROOT = $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH) + ifdef ALT_OUTPUTDIR + ABS_OUTPUTDIR = $(shell $(CD) $(ALT_OUTPUTDIR) && $(PWD)) + else + ABS_OUTPUTDIR = $(shell $(CD) $(TEST_ROOT)/.. && $(PWD)) + endif + + ABS_PLATFORM_BUILD_ROOT = $(ABS_OUTPUTDIR) + ABS_TEST_OUTPUT_DIR := $(ABS_PLATFORM_BUILD_ROOT)/testoutput/$(UNIQUE_DIR) endif -ABS_TEST_OUTPUT_DIR = $(ABS_BUILD_ROOT)/testoutput/$(UNIQUE_DIR) # Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test) ifndef PRODUCT_HOME - # Try to use j2sdk-image if it exists - ABS_JDK_IMAGE = $(ABS_BUILD_ROOT)/j2sdk-image - PRODUCT_HOME := \ - $(shell \ - if [ -d $(ABS_JDK_IMAGE) ] ; then \ - $(ECHO) "$(ABS_JDK_IMAGE)"; \ - else \ - $(ECHO) "$(ABS_BUILD_ROOT)" ; \ + # Try to use images/jdk if it exists + ABS_JDK_IMAGE = $(ABS_PLATFORM_BUILD_ROOT)/images/jdk + PRODUCT_HOME := \ + $(shell \ + if [ -d $(ABS_JDK_IMAGE) ] ; then \ + $(ECHO) "$(ABS_JDK_IMAGE)"; \ + else \ + $(ECHO) "$(ABS_PLATFORM_BUILD_ROOT)"; \ fi) + PRODUCT_HOME := $(PRODUCT_HOME) endif # Expect JPRT to set JAVA_ARGS (e.g. -server etc.) diff --git a/jaxp/.hgtags b/jaxp/.hgtags index f36d86837fa..3bef243c570 100644 --- a/jaxp/.hgtags +++ b/jaxp/.hgtags @@ -360,3 +360,4 @@ bdbf2342b21bd8ecad1b4e6499a0dfb314952bd7 jdk-9+103 1902a5bda18e794b31fc5f520f5e7d827714b50d jdk-9+115 9d71d20e614777cd23c1a43b38b5c08a9094d27a jdk-9+116 46b57560cd06ebcdd21489250628ff5f9d9d8916 jdk-9+117 +a8aa25fc6c5fda0ed7a93b8ffee62da326a752fc jdk-9+118 diff --git a/jaxp/THIRD_PARTY_README b/jaxp/THIRD_PARTY_README index a93b35b994c..4d3007051ce 100644 --- a/jaxp/THIRD_PARTY_README +++ b/jaxp/THIRD_PARTY_README @@ -3387,7 +3387,6 @@ included with JRE 8, JDK 8, and OpenJDK 8, except where noted: Apache Commons Math 2.2 Apache Derby 10.10.1.2 [included with JDK 8] Apache Jakarta BCEL 5.2 - Apache Jakarta Regexp 1.4 Apache Santuario XML Security for Java 1.5.4 Apache Xalan-Java 2.7.1 Apache Xerces Java 2.10.0 diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java index 162afd1e0dd..f755549b902 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java +++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/util/InstructionFinder.java @@ -4,64 +4,29 @@ */ package com.sun.org.apache.bcel.internal.util; -/* ==================================================================== - * The Apache Software License, Version 1.1 +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at * - * Copyright (c) 2001 The Apache Software Foundation. All rights - * reserved. + * http://www.apache.org/licenses/LICENSE-2.0 * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Apache" and "Apache Software Foundation" and - * "Apache BCEL" must not be used to endorse or promote products - * derived from this software without prior written permission. For - * written permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * "Apache BCEL", nor may "Apache" appear in their name, without - * prior written permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation. For more - * information on the Apache Software Foundation, please see - * <http://www.apache.org/>. */ -import java.util.*; import com.sun.org.apache.bcel.internal.Constants; import com.sun.org.apache.bcel.internal.generic.*; -import com.sun.org.apache.regexp.internal.*; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * InstructionFinder is a tool to search for given instructions patterns, @@ -231,28 +196,22 @@ public class InstructionFinder { if(start == -1) throw new ClassGenException("Instruction handle " + from + " not found in instruction list."); - try { - RE regex = new RE(search); - ArrayList matches = new ArrayList(); - while(start < il_string.length() && regex.match(il_string, start)) { - int startExpr = regex.getParenStart(0); - int endExpr = regex.getParenEnd(0); - int lenExpr = regex.getParenLength(0); + Pattern regex = Pattern.compile(search); + List<InstructionHandle[]> matches = new ArrayList<>(); + Matcher matcher = regex.matcher(il_string); + while(start < il_string.length() && matcher.find(start)) { + int startExpr = matcher.start(); + int endExpr = matcher.end(); + int lenExpr = endExpr - startExpr; + InstructionHandle[] match = getMatch(startExpr, lenExpr); - InstructionHandle[] match = getMatch(startExpr, lenExpr); - - if((constraint == null) || constraint.checkCode(match)) - matches.add(match); - start = endExpr; - } - - return matches.iterator(); - } catch(RESyntaxException e) { - System.err.println(e); + if((constraint == null) || constraint.checkCode(match)) + matches.add(match); + start = endExpr; } - return null; + return matches.iterator(); } /** diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/CharacterArrayCharacterIterator.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/CharacterArrayCharacterIterator.java deleted file mode 100644 index 6382d478d96..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/CharacterArrayCharacterIterator.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -/** - * Encapsulates char[] as CharacterIterator - * - * @author <a href="mailto:ales.novak@netbeans.com">Ales Novak</a> - */ -public final class CharacterArrayCharacterIterator implements CharacterIterator -{ - /** encapsulated */ - private final char[] src; - /** offset in the char array */ - private final int off; - /** used portion of the array */ - private final int len; - - /** @param src - encapsulated String */ - public CharacterArrayCharacterIterator(char[] src, int off, int len) - { - this.src = src; - this.off = off; - this.len = len; - } - - /** @return a substring */ - public String substring(int beginIndex, int endIndex) - { - if (endIndex > len) { - throw new IndexOutOfBoundsException("endIndex=" + endIndex - + "; sequence size=" + len); - } - if (beginIndex < 0 || beginIndex > endIndex) { - throw new IndexOutOfBoundsException("beginIndex=" + beginIndex - + "; endIndex=" + endIndex); - } - return new String(src, off + beginIndex, endIndex - beginIndex); - } - - /** @return a substring */ - public String substring(int beginIndex) - { - return substring(beginIndex, len); - } - - /** @return a character at the specified position. */ - public char charAt(int pos) - { - return src[off + pos]; - } - - /** @return <tt>true</tt> iff if the specified index is after the end of the character stream */ - public boolean isEnd(int pos) - { - return (pos >= len); - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/CharacterIterator.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/CharacterIterator.java deleted file mode 100644 index 69db536aaa2..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/CharacterIterator.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -/** - * Encapsulates different types of character sources - String, InputStream, ... - * Defines a set of common methods - * - * @author <a href="mailto:ales.novak@netbeans.com">Ales Novak</a> - */ -public interface CharacterIterator -{ - /** @return a substring */ - String substring(int beginIndex, int endIndex); - - /** @return a substring */ - String substring(int beginIndex); - - /** @return a character at the specified position. */ - char charAt(int pos); - - /** @return <tt>true</tt> iff if the specified index is after the end of the character stream */ - boolean isEnd(int pos); -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RE.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RE.java deleted file mode 100644 index 0cdc012dbb7..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RE.java +++ /dev/null @@ -1,1760 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -import java.io.Serializable; -import java.util.Vector; - -/** - * RE is an efficient, lightweight regular expression evaluator/matcher - * class. Regular expressions are pattern descriptions which enable - * sophisticated matching of strings. In addition to being able to - * match a string against a pattern, you can also extract parts of the - * match. This is especially useful in text parsing! Details on the - * syntax of regular expression patterns are given below. - * - * <p> - * To compile a regular expression (RE), you can simply construct an RE - * matcher object from the string specification of the pattern, like this: - * - * <pre> - * RE r = new RE("a*b"); - * </pre> - * - * <p> - * Once you have done this, you can call either of the RE.match methods to - * perform matching on a String. For example: - * - * <pre> - * boolean matched = r.match("aaaab"); - * </pre> - * - * will cause the boolean matched to be set to true because the - * pattern "a*b" matches the string "aaaab". - * - * <p> - * If you were interested in the <i>number</i> of a's which matched the - * first part of our example expression, you could change the expression to - * "(a*)b". Then when you compiled the expression and matched it against - * something like "xaaaab", you would get results like this: - * - * <pre> - * RE r = new RE("(a*)b"); // Compile expression - * boolean matched = r.match("xaaaab"); // Match against "xaaaab" - * - * String wholeExpr = r.getParen(0); // wholeExpr will be 'aaaab' - * String insideParens = r.getParen(1); // insideParens will be 'aaaa' - * - * int startWholeExpr = r.getParenStart(0); // startWholeExpr will be index 1 - * int endWholeExpr = r.getParenEnd(0); // endWholeExpr will be index 6 - * int lenWholeExpr = r.getParenLength(0); // lenWholeExpr will be 5 - * - * int startInside = r.getParenStart(1); // startInside will be index 1 - * int endInside = r.getParenEnd(1); // endInside will be index 5 - * int lenInside = r.getParenLength(1); // lenInside will be 4 - * </pre> - * - * You can also refer to the contents of a parenthesized expression - * within a regular expression itself. This is called a - * 'backreference'. The first backreference in a regular expression is - * denoted by \1, the second by \2 and so on. So the expression: - * - * <pre> - * ([0-9]+)=\1 - * </pre> - * - * will match any string of the form n=n (like 0=0 or 2=2). - * - * <p> - * The full regular expression syntax accepted by RE is described here: - * - * <pre> - * - * <b><font face=times roman>Characters</font></b> - * - * <i>unicodeChar</i> Matches any identical unicode character - * \ Used to quote a meta-character (like '*') - * \\ Matches a single '\' character - * \0nnn Matches a given octal character - * \xhh Matches a given 8-bit hexadecimal character - * \\uhhhh Matches a given 16-bit hexadecimal character - * \t Matches an ASCII tab character - * \n Matches an ASCII newline character - * \r Matches an ASCII return character - * \f Matches an ASCII form feed character - * - * - * <b><font face=times roman>Character Classes</font></b> - * - * [abc] Simple character class - * [a-zA-Z] Character class with ranges - * [^abc] Negated character class - * </pre> - * - * <b>NOTE:</b> Incomplete ranges will be interpreted as "starts - * from zero" or "ends with last character". - * <br> - * I.e. [-a] is the same as [\\u0000-a], and [a-] is the same as [a-\\uFFFF], - * [-] means "all characters". - * - * <pre> - * - * <b><font face=times roman>Standard POSIX Character Classes</font></b> - * - * [:alnum:] Alphanumeric characters. - * [:alpha:] Alphabetic characters. - * [:blank:] Space and tab characters. - * [:cntrl:] Control characters. - * [:digit:] Numeric characters. - * [:graph:] Characters that are printable and are also visible. - * (A space is printable, but not visible, while an - * `a' is both.) - * [:lower:] Lower-case alphabetic characters. - * [:print:] Printable characters (characters that are not - * control characters.) - * [:punct:] Punctuation characters (characters that are not letter, - * digits, control characters, or space characters). - * [:space:] Space characters (such as space, tab, and formfeed, - * to name a few). - * [:upper:] Upper-case alphabetic characters. - * [:xdigit:] Characters that are hexadecimal digits. - * - * - * <b><font face=times roman>Non-standard POSIX-style Character Classes</font></b> - * - * [:javastart:] Start of a Java identifier - * [:javapart:] Part of a Java identifier - * - * - * <b><font face=times roman>Predefined Classes</font></b> - * - * . Matches any character other than newline - * \w Matches a "word" character (alphanumeric plus "_") - * \W Matches a non-word character - * \s Matches a whitespace character - * \S Matches a non-whitespace character - * \d Matches a digit character - * \D Matches a non-digit character - * - * - * <b><font face=times roman>Boundary Matchers</font></b> - * - * ^ Matches only at the beginning of a line - * $ Matches only at the end of a line - * \b Matches only at a word boundary - * \B Matches only at a non-word boundary - * - * - * <b><font face=times roman>Greedy Closures</font></b> - * - * A* Matches A 0 or more times (greedy) - * A+ Matches A 1 or more times (greedy) - * A? Matches A 1 or 0 times (greedy) - * A{n} Matches A exactly n times (greedy) - * A{n,} Matches A at least n times (greedy) - * A{n,m} Matches A at least n but not more than m times (greedy) - * - * - * <b><font face=times roman>Reluctant Closures</font></b> - * - * A*? Matches A 0 or more times (reluctant) - * A+? Matches A 1 or more times (reluctant) - * A?? Matches A 0 or 1 times (reluctant) - * - * - * <b><font face=times roman>Logical Operators</font></b> - * - * AB Matches A followed by B - * A|B Matches either A or B - * (A) Used for subexpression grouping - * (?:A) Used for subexpression clustering (just like grouping but - * no backrefs) - * - * - * <b><font face=times roman>Backreferences</font></b> - * - * \1 Backreference to 1st parenthesized subexpression - * \2 Backreference to 2nd parenthesized subexpression - * \3 Backreference to 3rd parenthesized subexpression - * \4 Backreference to 4th parenthesized subexpression - * \5 Backreference to 5th parenthesized subexpression - * \6 Backreference to 6th parenthesized subexpression - * \7 Backreference to 7th parenthesized subexpression - * \8 Backreference to 8th parenthesized subexpression - * \9 Backreference to 9th parenthesized subexpression - * </pre> - * - * <p> - * All closure operators (+, *, ?, {m,n}) are greedy by default, meaning - * that they match as many elements of the string as possible without - * causing the overall match to fail. If you want a closure to be - * reluctant (non-greedy), you can simply follow it with a '?'. A - * reluctant closure will match as few elements of the string as - * possible when finding matches. {m,n} closures don't currently - * support reluctancy. - * - * <p> - * <b><font face="times roman">Line terminators</font></b> - * <br> - * A line terminator is a one- or two-character sequence that marks - * the end of a line of the input character sequence. The following - * are recognized as line terminators: - * <ul> - * <li>A newline (line feed) character ('\n'),</li> - * <li>A carriage-return character followed immediately by a newline character ("\r\n"),</li> - * <li>A standalone carriage-return character ('\r'),</li> - * <li>A next-line character ('\u0085'),</li> - * <li>A line-separator character ('\u2028'), or</li> - * <li>A paragraph-separator character ('\u2029).</li> - * </ul> - * - * <p> - * RE runs programs compiled by the RECompiler class. But the RE - * matcher class does not include the actual regular expression compiler - * for reasons of efficiency. In fact, if you want to pre-compile one - * or more regular expressions, the 'recompile' class can be invoked - * from the command line to produce compiled output like this: - * - * <pre> - * // Pre-compiled regular expression "a*b" - * char[] re1Instructions = - * { - * 0x007c, 0x0000, 0x001a, 0x007c, 0x0000, 0x000d, 0x0041, - * 0x0001, 0x0004, 0x0061, 0x007c, 0x0000, 0x0003, 0x0047, - * 0x0000, 0xfff6, 0x007c, 0x0000, 0x0003, 0x004e, 0x0000, - * 0x0003, 0x0041, 0x0001, 0x0004, 0x0062, 0x0045, 0x0000, - * 0x0000, - * }; - * - * - * REProgram re1 = new REProgram(re1Instructions); - * </pre> - * - * You can then construct a regular expression matcher (RE) object from - * the pre-compiled expression re1 and thus avoid the overhead of - * compiling the expression at runtime. If you require more dynamic - * regular expressions, you can construct a single RECompiler object and - * re-use it to compile each expression. Similarly, you can change the - * program run by a given matcher object at any time. However, RE and - * RECompiler are not threadsafe (for efficiency reasons, and because - * requiring thread safety in this class is deemed to be a rare - * requirement), so you will need to construct a separate compiler or - * matcher object for each thread (unless you do thread synchronization - * yourself). Once expression compiled into the REProgram object, REProgram - * can be safely shared across multiple threads and RE objects. - * - * <br><p><br> - * - * <font color="red"> - * <i>ISSUES:</i> - * - * <ul> - * <li>com.weusours.util.re is not currently compatible with all - * standard POSIX regcomp flags</li> - * <li>com.weusours.util.re does not support POSIX equivalence classes - * ([=foo=] syntax) (I18N/locale issue)</li> - * <li>com.weusours.util.re does not support nested POSIX character - * classes (definitely should, but not completely trivial)</li> - * <li>com.weusours.util.re Does not support POSIX character collation - * concepts ([.foo.] syntax) (I18N/locale issue)</li> - * <li>Should there be different matching styles (simple, POSIX, Perl etc?)</li> - * <li>Should RE support character iterators (for backwards RE matching!)?</li> - * <li>Should RE support reluctant {m,n} closures (does anyone care)?</li> - * <li>Not *all* possibilities are considered for greediness when backreferences - * are involved (as POSIX suggests should be the case). The POSIX RE - * "(ac*)c*d[ac]*\1", when matched against "acdacaa" should yield a match - * of acdacaa where \1 is "a". This is not the case in this RE package, - * and actually Perl doesn't go to this extent either! Until someone - * actually complains about this, I'm not sure it's worth "fixing". - * If it ever is fixed, test #137 in RETest.txt should be updated.</li> - * </ul> - * - * </font> - * - * @see recompile - * @see RECompiler - * - * @author <a href="mailto:jonl@muppetlabs.com">Jonathan Locke</a> - * @author <a href="mailto:ts@sch-fer.de">Tobias Schäfer</a> - */ -public class RE implements Serializable -{ - /** - * Specifies normal, case-sensitive matching behaviour. - */ - public static final int MATCH_NORMAL = 0x0000; - - /** - * Flag to indicate that matching should be case-independent (folded) - */ - public static final int MATCH_CASEINDEPENDENT = 0x0001; - - /** - * Newlines should match as BOL/EOL (^ and $) - */ - public static final int MATCH_MULTILINE = 0x0002; - - /** - * Consider all input a single body of text - newlines are matched by . - */ - public static final int MATCH_SINGLELINE = 0x0004; - - /************************************************ - * * - * The format of a node in a program is: * - * * - * [ OPCODE ] [ OPDATA ] [ OPNEXT ] [ OPERAND ] * - * * - * char OPCODE - instruction * - * char OPDATA - modifying data * - * char OPNEXT - next node (relative offset) * - * * - ************************************************/ - - // Opcode Char Opdata/Operand Meaning - // ---------- ---------- --------------- -------------------------------------------------- - static final char OP_END = 'E'; // end of program - static final char OP_BOL = '^'; // match only if at beginning of line - static final char OP_EOL = '$'; // match only if at end of line - static final char OP_ANY = '.'; // match any single character except newline - static final char OP_ANYOF = '['; // count/ranges match any char in the list of ranges - static final char OP_BRANCH = '|'; // node match this alternative or the next one - static final char OP_ATOM = 'A'; // length/string length of string followed by string itself - static final char OP_STAR = '*'; // node kleene closure - static final char OP_PLUS = '+'; // node positive closure - static final char OP_MAYBE = '?'; // node optional closure - static final char OP_ESCAPE = '\\'; // escape special escape code char class (escape is E_* code) - static final char OP_OPEN = '('; // number nth opening paren - static final char OP_OPEN_CLUSTER = '<'; // opening cluster - static final char OP_CLOSE = ')'; // number nth closing paren - static final char OP_CLOSE_CLUSTER = '>'; // closing cluster - static final char OP_BACKREF = '#'; // number reference nth already matched parenthesized string - static final char OP_GOTO = 'G'; // nothing but a (back-)pointer - static final char OP_NOTHING = 'N'; // match null string such as in '(a|)' - static final char OP_RELUCTANTSTAR = '8'; // none/expr reluctant '*' (mnemonic for char is unshifted '*') - static final char OP_RELUCTANTPLUS = '='; // none/expr reluctant '+' (mnemonic for char is unshifted '+') - static final char OP_RELUCTANTMAYBE = '/'; // none/expr reluctant '?' (mnemonic for char is unshifted '?') - static final char OP_POSIXCLASS = 'P'; // classid one of the posix character classes - - // Escape codes - static final char E_ALNUM = 'w'; // Alphanumeric - static final char E_NALNUM = 'W'; // Non-alphanumeric - static final char E_BOUND = 'b'; // Word boundary - static final char E_NBOUND = 'B'; // Non-word boundary - static final char E_SPACE = 's'; // Whitespace - static final char E_NSPACE = 'S'; // Non-whitespace - static final char E_DIGIT = 'd'; // Digit - static final char E_NDIGIT = 'D'; // Non-digit - - // Posix character classes - static final char POSIX_CLASS_ALNUM = 'w'; // Alphanumerics - static final char POSIX_CLASS_ALPHA = 'a'; // Alphabetics - static final char POSIX_CLASS_BLANK = 'b'; // Blanks - static final char POSIX_CLASS_CNTRL = 'c'; // Control characters - static final char POSIX_CLASS_DIGIT = 'd'; // Digits - static final char POSIX_CLASS_GRAPH = 'g'; // Graphic characters - static final char POSIX_CLASS_LOWER = 'l'; // Lowercase characters - static final char POSIX_CLASS_PRINT = 'p'; // Printable characters - static final char POSIX_CLASS_PUNCT = '!'; // Punctuation - static final char POSIX_CLASS_SPACE = 's'; // Spaces - static final char POSIX_CLASS_UPPER = 'u'; // Uppercase characters - static final char POSIX_CLASS_XDIGIT = 'x'; // Hexadecimal digits - static final char POSIX_CLASS_JSTART = 'j'; // Java identifier start - static final char POSIX_CLASS_JPART = 'k'; // Java identifier part - - // Limits - static final int maxNode = 65536; // Maximum number of nodes in a program - static final int MAX_PAREN = 16; // Number of paren pairs (only 9 can be backrefs) - - // Node layout constants - static final int offsetOpcode = 0; // Opcode offset (first character) - static final int offsetOpdata = 1; // Opdata offset (second char) - static final int offsetNext = 2; // Next index offset (third char) - static final int nodeSize = 3; // Node size (in chars) - - // State of current program - REProgram program; // Compiled regular expression 'program' - transient CharacterIterator search; // The string being matched against - int matchFlags; // Match behaviour flags - int maxParen = MAX_PAREN; - - // Parenthesized subexpressions - transient int parenCount; // Number of subexpressions matched (num open parens + 1) - transient int start0; // Cache of start[0] - transient int end0; // Cache of start[0] - transient int start1; // Cache of start[1] - transient int end1; // Cache of start[1] - transient int start2; // Cache of start[2] - transient int end2; // Cache of start[2] - transient int[] startn; // Lazy-alloced array of sub-expression starts - transient int[] endn; // Lazy-alloced array of sub-expression ends - - // Backreferences - transient int[] startBackref; // Lazy-alloced array of backref starts - transient int[] endBackref; // Lazy-alloced array of backref ends - - /** - * Constructs a regular expression matcher from a String by compiling it - * using a new instance of RECompiler. If you will be compiling many - * expressions, you may prefer to use a single RECompiler object instead. - * - * @param pattern The regular expression pattern to compile. - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - * @see RECompiler - * @see recompile - */ - public RE(String pattern) throws RESyntaxException - { - this(pattern, MATCH_NORMAL); - } - - /** - * Constructs a regular expression matcher from a String by compiling it - * using a new instance of RECompiler. If you will be compiling many - * expressions, you may prefer to use a single RECompiler object instead. - * - * @param pattern The regular expression pattern to compile. - * @param matchFlags The matching style - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - * @see RECompiler - * @see recompile - */ - public RE(String pattern, int matchFlags) throws RESyntaxException - { - this(new RECompiler().compile(pattern)); - setMatchFlags(matchFlags); - } - - /** - * Construct a matcher for a pre-compiled regular expression from program - * (bytecode) data. Permits special flags to be passed in to modify matching - * behaviour. - * - * @param program Compiled regular expression program (see RECompiler and/or recompile) - * @param matchFlags One or more of the RE match behaviour flags (RE.MATCH_*): - * - * <pre> - * MATCH_NORMAL // Normal (case-sensitive) matching - * MATCH_CASEINDEPENDENT // Case folded comparisons - * MATCH_MULTILINE // Newline matches as BOL/EOL - * </pre> - * - * @see RECompiler - * @see REProgram - * @see recompile - */ - public RE(REProgram program, int matchFlags) - { - setProgram(program); - setMatchFlags(matchFlags); - } - - /** - * Construct a matcher for a pre-compiled regular expression from program - * (bytecode) data. - * - * @param program Compiled regular expression program - * @see RECompiler - * @see recompile - */ - public RE(REProgram program) - { - this(program, MATCH_NORMAL); - } - - /** - * Constructs a regular expression matcher with no initial program. - * This is likely to be an uncommon practice, but is still supported. - */ - public RE() - { - this((REProgram)null, MATCH_NORMAL); - } - - /** - * Converts a 'simplified' regular expression to a full regular expression - * - * @param pattern The pattern to convert - * @return The full regular expression - */ - public static String simplePatternToFullRegularExpression(String pattern) - { - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < pattern.length(); i++) - { - char c = pattern.charAt(i); - switch (c) - { - case '*': - buf.append(".*"); - break; - - case '.': - case '[': - case ']': - case '\\': - case '+': - case '?': - case '{': - case '}': - case '$': - case '^': - case '|': - case '(': - case ')': - buf.append('\\'); - default: - buf.append(c); - break; - } - } - return buf.toString(); - } - - /** - * Sets match behaviour flags which alter the way RE does matching. - * @param matchFlags One or more of the RE match behaviour flags (RE.MATCH_*): - * - * <pre> - * MATCH_NORMAL // Normal (case-sensitive) matching - * MATCH_CASEINDEPENDENT // Case folded comparisons - * MATCH_MULTILINE // Newline matches as BOL/EOL - * </pre> - */ - public void setMatchFlags(int matchFlags) - { - this.matchFlags = matchFlags; - } - - /** - * Returns the current match behaviour flags. - * @return Current match behaviour flags (RE.MATCH_*). - * - * <pre> - * MATCH_NORMAL // Normal (case-sensitive) matching - * MATCH_CASEINDEPENDENT // Case folded comparisons - * MATCH_MULTILINE // Newline matches as BOL/EOL - * </pre> - * - * @see #setMatchFlags - */ - public int getMatchFlags() - { - return matchFlags; - } - - /** - * Sets the current regular expression program used by this matcher object. - * - * @param program Regular expression program compiled by RECompiler. - * @see RECompiler - * @see REProgram - * @see recompile - */ - public void setProgram(REProgram program) - { - this.program = program; - if (program != null && program.maxParens != -1) { - this.maxParen = program.maxParens; - } else { - this.maxParen = MAX_PAREN; - } - } - - /** - * Returns the current regular expression program in use by this matcher object. - * - * @return Regular expression program - * @see #setProgram - */ - public REProgram getProgram() - { - return program; - } - - /** - * Returns the number of parenthesized subexpressions available after a successful match. - * - * @return Number of available parenthesized subexpressions - */ - public int getParenCount() - { - return parenCount; - } - - /** - * Gets the contents of a parenthesized subexpression after a successful match. - * - * @param which Nesting level of subexpression - * @return String - */ - public String getParen(int which) - { - int start; - if (which < parenCount && (start = getParenStart(which)) >= 0) - { - return search.substring(start, getParenEnd(which)); - } - return null; - } - - /** - * Returns the start index of a given paren level. - * - * @param which Nesting level of subexpression - * @return String index - */ - public final int getParenStart(int which) - { - if (which < parenCount) - { - switch (which) - { - case 0: - return start0; - - case 1: - return start1; - - case 2: - return start2; - - default: - if (startn == null) - { - allocParens(); - } - return startn[which]; - } - } - return -1; - } - - /** - * Returns the end index of a given paren level. - * - * @param which Nesting level of subexpression - * @return String index - */ - public final int getParenEnd(int which) - { - if (which < parenCount) - { - switch (which) - { - case 0: - return end0; - - case 1: - return end1; - - case 2: - return end2; - - default: - if (endn == null) - { - allocParens(); - } - return endn[which]; - } - } - return -1; - } - - /** - * Returns the length of a given paren level. - * - * @param which Nesting level of subexpression - * @return Number of characters in the parenthesized subexpression - */ - public final int getParenLength(int which) - { - if (which < parenCount) - { - return getParenEnd(which) - getParenStart(which); - } - return -1; - } - - /** - * Sets the start of a paren level - * - * @param which Which paren level - * @param i Index in input array - */ - protected final void setParenStart(int which, int i) - { - if (which < parenCount) - { - switch (which) - { - case 0: - start0 = i; - break; - - case 1: - start1 = i; - break; - - case 2: - start2 = i; - break; - - default: - if (startn == null) - { - allocParens(); - } - startn[which] = i; - break; - } - } - } - - /** - * Sets the end of a paren level - * - * @param which Which paren level - * @param i Index in input array - */ - protected final void setParenEnd(int which, int i) - { - if (which < parenCount) - { - switch (which) - { - case 0: - end0 = i; - break; - - case 1: - end1 = i; - break; - - case 2: - end2 = i; - break; - - default: - if (endn == null) - { - allocParens(); - } - endn[which] = i; - break; - } - } - } - - /** - * Throws an Error representing an internal error condition probably resulting - * from a bug in the regular expression compiler (or possibly data corruption). - * In practice, this should be very rare. - * - * @param s Error description - */ - protected void internalError(String s) throws Error - { - throw new Error("RE internal error: " + s); - } - - /** - * Performs lazy allocation of subexpression arrays - */ - private final void allocParens() - { - // Allocate arrays for subexpressions - startn = new int[maxParen]; - endn = new int[maxParen]; - - // Set sub-expression pointers to invalid values - for (int i = 0; i < maxParen; i++) - { - startn[i] = -1; - endn[i] = -1; - } - } - - /** - * Try to match a string against a subset of nodes in the program - * - * @param firstNode Node to start at in program - * @param lastNode Last valid node (used for matching a subexpression without - * matching the rest of the program as well). - * @param idxStart Starting position in character array - * @return Final input array index if match succeeded. -1 if not. - */ - protected int matchNodes(int firstNode, int lastNode, int idxStart) - { - // Our current place in the string - int idx = idxStart; - - // Loop while node is valid - int next, opcode, opdata; - int idxNew; - char[] instruction = program.instruction; - for (int node = firstNode; node < lastNode; ) - { - opcode = instruction[node + offsetOpcode]; - next = node + (short)instruction[node + offsetNext]; - opdata = instruction[node + offsetOpdata]; - - switch (opcode) - { - case OP_RELUCTANTMAYBE: - { - int once = 0; - do - { - // Try to match the rest without using the reluctant subexpr - if ((idxNew = matchNodes(next, maxNode, idx)) != -1) - { - return idxNew; - } - } - while ((once++ == 0) && (idx = matchNodes(node + nodeSize, next, idx)) != -1); - return -1; - } - - case OP_RELUCTANTPLUS: - while ((idx = matchNodes(node + nodeSize, next, idx)) != -1) - { - // Try to match the rest without using the reluctant subexpr - if ((idxNew = matchNodes(next, maxNode, idx)) != -1) - { - return idxNew; - } - } - return -1; - - case OP_RELUCTANTSTAR: - do - { - // Try to match the rest without using the reluctant subexpr - if ((idxNew = matchNodes(next, maxNode, idx)) != -1) - { - return idxNew; - } - } - while ((idx = matchNodes(node + nodeSize, next, idx)) != -1); - return -1; - - case OP_OPEN: - - // Match subexpression - if ((program.flags & REProgram.OPT_HASBACKREFS) != 0) - { - startBackref[opdata] = idx; - } - if ((idxNew = matchNodes(next, maxNode, idx)) != -1) - { - // Increase valid paren count - if ((opdata + 1) > parenCount) - { - parenCount = opdata + 1; - } - - // Don't set paren if already set later on - if (getParenStart(opdata) == -1) - { - setParenStart(opdata, idx); - } - } - return idxNew; - - case OP_CLOSE: - - // Done matching subexpression - if ((program.flags & REProgram.OPT_HASBACKREFS) != 0) - { - endBackref[opdata] = idx; - } - if ((idxNew = matchNodes(next, maxNode, idx)) != -1) - { - // Increase valid paren count - if ((opdata + 1) > parenCount) - { - parenCount = opdata + 1; - } - - // Don't set paren if already set later on - if (getParenEnd(opdata) == -1) - { - setParenEnd(opdata, idx); - } - } - return idxNew; - - case OP_OPEN_CLUSTER: - case OP_CLOSE_CLUSTER: - // starting or ending the matching of a subexpression which has no backref. - return matchNodes( next, maxNode, idx ); - - case OP_BACKREF: - { - // Get the start and end of the backref - int s = startBackref[opdata]; - int e = endBackref[opdata]; - - // We don't know the backref yet - if (s == -1 || e == -1) - { - return -1; - } - - // The backref is empty size - if (s == e) - { - break; - } - - // Get the length of the backref - int l = e - s; - - // If there's not enough input left, give up. - if (search.isEnd(idx + l - 1)) - { - return -1; - } - - // Case fold the backref? - final boolean caseFold = - ((matchFlags & MATCH_CASEINDEPENDENT) != 0); - // Compare backref to input - for (int i = 0; i < l; i++) - { - if (compareChars(search.charAt(idx++), search.charAt(s + i), caseFold) != 0) - { - return -1; - } - } - } - break; - - case OP_BOL: - - // Fail if we're not at the start of the string - if (idx != 0) - { - // If we're multiline matching, we could still be at the start of a line - if ((matchFlags & MATCH_MULTILINE) == MATCH_MULTILINE) - { - // If not at start of line, give up - if (idx <= 0 || !isNewline(idx - 1)) { - return -1; - } else { - break; - } - } - return -1; - } - break; - - case OP_EOL: - - // If we're not at the end of string - if (!search.isEnd(0) && !search.isEnd(idx)) - { - // If we're multi-line matching - if ((matchFlags & MATCH_MULTILINE) == MATCH_MULTILINE) - { - // Give up if we're not at the end of a line - if (!isNewline(idx)) { - return -1; - } else { - break; - } - } - return -1; - } - break; - - case OP_ESCAPE: - - // Which escape? - switch (opdata) - { - // Word boundary match - case E_NBOUND: - case E_BOUND: - { - char cLast = ((idx == 0) ? '\n' : search.charAt(idx - 1)); - char cNext = ((search.isEnd(idx)) ? '\n' : search.charAt(idx)); - if ((Character.isLetterOrDigit(cLast) == Character.isLetterOrDigit(cNext)) == (opdata == E_BOUND)) - { - return -1; - } - } - break; - - // Alpha-numeric, digit, space, javaLetter, javaLetterOrDigit - case E_ALNUM: - case E_NALNUM: - case E_DIGIT: - case E_NDIGIT: - case E_SPACE: - case E_NSPACE: - - // Give up if out of input - if (search.isEnd(idx)) - { - return -1; - } - - char c = search.charAt(idx); - - // Switch on escape - switch (opdata) - { - case E_ALNUM: - case E_NALNUM: - if (!((Character.isLetterOrDigit(c) || c == '_') == (opdata == E_ALNUM))) - { - return -1; - } - break; - - case E_DIGIT: - case E_NDIGIT: - if (!(Character.isDigit(c) == (opdata == E_DIGIT))) - { - return -1; - } - break; - - case E_SPACE: - case E_NSPACE: - if (!(Character.isWhitespace(c) == (opdata == E_SPACE))) - { - return -1; - } - break; - } - idx++; - break; - - default: - internalError("Unrecognized escape '" + opdata + "'"); - } - break; - - case OP_ANY: - - if ((matchFlags & MATCH_SINGLELINE) == MATCH_SINGLELINE) { - // Match anything - if (search.isEnd(idx)) - { - return -1; - } - } - else - { - // Match anything but a newline - if (search.isEnd(idx) || isNewline(idx)) - { - return -1; - } - } - idx++; - break; - - case OP_ATOM: - { - // Match an atom value - if (search.isEnd(idx)) - { - return -1; - } - - // Get length of atom and starting index - int lenAtom = opdata; - int startAtom = node + nodeSize; - - // Give up if not enough input remains to have a match - if (search.isEnd(lenAtom + idx - 1)) - { - return -1; - } - - // Match atom differently depending on casefolding flag - final boolean caseFold = - ((matchFlags & MATCH_CASEINDEPENDENT) != 0); - - for (int i = 0; i < lenAtom; i++) - { - if (compareChars(search.charAt(idx++), instruction[startAtom + i], caseFold) != 0) - { - return -1; - } - } - } - break; - - case OP_POSIXCLASS: - { - // Out of input? - if (search.isEnd(idx)) - { - return -1; - } - - switch (opdata) - { - case POSIX_CLASS_ALNUM: - if (!Character.isLetterOrDigit(search.charAt(idx))) - { - return -1; - } - break; - - case POSIX_CLASS_ALPHA: - if (!Character.isLetter(search.charAt(idx))) - { - return -1; - } - break; - - case POSIX_CLASS_DIGIT: - if (!Character.isDigit(search.charAt(idx))) - { - return -1; - } - break; - - case POSIX_CLASS_BLANK: // JWL - bugbug: is this right?? - if (!Character.isSpaceChar(search.charAt(idx))) - { - return -1; - } - break; - - case POSIX_CLASS_SPACE: - if (!Character.isWhitespace(search.charAt(idx))) - { - return -1; - } - break; - - case POSIX_CLASS_CNTRL: - if (Character.getType(search.charAt(idx)) != Character.CONTROL) - { - return -1; - } - break; - - case POSIX_CLASS_GRAPH: // JWL - bugbug??? - switch (Character.getType(search.charAt(idx))) - { - case Character.MATH_SYMBOL: - case Character.CURRENCY_SYMBOL: - case Character.MODIFIER_SYMBOL: - case Character.OTHER_SYMBOL: - break; - - default: - return -1; - } - break; - - case POSIX_CLASS_LOWER: - if (Character.getType(search.charAt(idx)) != Character.LOWERCASE_LETTER) - { - return -1; - } - break; - - case POSIX_CLASS_UPPER: - if (Character.getType(search.charAt(idx)) != Character.UPPERCASE_LETTER) - { - return -1; - } - break; - - case POSIX_CLASS_PRINT: - if (Character.getType(search.charAt(idx)) == Character.CONTROL) - { - return -1; - } - break; - - case POSIX_CLASS_PUNCT: - { - int type = Character.getType(search.charAt(idx)); - switch(type) - { - case Character.DASH_PUNCTUATION: - case Character.START_PUNCTUATION: - case Character.END_PUNCTUATION: - case Character.CONNECTOR_PUNCTUATION: - case Character.OTHER_PUNCTUATION: - break; - - default: - return -1; - } - } - break; - - case POSIX_CLASS_XDIGIT: // JWL - bugbug?? - { - boolean isXDigit = ((search.charAt(idx) >= '0' && search.charAt(idx) <= '9') || - (search.charAt(idx) >= 'a' && search.charAt(idx) <= 'f') || - (search.charAt(idx) >= 'A' && search.charAt(idx) <= 'F')); - if (!isXDigit) - { - return -1; - } - } - break; - - case POSIX_CLASS_JSTART: - if (!Character.isJavaIdentifierStart(search.charAt(idx))) - { - return -1; - } - break; - - case POSIX_CLASS_JPART: - if (!Character.isJavaIdentifierPart(search.charAt(idx))) - { - return -1; - } - break; - - default: - internalError("Bad posix class"); - break; - } - - // Matched. - idx++; - } - break; - - case OP_ANYOF: - { - // Out of input? - if (search.isEnd(idx)) - { - return -1; - } - - // Get character to match against character class and maybe casefold - char c = search.charAt(idx); - boolean caseFold = (matchFlags & MATCH_CASEINDEPENDENT) != 0; - // Loop through character class checking our match character - int idxRange = node + nodeSize; - int idxEnd = idxRange + (opdata * 2); - boolean match = false; - for (int i = idxRange; !match && i < idxEnd; ) - { - // Get start, end and match characters - char s = instruction[i++]; - char e = instruction[i++]; - - match = ((compareChars(c, s, caseFold) >= 0) - && (compareChars(c, e, caseFold) <= 0)); - } - - // Fail if we didn't match the character class - if (!match) - { - return -1; - } - idx++; - } - break; - - case OP_BRANCH: - { - // Check for choices - if (instruction[next + offsetOpcode] != OP_BRANCH) - { - // If there aren't any other choices, just evaluate this branch. - node += nodeSize; - continue; - } - - // Try all available branches - short nextBranch; - do - { - // Try matching the branch against the string - if ((idxNew = matchNodes(node + nodeSize, maxNode, idx)) != -1) - { - return idxNew; - } - - // Go to next branch (if any) - nextBranch = (short)instruction[node + offsetNext]; - node += nextBranch; - } - while (nextBranch != 0 && (instruction[node + offsetOpcode] == OP_BRANCH)); - - // Failed to match any branch! - return -1; - } - - case OP_NOTHING: - case OP_GOTO: - - // Just advance to the next node without doing anything - break; - - case OP_END: - - // Match has succeeded! - setParenEnd(0, idx); - return idx; - - default: - - // Corrupt program - internalError("Invalid opcode '" + opcode + "'"); - } - - // Advance to the next node in the program - node = next; - } - - // We "should" never end up here - internalError("Corrupt program"); - return -1; - } - - /** - * Match the current regular expression program against the current - * input string, starting at index i of the input string. This method - * is only meant for internal use. - * - * @param i The input string index to start matching at - * @return True if the input matched the expression - */ - protected boolean matchAt(int i) - { - // Initialize start pointer, paren cache and paren count - start0 = -1; - end0 = -1; - start1 = -1; - end1 = -1; - start2 = -1; - end2 = -1; - startn = null; - endn = null; - parenCount = 1; - setParenStart(0, i); - - // Allocate backref arrays (unless optimizations indicate otherwise) - if ((program.flags & REProgram.OPT_HASBACKREFS) != 0) - { - startBackref = new int[maxParen]; - endBackref = new int[maxParen]; - } - - // Match against string - int idx; - if ((idx = matchNodes(0, maxNode, i)) != -1) - { - setParenEnd(0, idx); - return true; - } - - // Didn't match - parenCount = 0; - return false; - } - - /** - * Matches the current regular expression program against a character array, - * starting at a given index. - * - * @param search String to match against - * @param i Index to start searching at - * @return True if string matched - */ - public boolean match(String search, int i) - { - return match(new StringCharacterIterator(search), i); - } - - /** - * Matches the current regular expression program against a character array, - * starting at a given index. - * - * @param search String to match against - * @param i Index to start searching at - * @return True if string matched - */ - public boolean match(CharacterIterator search, int i) - { - // There is no compiled program to search with! - if (program == null) - { - // This should be uncommon enough to be an error case rather - // than an exception (which would have to be handled everywhere) - internalError("No RE program to run!"); - } - - // Save string to search - this.search = search; - - // Can we optimize the search by looking for a prefix string? - if (program.prefix == null) - { - // Unprefixed matching must try for a match at each character - for ( ;! search.isEnd(i - 1); i++) - { - // Try a match at index i - if (matchAt(i)) - { - return true; - } - } - return false; - } - else - { - // Prefix-anchored matching is possible - boolean caseIndependent = (matchFlags & MATCH_CASEINDEPENDENT) != 0; - char[] prefix = program.prefix; - for ( ; !search.isEnd(i + prefix.length - 1); i++) - { - int j = i; - int k = 0; - - boolean match; - do { - // If there's a mismatch of any character in the prefix, give up - match = (compareChars(search.charAt(j++), prefix[k++], caseIndependent) == 0); - } while (match && k < prefix.length); - - // See if the whole prefix string matched - if (k == prefix.length) - { - // We matched the full prefix at firstChar, so try it - if (matchAt(i)) - { - return true; - } - } - } - return false; - } - } - - /** - * Matches the current regular expression program against a String. - * - * @param search String to match against - * @return True if string matched - */ - public boolean match(String search) - { - return match(search, 0); - } - - /** - * Splits a string into an array of strings on regular expression boundaries. - * This function works the same way as the Perl function of the same name. - * Given a regular expression of "[ab]+" and a string to split of - * "xyzzyababbayyzabbbab123", the result would be the array of Strings - * "[xyzzy, yyz, 123]". - * - * <p>Please note that the first string in the resulting array may be an empty - * string. This happens when the very first character of input string is - * matched by the pattern. - * - * @param s String to split on this regular exression - * @return Array of strings - */ - public String[] split(String s) - { - // Create new vector - Vector v = new Vector(); - - // Start at position 0 and search the whole string - int pos = 0; - int len = s.length(); - - // Try a match at each position - while (pos < len && match(s, pos)) - { - // Get start of match - int start = getParenStart(0); - - // Get end of match - int newpos = getParenEnd(0); - - // Check if no progress was made - if (newpos == pos) - { - v.addElement(s.substring(pos, start + 1)); - newpos++; - } - else - { - v.addElement(s.substring(pos, start)); - } - - // Move to new position - pos = newpos; - } - - // Push remainder if it's not empty - String remainder = s.substring(pos); - if (remainder.length() != 0) - { - v.addElement(remainder); - } - - // Return vector as an array of strings - String[] ret = new String[v.size()]; - v.copyInto(ret); - return ret; - } - - /** - * Flag bit that indicates that subst should replace all occurrences of this - * regular expression. - */ - public static final int REPLACE_ALL = 0x0000; - - /** - * Flag bit that indicates that subst should only replace the first occurrence - * of this regular expression. - */ - public static final int REPLACE_FIRSTONLY = 0x0001; - - /** - * Flag bit that indicates that subst should replace backreferences - */ - public static final int REPLACE_BACKREFERENCES = 0x0002; - - /** - * Substitutes a string for this regular expression in another string. - * This method works like the Perl function of the same name. - * Given a regular expression of "a*b", a String to substituteIn of - * "aaaabfooaaabgarplyaaabwackyb" and the substitution String "-", the - * resulting String returned by subst would be "-foo-garply-wacky-". - * - * @param substituteIn String to substitute within - * @param substitution String to substitute for all matches of this regular expression. - * @return The string substituteIn with zero or more occurrences of the current - * regular expression replaced with the substitution String (if this regular - * expression object doesn't match at any position, the original String is returned - * unchanged). - */ - public String subst(String substituteIn, String substitution) - { - return subst(substituteIn, substitution, REPLACE_ALL); - } - - /** - * Substitutes a string for this regular expression in another string. - * This method works like the Perl function of the same name. - * Given a regular expression of "a*b", a String to substituteIn of - * "aaaabfooaaabgarplyaaabwackyb" and the substitution String "-", the - * resulting String returned by subst would be "-foo-garply-wacky-". - * <p> - * It is also possible to reference the contents of a parenthesized expression - * with $0, $1, ... $9. A regular expression of "http://[\\.\\w\\-\\?/~_@&=%]+", - * a String to substituteIn of "visit us: http://www.apache.org!" and the - * substitution String "<a href=\"$0\">$0</a>", the resulting String - * returned by subst would be - * "visit us: <a href=\"http://www.apache.org\">http://www.apache.org</a>!". - * <p> - * <i>Note:</i> $0 represents the whole match. - * - * @param substituteIn String to substitute within - * @param substitution String to substitute for matches of this regular expression - * @param flags One or more bitwise flags from REPLACE_*. If the REPLACE_FIRSTONLY - * flag bit is set, only the first occurrence of this regular expression is replaced. - * If the bit is not set (REPLACE_ALL), all occurrences of this pattern will be - * replaced. If the flag REPLACE_BACKREFERENCES is set, all backreferences will - * be processed. - * @return The string substituteIn with zero or more occurrences of the current - * regular expression replaced with the substitution String (if this regular - * expression object doesn't match at any position, the original String is returned - * unchanged). - */ - public String subst(String substituteIn, String substitution, int flags) - { - // String to return - StringBuffer ret = new StringBuffer(); - - // Start at position 0 and search the whole string - int pos = 0; - int len = substituteIn.length(); - - // Try a match at each position - while (pos < len && match(substituteIn, pos)) - { - // Append string before match - ret.append(substituteIn.substring(pos, getParenStart(0))); - - if ((flags & REPLACE_BACKREFERENCES) != 0) - { - // Process backreferences - int lCurrentPosition = 0; - int lLastPosition = -2; - int lLength = substitution.length(); - boolean bAddedPrefix = false; - - while ((lCurrentPosition = substitution.indexOf("$", lCurrentPosition)) >= 0) - { - if ((lCurrentPosition == 0 || substitution.charAt(lCurrentPosition - 1) != '\\') - && lCurrentPosition+1 < lLength) - { - char c = substitution.charAt(lCurrentPosition + 1); - if (c >= '0' && c <= '9') - { - if (bAddedPrefix == false) - { - // Append everything between the beginning of the - // substitution string and the current $ sign - ret.append(substitution.substring(0, lCurrentPosition)); - bAddedPrefix = true; - } - else - { - // Append everything between the last and the current $ sign - ret.append(substitution.substring(lLastPosition + 2, lCurrentPosition)); - } - - // Append the parenthesized expression - // Note: if a parenthesized expression of the requested - // index is not available "null" is added to the string - ret.append(getParen(c - '0')); - lLastPosition = lCurrentPosition; - } - } - - // Move forward, skipping past match - lCurrentPosition++; - } - - // Append everything after the last $ sign - ret.append(substitution.substring(lLastPosition + 2, lLength)); - } - else - { - // Append substitution without processing backreferences - ret.append(substitution); - } - - // Move forward, skipping past match - int newpos = getParenEnd(0); - - // We always want to make progress! - if (newpos == pos) - { - newpos++; - } - - // Try new position - pos = newpos; - - // Break out if we're only supposed to replace one occurrence - if ((flags & REPLACE_FIRSTONLY) != 0) - { - break; - } - } - - // If there's remaining input, append it - if (pos < len) - { - ret.append(substituteIn.substring(pos)); - } - - // Return string buffer as string - return ret.toString(); - } - - /** - * Returns an array of Strings, whose toString representation matches a regular - * expression. This method works like the Perl function of the same name. Given - * a regular expression of "a*b" and an array of String objects of [foo, aab, zzz, - * aaaab], the array of Strings returned by grep would be [aab, aaaab]. - * - * @param search Array of Objects to search - * @return Array of Strings whose toString() value matches this regular expression. - */ - public String[] grep(Object[] search) - { - // Create new vector to hold return items - Vector v = new Vector(); - - // Traverse array of objects - for (int i = 0; i < search.length; i++) - { - // Get next object as a string - String s = search[i].toString(); - - // If it matches this regexp, add it to the list - if (match(s)) - { - v.addElement(s); - } - } - - // Return vector as an array of strings - String[] ret = new String[v.size()]; - v.copyInto(ret); - return ret; - } - - /** - * @return true if character at i-th position in the <code>search</code> string is a newline - */ - private boolean isNewline(int i) - { - char nextChar = search.charAt(i); - - if (nextChar == '\n' || nextChar == '\r' || nextChar == '\u0085' - || nextChar == '\u2028' || nextChar == '\u2029') - { - return true; - } - - return false; - } - - /** - * Compares two characters. - * - * @param c1 first character to compare. - * @param c2 second character to compare. - * @param caseIndependent whether comparision is case insensitive or not. - * @return negative, 0, or positive integer as the first character - * less than, equal to, or greater then the second. - */ - private int compareChars(char c1, char c2, boolean caseIndependent) - { - if (caseIndependent) - { - c1 = Character.toLowerCase(c1); - c2 = Character.toLowerCase(c2); - } - return ((int)c1 - (int)c2); - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RECompiler.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RECompiler.java deleted file mode 100644 index 23874ee8da0..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RECompiler.java +++ /dev/null @@ -1,1520 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -import com.sun.org.apache.regexp.internal.RE; -import java.util.Hashtable; - -/** - * A regular expression compiler class. This class compiles a pattern string into a - * regular expression program interpretable by the RE evaluator class. The 'recompile' - * command line tool uses this compiler to pre-compile regular expressions for use - * with RE. For a description of the syntax accepted by RECompiler and what you can - * do with regular expressions, see the documentation for the RE matcher class. - * - * @see RE - * @see recompile - * - * @author <a href="mailto:jonl@muppetlabs.com">Jonathan Locke</a> - * @author <a href="mailto:gholam@xtra.co.nz">Michael McCallum</a> - */ -public class RECompiler -{ - // The compiled program - char[] instruction; // The compiled RE 'program' instruction buffer - int lenInstruction; // The amount of the program buffer currently in use - - // Input state for compiling regular expression - String pattern; // Input string - int len; // Length of the pattern string - int idx; // Current input index into ac - int parens; // Total number of paren pairs - - // Node flags - static final int NODE_NORMAL = 0; // No flags (nothing special) - static final int NODE_NULLABLE = 1; // True if node is potentially null - static final int NODE_TOPLEVEL = 2; // True if top level expr - - // Special types of 'escapes' - static final int ESC_MASK = 0xffff0; // Escape complexity mask - static final int ESC_BACKREF = 0xfffff; // Escape is really a backreference - static final int ESC_COMPLEX = 0xffffe; // Escape isn't really a true character - static final int ESC_CLASS = 0xffffd; // Escape represents a whole class of characters - - // {m,n} stacks - int maxBrackets = 10; // Maximum number of bracket pairs - static final int bracketUnbounded = -1; // Unbounded value - int brackets = 0; // Number of bracket sets - int[] bracketStart = null; // Starting point - int[] bracketEnd = null; // Ending point - int[] bracketMin = null; // Minimum number of matches - int[] bracketOpt = null; // Additional optional matches - - // Lookup table for POSIX character class names - static Hashtable hashPOSIX = new Hashtable(); - static - { - hashPOSIX.put("alnum", new Character(RE.POSIX_CLASS_ALNUM)); - hashPOSIX.put("alpha", new Character(RE.POSIX_CLASS_ALPHA)); - hashPOSIX.put("blank", new Character(RE.POSIX_CLASS_BLANK)); - hashPOSIX.put("cntrl", new Character(RE.POSIX_CLASS_CNTRL)); - hashPOSIX.put("digit", new Character(RE.POSIX_CLASS_DIGIT)); - hashPOSIX.put("graph", new Character(RE.POSIX_CLASS_GRAPH)); - hashPOSIX.put("lower", new Character(RE.POSIX_CLASS_LOWER)); - hashPOSIX.put("print", new Character(RE.POSIX_CLASS_PRINT)); - hashPOSIX.put("punct", new Character(RE.POSIX_CLASS_PUNCT)); - hashPOSIX.put("space", new Character(RE.POSIX_CLASS_SPACE)); - hashPOSIX.put("upper", new Character(RE.POSIX_CLASS_UPPER)); - hashPOSIX.put("xdigit", new Character(RE.POSIX_CLASS_XDIGIT)); - hashPOSIX.put("javastart", new Character(RE.POSIX_CLASS_JSTART)); - hashPOSIX.put("javapart", new Character(RE.POSIX_CLASS_JPART)); - } - - /** - * Constructor. Creates (initially empty) storage for a regular expression program. - */ - public RECompiler() - { - // Start off with a generous, yet reasonable, initial size - instruction = new char[128]; - lenInstruction = 0; - } - - /** - * Ensures that n more characters can fit in the program buffer. - * If n more can't fit, then the size is doubled until it can. - * @param n Number of additional characters to ensure will fit. - */ - void ensure(int n) - { - // Get current program length - int curlen = instruction.length; - - // If the current length + n more is too much - if (lenInstruction + n >= curlen) - { - // Double the size of the program array until n more will fit - while (lenInstruction + n >= curlen) - { - curlen *= 2; - } - - // Allocate new program array and move data into it - char[] newInstruction = new char[curlen]; - System.arraycopy(instruction, 0, newInstruction, 0, lenInstruction); - instruction = newInstruction; - } - } - - /** - * Emit a single character into the program stream. - * @param c Character to add - */ - void emit(char c) - { - // Make room for character - ensure(1); - - // Add character - instruction[lenInstruction++] = c; - } - - /** - * Inserts a node with a given opcode and opdata at insertAt. The node relative next - * pointer is initialized to 0. - * @param opcode Opcode for new node - * @param opdata Opdata for new node (only the low 16 bits are currently used) - * @param insertAt Index at which to insert the new node in the program - */ - void nodeInsert(char opcode, int opdata, int insertAt) - { - // Make room for a new node - ensure(RE.nodeSize); - - // Move everything from insertAt to the end down nodeSize elements - System.arraycopy(instruction, insertAt, instruction, insertAt + RE.nodeSize, lenInstruction - insertAt); - instruction[insertAt + RE.offsetOpcode] = opcode; - instruction[insertAt + RE.offsetOpdata] = (char)opdata; - instruction[insertAt + RE.offsetNext] = 0; - lenInstruction += RE.nodeSize; - } - - /** - * Appends a node to the end of a node chain - * @param node Start of node chain to traverse - * @param pointTo Node to have the tail of the chain point to - */ - void setNextOfEnd(int node, int pointTo) - { - // Traverse the chain until the next offset is 0 - int next = instruction[node + RE.offsetNext]; - // while the 'node' is not the last in the chain - // and the 'node' is not the last in the program. - while ( next != 0 && node < lenInstruction ) - { - // if the node we are supposed to point to is in the chain then - // point to the end of the program instead. - // Michael McCallum <gholam@xtra.co.nz> - // FIXME: // This is a _hack_ to stop infinite programs. - // I believe that the implementation of the reluctant matches is wrong but - // have not worked out a better way yet. - if ( node == pointTo ) { - pointTo = lenInstruction; - } - node += next; - next = instruction[node + RE.offsetNext]; - } - // if we have reached the end of the program then dont set the pointTo. - // im not sure if this will break any thing but passes all the tests. - if ( node < lenInstruction ) { - // Point the last node in the chain to pointTo. - instruction[node + RE.offsetNext] = (char)(short)(pointTo - node); - } - } - - /** - * Adds a new node - * @param opcode Opcode for node - * @param opdata Opdata for node (only the low 16 bits are currently used) - * @return Index of new node in program - */ - int node(char opcode, int opdata) - { - // Make room for a new node - ensure(RE.nodeSize); - - // Add new node at end - instruction[lenInstruction + RE.offsetOpcode] = opcode; - instruction[lenInstruction + RE.offsetOpdata] = (char)opdata; - instruction[lenInstruction + RE.offsetNext] = 0; - lenInstruction += RE.nodeSize; - - // Return index of new node - return lenInstruction - RE.nodeSize; - } - - - /** - * Throws a new internal error exception - * @exception Error Thrown in the event of an internal error. - */ - void internalError() throws Error - { - throw new Error("Internal error!"); - } - - /** - * Throws a new syntax error exception - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - */ - void syntaxError(String s) throws RESyntaxException - { - throw new RESyntaxException(s); - } - - /** - * Allocate storage for brackets only as needed - */ - void allocBrackets() - { - // Allocate bracket stacks if not already done - if (bracketStart == null) - { - // Allocate storage - bracketStart = new int[maxBrackets]; - bracketEnd = new int[maxBrackets]; - bracketMin = new int[maxBrackets]; - bracketOpt = new int[maxBrackets]; - - // Initialize to invalid values - for (int i = 0; i < maxBrackets; i++) - { - bracketStart[i] = bracketEnd[i] = bracketMin[i] = bracketOpt[i] = -1; - } - } - } - - /** Enlarge storage for brackets only as needed. */ - synchronized void reallocBrackets() { - // trick the tricky - if (bracketStart == null) { - allocBrackets(); - } - - int new_size = maxBrackets * 2; - int[] new_bS = new int[new_size]; - int[] new_bE = new int[new_size]; - int[] new_bM = new int[new_size]; - int[] new_bO = new int[new_size]; - // Initialize to invalid values - for (int i=brackets; i<new_size; i++) { - new_bS[i] = new_bE[i] = new_bM[i] = new_bO[i] = -1; - } - System.arraycopy(bracketStart,0, new_bS,0, brackets); - System.arraycopy(bracketEnd,0, new_bE,0, brackets); - System.arraycopy(bracketMin,0, new_bM,0, brackets); - System.arraycopy(bracketOpt,0, new_bO,0, brackets); - bracketStart = new_bS; - bracketEnd = new_bE; - bracketMin = new_bM; - bracketOpt = new_bO; - maxBrackets = new_size; - } - - /** - * Match bracket {m,n} expression put results in bracket member variables - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - */ - void bracket() throws RESyntaxException - { - // Current character must be a '{' - if (idx >= len || pattern.charAt(idx++) != '{') - { - internalError(); - } - - // Next char must be a digit - if (idx >= len || !Character.isDigit(pattern.charAt(idx))) - { - syntaxError("Expected digit"); - } - - // Get min ('m' of {m,n}) number - StringBuffer number = new StringBuffer(); - while (idx < len && Character.isDigit(pattern.charAt(idx))) - { - number.append(pattern.charAt(idx++)); - } - try - { - bracketMin[brackets] = Integer.parseInt(number.toString()); - } - catch (NumberFormatException e) - { - syntaxError("Expected valid number"); - } - - // If out of input, fail - if (idx >= len) - { - syntaxError("Expected comma or right bracket"); - } - - // If end of expr, optional limit is 0 - if (pattern.charAt(idx) == '}') - { - idx++; - bracketOpt[brackets] = 0; - return; - } - - // Must have at least {m,} and maybe {m,n}. - if (idx >= len || pattern.charAt(idx++) != ',') - { - syntaxError("Expected comma"); - } - - // If out of input, fail - if (idx >= len) - { - syntaxError("Expected comma or right bracket"); - } - - // If {m,} max is unlimited - if (pattern.charAt(idx) == '}') - { - idx++; - bracketOpt[brackets] = bracketUnbounded; - return; - } - - // Next char must be a digit - if (idx >= len || !Character.isDigit(pattern.charAt(idx))) - { - syntaxError("Expected digit"); - } - - // Get max number - number.setLength(0); - while (idx < len && Character.isDigit(pattern.charAt(idx))) - { - number.append(pattern.charAt(idx++)); - } - try - { - bracketOpt[brackets] = Integer.parseInt(number.toString()) - bracketMin[brackets]; - } - catch (NumberFormatException e) - { - syntaxError("Expected valid number"); - } - - // Optional repetitions must be >= 0 - if (bracketOpt[brackets] < 0) - { - syntaxError("Bad range"); - } - - // Must have close brace - if (idx >= len || pattern.charAt(idx++) != '}') - { - syntaxError("Missing close brace"); - } - } - - /** - * Match an escape sequence. Handles quoted chars and octal escapes as well - * as normal escape characters. Always advances the input stream by the - * right amount. This code "understands" the subtle difference between an - * octal escape and a backref. You can access the type of ESC_CLASS or - * ESC_COMPLEX or ESC_BACKREF by looking at pattern[idx - 1]. - * @return ESC_* code or character if simple escape - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - */ - int escape() throws RESyntaxException - { - // "Shouldn't" happen - if (pattern.charAt(idx) != '\\') - { - internalError(); - } - - // Escape shouldn't occur as last character in string! - if (idx + 1 == len) - { - syntaxError("Escape terminates string"); - } - - // Switch on character after backslash - idx += 2; - char escapeChar = pattern.charAt(idx - 1); - switch (escapeChar) - { - case RE.E_BOUND: - case RE.E_NBOUND: - return ESC_COMPLEX; - - case RE.E_ALNUM: - case RE.E_NALNUM: - case RE.E_SPACE: - case RE.E_NSPACE: - case RE.E_DIGIT: - case RE.E_NDIGIT: - return ESC_CLASS; - - case 'u': - case 'x': - { - // Exact required hex digits for escape type - int hexDigits = (escapeChar == 'u' ? 4 : 2); - - // Parse up to hexDigits characters from input - int val = 0; - for ( ; idx < len && hexDigits-- > 0; idx++) - { - // Get char - char c = pattern.charAt(idx); - - // If it's a hexadecimal digit (0-9) - if (c >= '0' && c <= '9') - { - // Compute new value - val = (val << 4) + c - '0'; - } - else - { - // If it's a hexadecimal letter (a-f) - c = Character.toLowerCase(c); - if (c >= 'a' && c <= 'f') - { - // Compute new value - val = (val << 4) + (c - 'a') + 10; - } - else - { - // If it's not a valid digit or hex letter, the escape must be invalid - // because hexDigits of input have not been absorbed yet. - syntaxError("Expected " + hexDigits + " hexadecimal digits after \\" + escapeChar); - } - } - } - return val; - } - - case 't': - return '\t'; - - case 'n': - return '\n'; - - case 'r': - return '\r'; - - case 'f': - return '\f'; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - - // An octal escape starts with a 0 or has two digits in a row - if ((idx < len && Character.isDigit(pattern.charAt(idx))) || escapeChar == '0') - { - // Handle \nnn octal escapes - int val = escapeChar - '0'; - if (idx < len && Character.isDigit(pattern.charAt(idx))) - { - val = ((val << 3) + (pattern.charAt(idx++) - '0')); - if (idx < len && Character.isDigit(pattern.charAt(idx))) - { - val = ((val << 3) + (pattern.charAt(idx++) - '0')); - } - } - return val; - } - - // It's actually a backreference (\[1-9]), not an escape - return ESC_BACKREF; - - default: - - // Simple quoting of a character - return escapeChar; - } - } - - /** - * Compile a character class - * @return Index of class node - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - */ - int characterClass() throws RESyntaxException - { - // Check for bad calling or empty class - if (pattern.charAt(idx) != '[') - { - internalError(); - } - - // Check for unterminated or empty class - if ((idx + 1) >= len || pattern.charAt(++idx) == ']') - { - syntaxError("Empty or unterminated class"); - } - - // Check for POSIX character class - if (idx < len && pattern.charAt(idx) == ':') - { - // Skip colon - idx++; - - // POSIX character classes are denoted with lowercase ASCII strings - int idxStart = idx; - while (idx < len && pattern.charAt(idx) >= 'a' && pattern.charAt(idx) <= 'z') - { - idx++; - } - - // Should be a ":]" to terminate the POSIX character class - if ((idx + 1) < len && pattern.charAt(idx) == ':' && pattern.charAt(idx + 1) == ']') - { - // Get character class - String charClass = pattern.substring(idxStart, idx); - - // Select the POSIX class id - Character i = (Character)hashPOSIX.get(charClass); - if (i != null) - { - // Move past colon and right bracket - idx += 2; - - // Return new POSIX character class node - return node(RE.OP_POSIXCLASS, i.charValue()); - } - syntaxError("Invalid POSIX character class '" + charClass + "'"); - } - syntaxError("Invalid POSIX character class syntax"); - } - - // Try to build a class. Create OP_ANYOF node - int ret = node(RE.OP_ANYOF, 0); - - // Parse class declaration - char CHAR_INVALID = Character.MAX_VALUE; - char last = CHAR_INVALID; - char simpleChar = 0; - boolean include = true; - boolean definingRange = false; - int idxFirst = idx; - char rangeStart = Character.MIN_VALUE; - char rangeEnd; - RERange range = new RERange(); - while (idx < len && pattern.charAt(idx) != ']') - { - - switchOnCharacter: - - // Switch on character - switch (pattern.charAt(idx)) - { - case '^': - include = !include; - if (idx == idxFirst) - { - range.include(Character.MIN_VALUE, Character.MAX_VALUE, true); - } - idx++; - continue; - - case '\\': - { - // Escape always advances the stream - int c; - switch (c = escape ()) - { - case ESC_COMPLEX: - case ESC_BACKREF: - - // Word boundaries and backrefs not allowed in a character class! - syntaxError("Bad character class"); - - case ESC_CLASS: - - // Classes can't be an endpoint of a range - if (definingRange) - { - syntaxError("Bad character class"); - } - - // Handle specific type of class (some are ok) - switch (pattern.charAt(idx - 1)) - { - case RE.E_NSPACE: - case RE.E_NDIGIT: - case RE.E_NALNUM: - syntaxError("Bad character class"); - - case RE.E_SPACE: - range.include('\t', include); - range.include('\r', include); - range.include('\f', include); - range.include('\n', include); - range.include('\b', include); - range.include(' ', include); - break; - - case RE.E_ALNUM: - range.include('a', 'z', include); - range.include('A', 'Z', include); - range.include('_', include); - - // Fall through! - - case RE.E_DIGIT: - range.include('0', '9', include); - break; - } - - // Make last char invalid (can't be a range start) - last = CHAR_INVALID; - break; - - default: - - // Escape is simple so treat as a simple char - simpleChar = (char) c; - break switchOnCharacter; - } - } - continue; - - case '-': - - // Start a range if one isn't already started - if (definingRange) - { - syntaxError("Bad class range"); - } - definingRange = true; - - // If no last character, start of range is 0 - rangeStart = (last == CHAR_INVALID ? 0 : last); - - // Premature end of range. define up to Character.MAX_VALUE - if ((idx + 1) < len && pattern.charAt(++idx) == ']') - { - simpleChar = Character.MAX_VALUE; - break; - } - continue; - - default: - simpleChar = pattern.charAt(idx++); - break; - } - - // Handle simple character simpleChar - if (definingRange) - { - // if we are defining a range make it now - rangeEnd = simpleChar; - - // Actually create a range if the range is ok - if (rangeStart >= rangeEnd) - { - syntaxError("Bad character class"); - } - range.include(rangeStart, rangeEnd, include); - - // We are done defining the range - last = CHAR_INVALID; - definingRange = false; - } - else - { - // If simple character and not start of range, include it - if (idx >= len || pattern.charAt(idx) != '-') - { - range.include(simpleChar, include); - } - last = simpleChar; - } - } - - // Shouldn't be out of input - if (idx == len) - { - syntaxError("Unterminated character class"); - } - - // Absorb the ']' end of class marker - idx++; - - // Emit character class definition - instruction[ret + RE.offsetOpdata] = (char)range.num; - for (int i = 0; i < range.num; i++) - { - emit((char)range.minRange[i]); - emit((char)range.maxRange[i]); - } - return ret; - } - - /** - * Absorb an atomic character string. This method is a little tricky because - * it can un-include the last character of string if a closure operator follows. - * This is correct because *+? have higher precedence than concatentation (thus - * ABC* means AB(C*) and NOT (ABC)*). - * @return Index of new atom node - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - */ - int atom() throws RESyntaxException - { - // Create a string node - int ret = node(RE.OP_ATOM, 0); - - // Length of atom - int lenAtom = 0; - - // Loop while we've got input - - atomLoop: - - while (idx < len) - { - // Is there a next char? - if ((idx + 1) < len) - { - char c = pattern.charAt(idx + 1); - - // If the next 'char' is an escape, look past the whole escape - if (pattern.charAt(idx) == '\\') - { - int idxEscape = idx; - escape(); - if (idx < len) - { - c = pattern.charAt(idx); - } - idx = idxEscape; - } - - // Switch on next char - switch (c) - { - case '{': - case '?': - case '*': - case '+': - - // If the next character is a closure operator and our atom is non-empty, the - // current character should bind to the closure operator rather than the atom - if (lenAtom != 0) - { - break atomLoop; - } - } - } - - // Switch on current char - switch (pattern.charAt(idx)) - { - case ']': - case '^': - case '$': - case '.': - case '[': - case '(': - case ')': - case '|': - break atomLoop; - - case '{': - case '?': - case '*': - case '+': - - // We should have an atom by now - if (lenAtom == 0) - { - // No atom before closure - syntaxError("Missing operand to closure"); - } - break atomLoop; - - case '\\': - - { - // Get the escaped character (advances input automatically) - int idxBeforeEscape = idx; - int c = escape(); - - // Check if it's a simple escape (as opposed to, say, a backreference) - if ((c & ESC_MASK) == ESC_MASK) - { - // Not a simple escape, so backup to where we were before the escape. - idx = idxBeforeEscape; - break atomLoop; - } - - // Add escaped char to atom - emit((char) c); - lenAtom++; - } - break; - - default: - - // Add normal character to atom - emit(pattern.charAt(idx++)); - lenAtom++; - break; - } - } - - // This "shouldn't" happen - if (lenAtom == 0) - { - internalError(); - } - - // Emit the atom length into the program - instruction[ret + RE.offsetOpdata] = (char)lenAtom; - return ret; - } - - /** - * Match a terminal node. - * @param flags Flags - * @return Index of terminal node (closeable) - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - */ - int terminal(int[] flags) throws RESyntaxException - { - switch (pattern.charAt(idx)) - { - case RE.OP_EOL: - case RE.OP_BOL: - case RE.OP_ANY: - return node(pattern.charAt(idx++), 0); - - case '[': - return characterClass(); - - case '(': - return expr(flags); - - case ')': - syntaxError("Unexpected close paren"); - - case '|': - internalError(); - - case ']': - syntaxError("Mismatched class"); - - case 0: - syntaxError("Unexpected end of input"); - - case '?': - case '+': - case '{': - case '*': - syntaxError("Missing operand to closure"); - - case '\\': - { - // Don't forget, escape() advances the input stream! - int idxBeforeEscape = idx; - - // Switch on escaped character - switch (escape()) - { - case ESC_CLASS: - case ESC_COMPLEX: - flags[0] &= ~NODE_NULLABLE; - return node(RE.OP_ESCAPE, pattern.charAt(idx - 1)); - - case ESC_BACKREF: - { - char backreference = (char)(pattern.charAt(idx - 1) - '0'); - if (parens <= backreference) - { - syntaxError("Bad backreference"); - } - flags[0] |= NODE_NULLABLE; - return node(RE.OP_BACKREF, backreference); - } - - default: - - // We had a simple escape and we want to have it end up in - // an atom, so we back up and fall though to the default handling - idx = idxBeforeEscape; - flags[0] &= ~NODE_NULLABLE; - break; - } - } - } - - // Everything above either fails or returns. - // If it wasn't one of the above, it must be the start of an atom. - flags[0] &= ~NODE_NULLABLE; - return atom(); - } - - /** - * Compile a possibly closured terminal - * @param flags Flags passed by reference - * @return Index of closured node - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - */ - int closure(int[] flags) throws RESyntaxException - { - // Before terminal - int idxBeforeTerminal = idx; - - // Values to pass by reference to terminal() - int[] terminalFlags = { NODE_NORMAL }; - - // Get terminal symbol - int ret = terminal(terminalFlags); - - // Or in flags from terminal symbol - flags[0] |= terminalFlags[0]; - - // Advance input, set NODE_NULLABLE flag and do sanity checks - if (idx >= len) - { - return ret; - } - boolean greedy = true; - char closureType = pattern.charAt(idx); - switch (closureType) - { - case '?': - case '*': - - // The current node can be null - flags[0] |= NODE_NULLABLE; - - case '+': - - // Eat closure character - idx++; - - case '{': - - // Don't allow blantant stupidity - int opcode = instruction[ret + RE.offsetOpcode]; - if (opcode == RE.OP_BOL || opcode == RE.OP_EOL) - { - syntaxError("Bad closure operand"); - } - if ((terminalFlags[0] & NODE_NULLABLE) != 0) - { - syntaxError("Closure operand can't be nullable"); - } - break; - } - - // If the next character is a '?', make the closure non-greedy (reluctant) - if (idx < len && pattern.charAt(idx) == '?') - { - idx++; - greedy = false; - } - - if (greedy) - { - // Actually do the closure now - switch (closureType) - { - case '{': - { - // We look for our bracket in the list - boolean found = false; - int i; - allocBrackets(); - for (i = 0; i < brackets; i++) - { - if (bracketStart[i] == idx) - { - found = true; - break; - } - } - - // If its not in the list we parse the {m,n} - if (!found) - { - if (brackets >= maxBrackets) - { - reallocBrackets(); - } - bracketStart[brackets] = idx; - bracket(); - bracketEnd[brackets] = idx; - i = brackets++; - } - - // Process min first - if (bracketMin[i]-- > 0) - { - if (bracketMin[i] > 0 || bracketOpt[i] != 0) { - // Rewind stream and run it through again - more matchers coming - for (int j = 0; j < brackets; j++) { - if (j != i && bracketStart[j] < idx - && bracketStart[j] >= idxBeforeTerminal) - { - brackets--; - bracketStart[j] = bracketStart[brackets]; - bracketEnd[j] = bracketEnd[brackets]; - bracketMin[j] = bracketMin[brackets]; - bracketOpt[j] = bracketOpt[brackets]; - } - } - - idx = idxBeforeTerminal; - } else { - // Bug #1030: No optinal matches - no need to rewind - idx = bracketEnd[i]; - } - break; - } - - // Do the right thing for maximum ({m,}) - if (bracketOpt[i] == bracketUnbounded) - { - // Drop through now and closure expression. - // We are done with the {m,} expr, so skip rest - closureType = '*'; - bracketOpt[i] = 0; - idx = bracketEnd[i]; - } - else - if (bracketOpt[i]-- > 0) - { - if (bracketOpt[i] > 0) - { - // More optional matchers - 'play it again sam!' - idx = idxBeforeTerminal; - } else { - // Bug #1030: We are done - this one is last and optional - idx = bracketEnd[i]; - } - // Drop through to optionally close - closureType = '?'; - } - else - { - // Rollback terminal - neither min nor opt matchers present - lenInstruction = ret; - node(RE.OP_NOTHING, 0); - - // We are done. skip the rest of {m,n} expr - idx = bracketEnd[i]; - break; - } - } - - // Fall through! - - case '?': - case '*': - - if (!greedy) - { - break; - } - - if (closureType == '?') - { - // X? is compiled as (X|) - nodeInsert(RE.OP_BRANCH, 0, ret); // branch before X - setNextOfEnd(ret, node (RE.OP_BRANCH, 0)); // inserted branch to option - int nothing = node (RE.OP_NOTHING, 0); // which is OP_NOTHING - setNextOfEnd(ret, nothing); // point (second) branch to OP_NOTHING - setNextOfEnd(ret + RE.nodeSize, nothing); // point the end of X to OP_NOTHING node - } - - if (closureType == '*') - { - // X* is compiled as (X{gotoX}|) - nodeInsert(RE.OP_BRANCH, 0, ret); // branch before X - setNextOfEnd(ret + RE.nodeSize, node(RE.OP_BRANCH, 0)); // end of X points to an option - setNextOfEnd(ret + RE.nodeSize, node(RE.OP_GOTO, 0)); // to goto - setNextOfEnd(ret + RE.nodeSize, ret); // the start again - setNextOfEnd(ret, node(RE.OP_BRANCH, 0)); // the other option is - setNextOfEnd(ret, node(RE.OP_NOTHING, 0)); // OP_NOTHING - } - break; - - case '+': - { - // X+ is compiled as X({gotoX}|) - int branch; - branch = node(RE.OP_BRANCH, 0); // a new branch - setNextOfEnd(ret, branch); // is added to the end of X - setNextOfEnd(node(RE.OP_GOTO, 0), ret); // one option is to go back to the start - setNextOfEnd(branch, node(RE.OP_BRANCH, 0)); // the other option - setNextOfEnd(ret, node(RE.OP_NOTHING, 0)); // is OP_NOTHING - } - break; - } - } - else - { - // Add end after closured subexpr - setNextOfEnd(ret, node(RE.OP_END, 0)); - - // Actually do the closure now - switch (closureType) - { - case '?': - nodeInsert(RE.OP_RELUCTANTMAYBE, 0, ret); - break; - - case '*': - nodeInsert(RE.OP_RELUCTANTSTAR, 0, ret); - break; - - case '+': - nodeInsert(RE.OP_RELUCTANTPLUS, 0, ret); - break; - } - - // Point to the expr after the closure - setNextOfEnd(ret, lenInstruction); - } - return ret; - } - - /** - * Compile one branch of an or operator (implements concatenation) - * @param flags Flags passed by reference - * @return Pointer to branch node - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - */ - int branch(int[] flags) throws RESyntaxException - { - // Get each possibly closured piece and concat - int node; - int ret = node(RE.OP_BRANCH, 0); - int chain = -1; - int[] closureFlags = new int[1]; - boolean nullable = true; - while (idx < len && pattern.charAt(idx) != '|' && pattern.charAt(idx) != ')') - { - // Get new node - closureFlags[0] = NODE_NORMAL; - node = closure(closureFlags); - if (closureFlags[0] == NODE_NORMAL) - { - nullable = false; - } - - // If there's a chain, append to the end - if (chain != -1) - { - setNextOfEnd(chain, node); - } - - // Chain starts at current - chain = node; - } - - // If we don't run loop, make a nothing node - if (chain == -1) - { - node(RE.OP_NOTHING, 0); - } - - // Set nullable flag for this branch - if (nullable) - { - flags[0] |= NODE_NULLABLE; - } - return ret; - } - - /** - * Compile an expression with possible parens around it. Paren matching - * is done at this level so we can tie the branch tails together. - * @param flags Flag value passed by reference - * @return Node index of expression in instruction array - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - */ - int expr(int[] flags) throws RESyntaxException - { - // Create open paren node unless we were called from the top level (which has no parens) - int paren = -1; - int ret = -1; - int closeParens = parens; - if ((flags[0] & NODE_TOPLEVEL) == 0 && pattern.charAt(idx) == '(') - { - // if its a cluster ( rather than a proper subexpression ie with backrefs ) - if ( idx + 2 < len && pattern.charAt( idx + 1 ) == '?' && pattern.charAt( idx + 2 ) == ':' ) - { - paren = 2; - idx += 3; - ret = node( RE.OP_OPEN_CLUSTER, 0 ); - } - else - { - paren = 1; - idx++; - ret = node(RE.OP_OPEN, parens++); - } - } - flags[0] &= ~NODE_TOPLEVEL; - - // Create a branch node - int branch = branch(flags); - if (ret == -1) - { - ret = branch; - } - else - { - setNextOfEnd(ret, branch); - } - - // Loop through branches - while (idx < len && pattern.charAt(idx) == '|') - { - idx++; - branch = branch(flags); - setNextOfEnd(ret, branch); - } - - // Create an ending node (either a close paren or an OP_END) - int end; - if ( paren > 0 ) - { - if (idx < len && pattern.charAt(idx) == ')') - { - idx++; - } - else - { - syntaxError("Missing close paren"); - } - if ( paren == 1 ) - { - end = node(RE.OP_CLOSE, closeParens); - } - else - { - end = node( RE.OP_CLOSE_CLUSTER, 0 ); - } - } - else - { - end = node(RE.OP_END, 0); - } - - // Append the ending node to the ret nodelist - setNextOfEnd(ret, end); - - // Hook the ends of each branch to the end node - int currentNode = ret; - int nextNodeOffset = instruction[ currentNode + RE.offsetNext ]; - // while the next node o - while ( nextNodeOffset != 0 && currentNode < lenInstruction ) - { - // If branch, make the end of the branch's operand chain point to the end node. - if ( instruction[ currentNode + RE.offsetOpcode ] == RE.OP_BRANCH ) - { - setNextOfEnd( currentNode + RE.nodeSize, end ); - } - nextNodeOffset = instruction[ currentNode + RE.offsetNext ]; - currentNode += nextNodeOffset; - } - - // Return the node list - return ret; - } - - /** - * Compiles a regular expression pattern into a program runnable by the pattern - * matcher class 'RE'. - * @param pattern Regular expression pattern to compile (see RECompiler class - * for details). - * @return A compiled regular expression program. - * @exception RESyntaxException Thrown if the regular expression has invalid syntax. - * @see RECompiler - * @see RE - */ - public REProgram compile(String pattern) throws RESyntaxException - { - // Initialize variables for compilation - this.pattern = pattern; // Save pattern in instance variable - len = pattern.length(); // Precompute pattern length for speed - idx = 0; // Set parsing index to the first character - lenInstruction = 0; // Set emitted instruction count to zero - parens = 1; // Set paren level to 1 (the implicit outer parens) - brackets = 0; // No bracketed closures yet - - // Initialize pass by reference flags value - int[] flags = { NODE_TOPLEVEL }; - - // Parse expression - expr(flags); - - // Should be at end of input - if (idx != len) - { - if (pattern.charAt(idx) == ')') - { - syntaxError("Unmatched close paren"); - } - syntaxError("Unexpected input remains"); - } - - // Return the result - char[] ins = new char[lenInstruction]; - System.arraycopy(instruction, 0, ins, 0, lenInstruction); - return new REProgram(parens, ins); - } - - /** - * Local, nested class for maintaining character ranges for character classes. - */ - class RERange - { - int size = 16; // Capacity of current range arrays - int[] minRange = new int[size]; // Range minima - int[] maxRange = new int[size]; // Range maxima - int num = 0; // Number of range array elements in use - - /** - * Deletes the range at a given index from the range lists - * @param index Index of range to delete from minRange and maxRange arrays. - */ - void delete(int index) - { - // Return if no elements left or index is out of range - if (num == 0 || index >= num) - { - return; - } - - // Move elements down - while (++index < num) - { - if (index - 1 >= 0) - { - minRange[index-1] = minRange[index]; - maxRange[index-1] = maxRange[index]; - } - } - - // One less element now - num--; - } - - /** - * Merges a range into the range list, coalescing ranges if possible. - * @param min Minimum end of range - * @param max Maximum end of range - */ - void merge(int min, int max) - { - // Loop through ranges - for (int i = 0; i < num; i++) - { - // Min-max is subsumed by minRange[i]-maxRange[i] - if (min >= minRange[i] && max <= maxRange[i]) - { - return; - } - - // Min-max subsumes minRange[i]-maxRange[i] - else if (min <= minRange[i] && max >= maxRange[i]) - { - delete(i); - merge(min, max); - return; - } - - // Min is in the range, but max is outside - else if (min >= minRange[i] && min <= maxRange[i]) - { - delete(i); - min = minRange[i]; - merge(min, max); - return; - } - - // Max is in the range, but min is outside - else if (max >= minRange[i] && max <= maxRange[i]) - { - delete(i); - max = maxRange[i]; - merge(min, max); - return; - } - } - - // Must not overlap any other ranges - if (num >= size) - { - size *= 2; - int[] newMin = new int[size]; - int[] newMax = new int[size]; - System.arraycopy(minRange, 0, newMin, 0, num); - System.arraycopy(maxRange, 0, newMax, 0, num); - minRange = newMin; - maxRange = newMax; - } - minRange[num] = min; - maxRange[num] = max; - num++; - } - - /** - * Removes a range by deleting or shrinking all other ranges - * @param min Minimum end of range - * @param max Maximum end of range - */ - void remove(int min, int max) - { - // Loop through ranges - for (int i = 0; i < num; i++) - { - // minRange[i]-maxRange[i] is subsumed by min-max - if (minRange[i] >= min && maxRange[i] <= max) - { - delete(i); - i--; - return; - } - - // min-max is subsumed by minRange[i]-maxRange[i] - else if (min >= minRange[i] && max <= maxRange[i]) - { - int minr = minRange[i]; - int maxr = maxRange[i]; - delete(i); - if (minr < min) - { - merge(minr, min - 1); - } - if (max < maxr) - { - merge(max + 1, maxr); - } - return; - } - - // minRange is in the range, but maxRange is outside - else if (minRange[i] >= min && minRange[i] <= max) - { - minRange[i] = max + 1; - return; - } - - // maxRange is in the range, but minRange is outside - else if (maxRange[i] >= min && maxRange[i] <= max) - { - maxRange[i] = min - 1; - return; - } - } - } - - /** - * Includes (or excludes) the range from min to max, inclusive. - * @param min Minimum end of range - * @param max Maximum end of range - * @param include True if range should be included. False otherwise. - */ - void include(int min, int max, boolean include) - { - if (include) - { - merge(min, max); - } - else - { - remove(min, max); - } - } - - /** - * Includes a range with the same min and max - * @param minmax Minimum and maximum end of range (inclusive) - * @param include True if range should be included. False otherwise. - */ - void include(char minmax, boolean include) - { - include(minmax, minmax, include); - } - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/REDebugCompiler.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/REDebugCompiler.java deleted file mode 100644 index 815d4fdfa81..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/REDebugCompiler.java +++ /dev/null @@ -1,225 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -import java.io.PrintWriter; -import java.util.Hashtable; - -/** - * A subclass of RECompiler which can dump a regular expression program - * for debugging purposes. - * - * @author <a href="mailto:jonl@muppetlabs.com">Jonathan Locke</a> - */ -public class REDebugCompiler extends RECompiler -{ - /** - * Mapping from opcodes to descriptive strings - */ - static Hashtable hashOpcode = new Hashtable(); - static - { - hashOpcode.put(new Integer(RE.OP_RELUCTANTSTAR), "OP_RELUCTANTSTAR"); - hashOpcode.put(new Integer(RE.OP_RELUCTANTPLUS), "OP_RELUCTANTPLUS"); - hashOpcode.put(new Integer(RE.OP_RELUCTANTMAYBE), "OP_RELUCTANTMAYBE"); - hashOpcode.put(new Integer(RE.OP_END), "OP_END"); - hashOpcode.put(new Integer(RE.OP_BOL), "OP_BOL"); - hashOpcode.put(new Integer(RE.OP_EOL), "OP_EOL"); - hashOpcode.put(new Integer(RE.OP_ANY), "OP_ANY"); - hashOpcode.put(new Integer(RE.OP_ANYOF), "OP_ANYOF"); - hashOpcode.put(new Integer(RE.OP_BRANCH), "OP_BRANCH"); - hashOpcode.put(new Integer(RE.OP_ATOM), "OP_ATOM"); - hashOpcode.put(new Integer(RE.OP_STAR), "OP_STAR"); - hashOpcode.put(new Integer(RE.OP_PLUS), "OP_PLUS"); - hashOpcode.put(new Integer(RE.OP_MAYBE), "OP_MAYBE"); - hashOpcode.put(new Integer(RE.OP_NOTHING), "OP_NOTHING"); - hashOpcode.put(new Integer(RE.OP_GOTO), "OP_GOTO"); - hashOpcode.put(new Integer(RE.OP_ESCAPE), "OP_ESCAPE"); - hashOpcode.put(new Integer(RE.OP_OPEN), "OP_OPEN"); - hashOpcode.put(new Integer(RE.OP_CLOSE), "OP_CLOSE"); - hashOpcode.put(new Integer(RE.OP_BACKREF), "OP_BACKREF"); - hashOpcode.put(new Integer(RE.OP_POSIXCLASS), "OP_POSIXCLASS"); - hashOpcode.put(new Integer(RE.OP_OPEN_CLUSTER), "OP_OPEN_CLUSTER"); - hashOpcode.put(new Integer(RE.OP_CLOSE_CLUSTER), "OP_CLOSE_CLUSTER"); - } - - /** - * Returns a descriptive string for an opcode. - * @param opcode Opcode to convert to a string - * @return Description of opcode - */ - String opcodeToString(char opcode) - { - // Get string for opcode - String ret =(String)hashOpcode.get(new Integer(opcode)); - - // Just in case we have a corrupt program - if (ret == null) - { - ret = "OP_????"; - } - return ret; - } - - /** - * Return a string describing a (possibly unprintable) character. - * @param c Character to convert to a printable representation - * @return String representation of character - */ - String charToString(char c) - { - // If it's unprintable, convert to '\###' - if (c < ' ' || c > 127) - { - return "\\" + (int)c; - } - - // Return the character as a string - return String.valueOf(c); - } - - /** - * Returns a descriptive string for a node in a regular expression program. - * @param node Node to describe - * @return Description of node - */ - String nodeToString(int node) - { - // Get opcode and opdata for node - char opcode = instruction[node + RE.offsetOpcode]; - int opdata = (int)instruction[node + RE.offsetOpdata]; - - // Return opcode as a string and opdata value - return opcodeToString(opcode) + ", opdata = " + opdata; - } - - /** - * Inserts a node with a given opcode and opdata at insertAt. The node relative next - * pointer is initialized to 0. - * @param opcode Opcode for new node - * @param opdata Opdata for new node (only the low 16 bits are currently used) - * @param insertAt Index at which to insert the new node in the program * / - void nodeInsert(char opcode, int opdata, int insertAt) { - System.out.println( "====> " + opcode + " " + opdata + " " + insertAt ); - PrintWriter writer = new PrintWriter( System.out ); - dumpProgram( writer ); - super.nodeInsert( opcode, opdata, insertAt ); - System.out.println( "====< " ); - dumpProgram( writer ); - writer.flush(); - }/**/ - - - /** - * Appends a node to the end of a node chain - * @param node Start of node chain to traverse - * @param pointTo Node to have the tail of the chain point to * / - void setNextOfEnd(int node, int pointTo) { - System.out.println( "====> " + node + " " + pointTo ); - PrintWriter writer = new PrintWriter( System.out ); - dumpProgram( writer ); - super.setNextOfEnd( node, pointTo ); - System.out.println( "====< " ); - dumpProgram( writer ); - writer.flush(); - }/**/ - - - /** - * Dumps the current program to a PrintWriter - * @param p PrintWriter for program dump output - */ - public void dumpProgram(PrintWriter p) - { - // Loop through the whole program - for (int i = 0; i < lenInstruction; ) - { - // Get opcode, opdata and next fields of current program node - char opcode = instruction[i + RE.offsetOpcode]; - char opdata = instruction[i + RE.offsetOpdata]; - short next = (short)instruction[i + RE.offsetNext]; - - // Display the current program node - p.print(i + ". " + nodeToString(i) + ", next = "); - - // If there's no next, say 'none', otherwise give absolute index of next node - if (next == 0) - { - p.print("none"); - } - else - { - p.print(i + next); - } - - // Move past node - i += RE.nodeSize; - - // If character class - if (opcode == RE.OP_ANYOF) - { - // Opening bracket for start of char class - p.print(", ["); - - // Show each range in the char class - int rangeCount = opdata; - for (int r = 0; r < rangeCount; r++) - { - // Get first and last chars in range - char charFirst = instruction[i++]; - char charLast = instruction[i++]; - - // Print range as X-Y, unless range encompasses only one char - if (charFirst == charLast) - { - p.print(charToString(charFirst)); - } - else - { - p.print(charToString(charFirst) + "-" + charToString(charLast)); - } - } - - // Annotate the end of the char class - p.print("]"); - } - - // If atom - if (opcode == RE.OP_ATOM) - { - // Open quote - p.print(", \""); - - // Print each character in the atom - for (int len = opdata; len-- != 0; ) - { - p.print(charToString(instruction[i++])); - } - - // Close quote - p.print("\""); - } - - // Print a newline - p.println(""); - } - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/REProgram.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/REProgram.java deleted file mode 100644 index f7a39ce3fe1..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/REProgram.java +++ /dev/null @@ -1,158 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -import java.io.Serializable; - -/** - * A class that holds compiled regular expressions. This is exposed mainly - * for use by the recompile utility (which helps you produce precompiled - * REProgram objects). You should not otherwise need to work directly with - * this class. -* - * @see RE - * @see RECompiler - * - * @author <a href="mailto:jonl@muppetlabs.com">Jonathan Locke</a> - */ -public class REProgram implements Serializable -{ - static final int OPT_HASBACKREFS = 1; - - char[] instruction; // The compiled regular expression 'program' - int lenInstruction; // The amount of the instruction buffer in use - char[] prefix; // Prefix string optimization - int flags; // Optimization flags (REProgram.OPT_*) - int maxParens = -1; - - /** - * Constructs a program object from a character array - * @param instruction Character array with RE opcode instructions in it - */ - public REProgram(char[] instruction) - { - this(instruction, instruction.length); - } - - /** - * Constructs a program object from a character array - * @param parens Count of parens in the program - * @param instruction Character array with RE opcode instructions in it - */ - public REProgram(int parens, char[] instruction) - { - this(instruction, instruction.length); - this.maxParens = parens; - } - - /** - * Constructs a program object from a character array - * @param instruction Character array with RE opcode instructions in it - * @param lenInstruction Amount of instruction array in use - */ - public REProgram(char[] instruction, int lenInstruction) - { - setInstructions(instruction, lenInstruction); - } - - /** - * Returns a copy of the current regular expression program in a character - * array that is exactly the right length to hold the program. If there is - * no program compiled yet, getInstructions() will return null. - * @return A copy of the current compiled RE program - */ - public char[] getInstructions() - { - // Ensure program has been compiled! - if (lenInstruction != 0) - { - // Return copy of program - char[] ret = new char[lenInstruction]; - System.arraycopy(instruction, 0, ret, 0, lenInstruction); - return ret; - } - return null; - } - - /** - * Sets a new regular expression program to run. It is this method which - * performs any special compile-time search optimizations. Currently only - * two optimizations are in place - one which checks for backreferences - * (so that they can be lazily allocated) and another which attempts to - * find an prefix anchor string so that substantial amounts of input can - * potentially be skipped without running the actual program. - * @param instruction Program instruction buffer - * @param lenInstruction Length of instruction buffer in use - */ - public void setInstructions(char[] instruction, int lenInstruction) - { - // Save reference to instruction array - this.instruction = instruction; - this.lenInstruction = lenInstruction; - - // Initialize other program-related variables - flags = 0; - prefix = null; - - // Try various compile-time optimizations if there's a program - if (instruction != null && lenInstruction != 0) - { - // If the first node is a branch - if (lenInstruction >= RE.nodeSize && instruction[0 + RE.offsetOpcode] == RE.OP_BRANCH) - { - // to the end node - int next = instruction[0 + RE.offsetNext]; - if (instruction[next + RE.offsetOpcode] == RE.OP_END) - { - // and the branch starts with an atom - if (lenInstruction >= (RE.nodeSize * 2) && instruction[RE.nodeSize + RE.offsetOpcode] == RE.OP_ATOM) - { - // then get that atom as an prefix because there's no other choice - int lenAtom = instruction[RE.nodeSize + RE.offsetOpdata]; - prefix = new char[lenAtom]; - System.arraycopy(instruction, RE.nodeSize * 2, prefix, 0, lenAtom); - } - } - } - - BackrefScanLoop: - - // Check for backreferences - for (int i = 0; i < lenInstruction; i += RE.nodeSize) - { - switch (instruction[i + RE.offsetOpcode]) - { - case RE.OP_ANYOF: - i += (instruction[i + RE.offsetOpdata] * 2); - break; - - case RE.OP_ATOM: - i += instruction[i + RE.offsetOpdata]; - break; - - case RE.OP_BACKREF: - flags |= OPT_HASBACKREFS; - break BackrefScanLoop; - } - } - } - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RESyntaxException.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RESyntaxException.java deleted file mode 100644 index a13f901ece4..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RESyntaxException.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -/** - * Exception thrown to indicate a syntax error in a regular expression. - * This is a non-checked exception because you should only have problems compiling - * a regular expression during development. - * If you are making regular expresion programs dynamically then you can catch it - * if you wish. But should not be forced to. - * - * @author <a href="mailto:jonl@muppetlabs.com">Jonathan Locke</a> - * @author <a href="mailto:gholam@xtra.co.nz>Michael McCallum</a> - */ -public class RESyntaxException extends RuntimeException -{ - /** - * Constructor. - * @param s Further description of the syntax error - */ - public RESyntaxException(String s) - { - super("Syntax error: " + s); - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RETest.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RETest.java deleted file mode 100644 index 463776d5140..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/RETest.java +++ /dev/null @@ -1,883 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.InputStreamReader; -import java.io.PrintWriter; -import java.io.File; -import java.io.ByteArrayOutputStream; -import java.io.ObjectOutputStream; -import java.io.ByteArrayInputStream; -import java.io.ObjectInputStream; -import java.io.StringBufferInputStream; -import java.io.StringReader; -import java.io.IOException; - -/** - * Data driven (and optionally interactive) testing harness to exercise regular - * expression compiler and matching engine. - * - * @author <a href="mailto:jonl@muppetlabs.com">Jonathan Locke</a> - * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> - * @author <a href="mailto:gholam@xtra.co.nz">Michael McCallum</a> - */ -public class RETest -{ - // True if we want to see output from success cases - static final boolean showSuccesses = false; - - // A new line character. - static final String NEW_LINE = System.getProperty( "line.separator" ); - - // Construct a debug compiler - REDebugCompiler compiler = new REDebugCompiler(); - - /** - * Main program entrypoint. If an argument is given, it will be compiled - * and interactive matching will ensue. If no argument is given, the - * file RETest.txt will be used as automated testing input. - * @param args Command line arguments (optional regular expression) - */ - public static void main(String[] args) - { - try - { - if (!test( args )) { - System.exit(1); - } - } - catch (Exception e) - { - e.printStackTrace(); - System.exit(1); - } - } - - /** - * Testing entrypoint. - * @param args Command line arguments - * @exception Exception thrown in case of error - */ - public static boolean test( String[] args ) throws Exception - { - RETest test = new RETest(); - // Run interactive tests against a single regexp - if (args.length == 2) - { - test.runInteractiveTests(args[1]); - } - else if (args.length == 1) - { - // Run automated tests - test.runAutomatedTests(args[0]); - } - else - { - System.out.println( "Usage: RETest ([-i] [regex]) ([/path/to/testfile.txt])" ); - System.out.println( "By Default will run automated tests from file 'docs/RETest.txt' ..." ); - System.out.println(); - test.runAutomatedTests("docs/RETest.txt"); - } - return test.failures == 0; - } - - /** - * Constructor - */ - public RETest() - { - } - - /** - * Compile and test matching against a single expression - * @param expr Expression to compile and test - */ - void runInteractiveTests(String expr) - { - RE r = new RE(); - try - { - // Compile expression - r.setProgram(compiler.compile(expr)); - - // Show expression - say("" + NEW_LINE + "" + expr + "" + NEW_LINE + ""); - - // Show program for compiled expression - PrintWriter writer = new PrintWriter( System.out ); - compiler.dumpProgram( writer ); - writer.flush(); - - boolean running = true; - // Test matching against compiled expression - while ( running ) - { - // Read from keyboard - BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); - System.out.print("> "); - System.out.flush(); - String match = br.readLine(); - - if ( match != null ) - { - // Try a match against the keyboard input - if (r.match(match)) - { - say("Match successful."); - } - else - { - say("Match failed."); - } - - // Show subparen registers - showParens(r); - } - else - { - running = false; - System.out.println(); - } - } - } - catch (Exception e) - { - say("Error: " + e.toString()); - e.printStackTrace(); - } - } - - /** - * Exit with a fatal error. - * @param s Last famous words before exiting - */ - void die(String s) - { - say("FATAL ERROR: " + s); - System.exit(-1); - } - - /** - * Fail with an error. Will print a big failure message to System.out. - * - * @param log Output before failure - * @param s Failure description - */ - void fail(StringBuffer log, String s) - { - System.out.print(log.toString()); - fail(s); - } - - /** - * Fail with an error. Will print a big failure message to System.out. - * - * @param s Failure description - */ - void fail(String s) - { - failures++; - say("" + NEW_LINE + ""); - say("*******************************************************"); - say("********************* FAILURE! **********************"); - say("*******************************************************"); - say("" + NEW_LINE + ""); - say(s); - say(""); - // make sure the writer gets flushed. - if (compiler != null) { - PrintWriter writer = new PrintWriter( System.out ); - compiler.dumpProgram( writer ); - writer.flush(); - say("" + NEW_LINE + ""); - } - } - - /** - * Say something to standard out - * @param s What to say - */ - void say(String s) - { - System.out.println(s); - } - - /** - * Dump parenthesized subexpressions found by a regular expression matcher object - * @param r Matcher object with results to show - */ - void showParens(RE r) - { - // Loop through each paren - for (int i = 0; i < r.getParenCount(); i++) - { - // Show paren register - say("$" + i + " = " + r.getParen(i)); - } - } - - /* - * number in automated test - */ - int testCount = 0; - - /* - * Count of failures in automated test - */ - int failures = 0; - - /** - * Run automated tests in RETest.txt file (from Perl 4.0 test battery) - * @exception Exception thrown in case of error - */ - void runAutomatedTests(String testDocument) throws Exception - { - long ms = System.currentTimeMillis(); - - // Some unit tests - testPrecompiledRE(); - testSplitAndGrep(); - testSubst(); - testOther(); - - // Test from script file - File testInput = new File(testDocument); - if (! testInput.exists()) { - throw new Exception ("Could not find: " + testDocument); - } - - BufferedReader br = new BufferedReader(new FileReader(testInput)); - try - { - // While input is available, parse lines - while (br.ready()) - { - RETestCase testcase = getNextTestCase(br); - if (testcase != null) { - testcase.runTest(); - } - } - } - finally - { - br.close(); - } - - // Show match time - say(NEW_LINE + NEW_LINE + "Match time = " + (System.currentTimeMillis() - ms) + " ms."); - - // Print final results - if (failures > 0) { - say("*************** THERE ARE FAILURES! *******************"); - } - say("Tests complete. " + testCount + " tests, " + failures + " failure(s)."); - } - - /** - * Run automated unit test - * @exception Exception thrown in case of error - */ - void testOther() throws Exception - { - // Serialization test 1: Compile regexp and serialize/deserialize it - RE r = new RE("(a*)b"); - say("Serialized/deserialized (a*)b"); - ByteArrayOutputStream out = new ByteArrayOutputStream(128); - new ObjectOutputStream(out).writeObject(r); - ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray()); - r = (RE)new ObjectInputStream(in).readObject(); - if (!r.match("aaab")) - { - fail("Did not match 'aaab' with deserialized RE."); - } else { - say("aaaab = true"); - showParens(r); - } - - // Serialization test 2: serialize/deserialize used regexp - out.reset(); - say("Deserialized (a*)b"); - new ObjectOutputStream(out).writeObject(r); - in = new ByteArrayInputStream(out.toByteArray()); - r = (RE)new ObjectInputStream(in).readObject(); - if (r.getParenCount() != 0) - { - fail("Has parens after deserialization."); - } - if (!r.match("aaab")) - { - fail("Did not match 'aaab' with deserialized RE."); - } else { - say("aaaab = true"); - showParens(r); - } - - // Test MATCH_CASEINDEPENDENT - r = new RE("abc(\\w*)"); - say("MATCH_CASEINDEPENDENT abc(\\w*)"); - r.setMatchFlags(RE.MATCH_CASEINDEPENDENT); - say("abc(d*)"); - if (!r.match("abcddd")) - { - fail("Did not match 'abcddd'."); - } else { - say("abcddd = true"); - showParens(r); - } - - if (!r.match("aBcDDdd")) - { - fail("Did not match 'aBcDDdd'."); - } else { - say("aBcDDdd = true"); - showParens(r); - } - - if (!r.match("ABCDDDDD")) - { - fail("Did not match 'ABCDDDDD'."); - } else { - say("ABCDDDDD = true"); - showParens(r); - } - - r = new RE("(A*)b\\1"); - r.setMatchFlags(RE.MATCH_CASEINDEPENDENT); - if (!r.match("AaAaaaBAAAAAA")) - { - fail("Did not match 'AaAaaaBAAAAAA'."); - } else { - say("AaAaaaBAAAAAA = true"); - showParens(r); - } - - r = new RE("[A-Z]*"); - r.setMatchFlags(RE.MATCH_CASEINDEPENDENT); - if (!r.match("CaBgDe12")) - { - fail("Did not match 'CaBgDe12'."); - } else { - say("CaBgDe12 = true"); - showParens(r); - } - - // Test MATCH_MULTILINE. Test for eol/bol symbols. - r = new RE("^abc$", RE.MATCH_MULTILINE); - if (!r.match("\nabc")) { - fail("\"\\nabc\" doesn't match \"^abc$\""); - } - if (!r.match("\rabc")) { - fail("\"\\rabc\" doesn't match \"^abc$\""); - } - if (!r.match("\r\nabc")) { - fail("\"\\r\\nabc\" doesn't match \"^abc$\""); - } - if (!r.match("\u0085abc")) { - fail("\"\\u0085abc\" doesn't match \"^abc$\""); - } - if (!r.match("\u2028abc")) { - fail("\"\\u2028abc\" doesn't match \"^abc$\""); - } - if (!r.match("\u2029abc")) { - fail("\"\\u2029abc\" doesn't match \"^abc$\""); - } - - // Test MATCH_MULTILINE. Test that '.' does not matches new line. - r = new RE("^a.*b$", RE.MATCH_MULTILINE); - if (r.match("a\nb")) { - fail("\"a\\nb\" matches \"^a.*b$\""); - } - if (r.match("a\rb")) { - fail("\"a\\rb\" matches \"^a.*b$\""); - } - if (r.match("a\r\nb")) { - fail("\"a\\r\\nb\" matches \"^a.*b$\""); - } - if (r.match("a\u0085b")) { - fail("\"a\\u0085b\" matches \"^a.*b$\""); - } - if (r.match("a\u2028b")) { - fail("\"a\\u2028b\" matches \"^a.*b$\""); - } - if (r.match("a\u2029b")) { - fail("\"a\\u2029b\" matches \"^a.*b$\""); - } - } - - private void testPrecompiledRE() - { - // Pre-compiled regular expression "a*b" - char[] re1Instructions = - { - 0x007c, 0x0000, 0x001a, 0x007c, 0x0000, 0x000d, 0x0041, - 0x0001, 0x0004, 0x0061, 0x007c, 0x0000, 0x0003, 0x0047, - 0x0000, 0xfff6, 0x007c, 0x0000, 0x0003, 0x004e, 0x0000, - 0x0003, 0x0041, 0x0001, 0x0004, 0x0062, 0x0045, 0x0000, - 0x0000, - }; - - REProgram re1 = new REProgram(re1Instructions); - - // Simple test of pre-compiled regular expressions - RE r = new RE(re1); - say("a*b"); - boolean result = r.match("aaab"); - say("aaab = " + result); - showParens(r); - if (!result) { - fail("\"aaab\" doesn't match to precompiled \"a*b\""); - } - - result = r.match("b"); - say("b = " + result); - showParens(r); - if (!result) { - fail("\"b\" doesn't match to precompiled \"a*b\""); - } - - result = r.match("c"); - say("c = " + result); - showParens(r); - if (result) { - fail("\"c\" matches to precompiled \"a*b\""); - } - - result = r.match("ccccaaaaab"); - say("ccccaaaaab = " + result); - showParens(r); - if (!result) { - fail("\"ccccaaaaab\" doesn't match to precompiled \"a*b\""); - } - } - - private void testSplitAndGrep() - { - String[] expected = {"xxxx", "xxxx", "yyyy", "zzz"}; - RE r = new RE("a*b"); - String[] s = r.split("xxxxaabxxxxbyyyyaaabzzz"); - for (int i = 0; i < expected.length && i < s.length; i++) { - assertEquals("Wrong splitted part", expected[i], s[i]); - } - assertEquals("Wrong number of splitted parts", expected.length, - s.length); - - r = new RE("x+"); - expected = new String[] {"xxxx", "xxxx"}; - s = r.grep(s); - for (int i = 0; i < s.length; i++) - { - say("s[" + i + "] = " + s[i]); - assertEquals("Grep fails", expected[i], s[i]); - } - assertEquals("Wrong number of string found by grep", expected.length, - s.length); - } - - private void testSubst() - { - RE r = new RE("a*b"); - String expected = "-foo-garply-wacky-"; - String actual = r.subst("aaaabfooaaabgarplyaaabwackyb", "-"); - assertEquals("Wrong result of substitution in \"a*b\"", expected, actual); - - // Test subst() with backreferences - r = new RE("http://[\\.\\w\\-\\?/~_@&=%]+"); - actual = r.subst("visit us: http://www.apache.org!", - "1234<a href=\"$0\">$0</a>", RE.REPLACE_BACKREFERENCES); - assertEquals("Wrong subst() result", "visit us: 1234<a href=\"http://www.apache.org\">http://www.apache.org</a>!", actual); - - // Test subst() with backreferences without leading characters - // before first backreference - r = new RE("(.*?)=(.*)"); - actual = r.subst("variable=value", - "$1_test_$212", RE.REPLACE_BACKREFERENCES); - assertEquals("Wrong subst() result", "variable_test_value12", actual); - - // Test subst() with NO backreferences - r = new RE("^a$"); - actual = r.subst("a", - "b", RE.REPLACE_BACKREFERENCES); - assertEquals("Wrong subst() result", "b", actual); - - // Test subst() with NO backreferences - r = new RE("^a$", RE.MATCH_MULTILINE); - actual = r.subst("\r\na\r\n", - "b", RE.REPLACE_BACKREFERENCES); - assertEquals("Wrong subst() result", "\r\nb\r\n", actual); - } - - public void assertEquals(String message, String expected, String actual) - { - if (expected != null && !expected.equals(actual) - || actual != null && !actual.equals(expected)) - { - fail(message + " (expected \"" + expected - + "\", actual \"" + actual + "\")"); - } - } - - public void assertEquals(String message, int expected, int actual) - { - if (expected != actual) { - fail(message + " (expected \"" + expected - + "\", actual \"" + actual + "\")"); - } - } - - /** - * Converts yesno string to boolean. - * @param yesno string representation of expected result - * @return true if yesno is "YES", false if yesno is "NO" - * stops program otherwise. - */ - private boolean getExpectedResult(String yesno) - { - if ("NO".equals(yesno)) - { - return false; - } - else if ("YES".equals(yesno)) - { - return true; - } - else - { - // Bad test script - die("Test script error!"); - return false; //to please javac - } - } - - /** - * Finds next test description in a given script. - * @param br <code>BufferedReader</code> for a script file - * @return strign tag for next test description - * @exception IOException if some io problems occured - */ - private String findNextTest(BufferedReader br) throws IOException - { - String number = ""; - - while (br.ready()) - { - number = br.readLine(); - if (number == null) - { - break; - } - number = number.trim(); - if (number.startsWith("#")) - { - break; - } - if (!number.equals("")) - { - say("Script error. Line = " + number); - System.exit(-1); - } - } - return number; - } - - /** - * Creates testcase for the next test description in the script file. - * @param br <code>BufferedReader</code> for script file. - * @return a new tescase or null. - * @exception IOException if some io problems occured - */ - private RETestCase getNextTestCase(BufferedReader br) throws IOException - { - // Find next re test case - final String tag = findNextTest(br); - - // Are we done? - if (!br.ready()) - { - return null; - } - - // Get expression - final String expr = br.readLine(); - - // Get test information - final String matchAgainst = br.readLine(); - final boolean badPattern = "ERR".equals(matchAgainst); - boolean shouldMatch = false; - int expectedParenCount = 0; - String[] expectedParens = null; - - if (!badPattern) { - shouldMatch = getExpectedResult(br.readLine().trim()); - if (shouldMatch) { - expectedParenCount = Integer.parseInt(br.readLine().trim()); - expectedParens = new String[expectedParenCount]; - for (int i = 0; i < expectedParenCount; i++) { - expectedParens[i] = br.readLine(); - } - } - } - - return new RETestCase(this, tag, expr, matchAgainst, badPattern, - shouldMatch, expectedParens); - } -} - -final class RETestCase -{ - final private StringBuffer log = new StringBuffer(); - final private int number; - final private String tag; // number from script file - final private String pattern; - final private String toMatch; - final private boolean badPattern; - final private boolean shouldMatch; - final private String[] parens; - final private RETest test; - private RE regexp; - - public RETestCase(RETest test, String tag, String pattern, - String toMatch, boolean badPattern, - boolean shouldMatch, String[] parens) - { - this.number = ++test.testCount; - this.test = test; - this.tag = tag; - this.pattern = pattern; - this.toMatch = toMatch; - this.badPattern = badPattern; - this.shouldMatch = shouldMatch; - if (parens != null) { - this.parens = new String[parens.length]; - for (int i = 0; i < parens.length; i++) { - this.parens[i] = parens[i]; - } - } else { - this.parens = null; - } - } - - public void runTest() - { - test.say(tag + "(" + number + "): " + pattern); - if (testCreation()) { - testMatch(); - } - } - - boolean testCreation() - { - try - { - // Compile it - regexp = new RE(); - regexp.setProgram(test.compiler.compile(pattern)); - // Expression didn't cause an expected error - if (badPattern) - { - test.fail(log, "Was expected to be an error, but wasn't."); - return false; - } - - return true; - } - // Some expressions *should* cause exceptions to be thrown - catch (Exception e) - { - // If it was supposed to be an error, report success and continue - if (badPattern) - { - log.append(" Match: ERR\n"); - success("Produces an error (" + e.toString() + "), as expected."); - return false; - } - - // Wasn't supposed to be an error - String message = (e.getMessage() == null) ? e.toString() : e.getMessage(); - test.fail(log, "Produces an unexpected exception \"" + message + "\""); - e.printStackTrace(); - } - catch (Error e) - { - // Internal error happened - test.fail(log, "Compiler threw fatal error \"" + e.getMessage() + "\""); - e.printStackTrace(); - } - - return false; - } - - private void testMatch() - { - log.append(" Match against: '" + toMatch + "'\n"); - // Try regular matching - try - { - // Match against the string - boolean result = regexp.match(toMatch); - log.append(" Matched: " + (result ? "YES" : "NO") + "\n"); - - // Check result, parens, and iterators - if (checkResult(result) && (!shouldMatch || checkParens())) - { - // test match(CharacterIterator, int) - // for every CharacterIterator implementation. - log.append(" Match using StringCharacterIterator\n"); - if (!tryMatchUsingCI(new StringCharacterIterator(toMatch))) - return; - - log.append(" Match using CharacterArrayCharacterIterator\n"); - if (!tryMatchUsingCI(new CharacterArrayCharacterIterator(toMatch.toCharArray(), 0, toMatch.length()))) - return; - - log.append(" Match using StreamCharacterIterator\n"); - if (!tryMatchUsingCI(new StreamCharacterIterator(new StringBufferInputStream(toMatch)))) - return; - - log.append(" Match using ReaderCharacterIterator\n"); - if (!tryMatchUsingCI(new ReaderCharacterIterator(new StringReader(toMatch)))) - return; - } - } - // Matcher blew it - catch(Exception e) - { - test.fail(log, "Matcher threw exception: " + e.toString()); - e.printStackTrace(); - } - // Internal error - catch(Error e) - { - test.fail(log, "Matcher threw fatal error \"" + e.getMessage() + "\""); - e.printStackTrace(); - } - } - - private boolean checkResult(boolean result) - { - // Write status - if (result == shouldMatch) { - success((shouldMatch ? "Matched" : "Did not match") - + " \"" + toMatch + "\", as expected:"); - return true; - } else { - if (shouldMatch) { - test.fail(log, "Did not match \"" + toMatch + "\", when expected to."); - } else { - test.fail(log, "Matched \"" + toMatch + "\", when not expected to."); - } - return false; - } - } - - private boolean checkParens() - { - // Show subexpression registers - if (RETest.showSuccesses) - { - test.showParens(regexp); - } - - log.append(" Paren count: " + regexp.getParenCount() + "\n"); - if (!assertEquals(log, "Wrong number of parens", parens.length, regexp.getParenCount())) - { - return false; - } - - // Check registers against expected contents - for (int p = 0; p < regexp.getParenCount(); p++) - { - log.append(" Paren " + p + ": " + regexp.getParen(p) + "\n"); - - // Compare expected result with actual - if ("null".equals(parens[p]) && regexp.getParen(p) == null) - { - // Consider "null" in test file equal to null - continue; - } - if (!assertEquals(log, "Wrong register " + p, parens[p], regexp.getParen(p))) - { - return false; - } - } - - return true; - } - - boolean tryMatchUsingCI(CharacterIterator matchAgainst) - { - try { - boolean result = regexp.match(matchAgainst, 0); - log.append(" Match: " + (result ? "YES" : "NO") + "\n"); - return checkResult(result) && (!shouldMatch || checkParens()); - } - // Matcher blew it - catch(Exception e) - { - test.fail(log, "Matcher threw exception: " + e.toString()); - e.printStackTrace(); - } - // Internal error - catch(Error e) - { - test.fail(log, "Matcher threw fatal error \"" + e.getMessage() + "\""); - e.printStackTrace(); - } - return false; - } - - public boolean assertEquals(StringBuffer log, String message, String expected, String actual) - { - if (expected != null && !expected.equals(actual) - || actual != null && !actual.equals(expected)) - { - test.fail(log, message + " (expected \"" + expected - + "\", actual \"" + actual + "\")"); - return false; - } - return true; - } - - public boolean assertEquals(StringBuffer log, String message, int expected, int actual) - { - if (expected != actual) { - test.fail(log, message + " (expected \"" + expected - + "\", actual \"" + actual + "\")"); - return false; - } - return true; - } - - /** - * Show a success - * @param s Success story - */ - void success(String s) - { - if (RETest.showSuccesses) - { - test.say("" + RETest.NEW_LINE + "-----------------------" + RETest.NEW_LINE + ""); - test.say("Expression #" + (number) + " \"" + pattern + "\" "); - test.say("Success: " + s); - } - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/REUtil.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/REUtil.java deleted file mode 100644 index 10907ece8d6..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/REUtil.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -/** - * This is a class that contains utility helper methods for this package. - * - * @author <a href="mailto:jonl@muppetlabs.com">Jonathan Locke</a> - */ -public class REUtil -{ - /** complex: */ - private static final String complexPrefix = "complex:"; - - /** - * Creates a regular expression, permitting simple or complex syntax - * @param expression The expression, beginning with a prefix if it's complex or - * having no prefix if it's simple - * @param matchFlags Matching style flags - * @return The regular expression object - * @exception RESyntaxException thrown in case of error - */ - public static RE createRE(String expression, int matchFlags) throws RESyntaxException - { - if (expression.startsWith(complexPrefix)) - { - return new RE(expression.substring(complexPrefix.length()), matchFlags); - } - return new RE(RE.simplePatternToFullRegularExpression(expression), matchFlags); - } - - /** - * Creates a regular expression, permitting simple or complex syntax - * @param expression The expression, beginning with a prefix if it's complex or - * having no prefix if it's simple - * @return The regular expression object - * @exception RESyntaxException thrown in case of error - */ - public static RE createRE(String expression) throws RESyntaxException - { - return createRE(expression, RE.MATCH_NORMAL); - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/ReaderCharacterIterator.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/ReaderCharacterIterator.java deleted file mode 100644 index 7eafff44121..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/ReaderCharacterIterator.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -import java.io.Reader; -import java.io.IOException; - -/** - * Encapsulates java.io.Reader as CharacterIterator - * - * @author <a href="mailto:ales.novak@netbeans.com">Ales Novak</a> - */ -public final class ReaderCharacterIterator implements CharacterIterator -{ - /** Underlying reader */ - private final Reader reader; - - /** Buffer of read chars */ - private final StringBuffer buff; - - /** read end? */ - private boolean closed; - - /** @param reader a Reader, which is parsed */ - public ReaderCharacterIterator(Reader reader) - { - this.reader = reader; - this.buff = new StringBuffer(512); - this.closed = false; - } - - /** @return a substring */ - public String substring(int beginIndex, int endIndex) - { - try - { - ensure(endIndex); - return buff.toString().substring(beginIndex, endIndex); - } - catch (IOException e) - { - throw new StringIndexOutOfBoundsException(e.getMessage()); - } - } - - /** @return a substring */ - public String substring(int beginIndex) - { - try - { - readAll(); - return buff.toString().substring(beginIndex); - } - catch (IOException e) - { - throw new StringIndexOutOfBoundsException(e.getMessage()); - } - } - - /** @return a character at the specified position. */ - public char charAt(int pos) - { - try - { - ensure(pos); - return buff.charAt(pos); - } - catch (IOException e) - { - throw new StringIndexOutOfBoundsException(e.getMessage()); - } - } - - /** @return <tt>true</tt> iff if the specified index is after the end of the character stream */ - public boolean isEnd(int pos) - { - if (buff.length() > pos) - { - return false; - } - else - { - try - { - ensure(pos); - return (buff.length() <= pos); - } - catch (IOException e) - { - throw new StringIndexOutOfBoundsException(e.getMessage()); - } - } - } - - /** Reads n characters from the stream and appends them to the buffer */ - private int read(int n) throws IOException - { - if (closed) - { - return 0; - } - - char[] c = new char[n]; - int count = 0; - int read = 0; - - do - { - read = reader.read(c); - if (read < 0) // EOF - { - closed = true; - break; - } - count += read; - buff.append(c, 0, read); - } - while (count < n); - - return count; - } - - /** Reads rest of the stream. */ - private void readAll() throws IOException - { - while(! closed) - { - read(1000); - } - } - - /** Reads chars up to the idx */ - private void ensure(int idx) throws IOException - { - if (closed) - { - return; - } - - if (idx < buff.length()) - { - return; - } - read(idx + 1 - buff.length()); - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/StreamCharacterIterator.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/StreamCharacterIterator.java deleted file mode 100644 index e489065b79b..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/StreamCharacterIterator.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -import java.io.InputStream; -import java.io.IOException; - -/** - * Encapsulates java.io.InputStream as CharacterIterator. - * - * @author <a href="mailto:ales.novak@netbeans.com">Ales Novak</a> - */ -public final class StreamCharacterIterator implements CharacterIterator -{ - /** Underlying is */ - private final InputStream is; - - /** Buffer of read chars */ - private final StringBuffer buff; - - /** read end? */ - private boolean closed; - - /** @param is an InputStream, which is parsed */ - public StreamCharacterIterator(InputStream is) - { - this.is = is; - this.buff = new StringBuffer(512); - this.closed = false; - } - - /** @return a substring */ - public String substring(int beginIndex, int endIndex) - { - try - { - ensure(endIndex); - return buff.toString().substring(beginIndex, endIndex); - } - catch (IOException e) - { - throw new StringIndexOutOfBoundsException(e.getMessage()); - } - } - - /** @return a substring */ - public String substring(int beginIndex) - { - try - { - readAll(); - return buff.toString().substring(beginIndex); - } - catch (IOException e) - { - throw new StringIndexOutOfBoundsException(e.getMessage()); - } - } - - - /** @return a character at the specified position. */ - public char charAt(int pos) - { - try - { - ensure(pos); - return buff.charAt(pos); - } - catch (IOException e) - { - throw new StringIndexOutOfBoundsException(e.getMessage()); - } - } - - /** @return <tt>true</tt> iff if the specified index is after the end of the character stream */ - public boolean isEnd(int pos) - { - if (buff.length() > pos) - { - return false; - } - else - { - try - { - ensure(pos); - return (buff.length() <= pos); - } - catch (IOException e) - { - throw new StringIndexOutOfBoundsException(e.getMessage()); - } - } - } - - /** Reads n characters from the stream and appends them to the buffer */ - private int read(int n) throws IOException - { - if (closed) - { - return 0; - } - - int c; - int i = n; - while (--i >= 0) - { - c = is.read(); - if (c < 0) // EOF - { - closed = true; - break; - } - buff.append((char) c); - } - return n - i; - } - - /** Reads rest of the stream. */ - private void readAll() throws IOException - { - while(! closed) - { - read(1000); - } - } - - /** Reads chars up to the idx */ - private void ensure(int idx) throws IOException - { - if (closed) - { - return; - } - - if (idx < buff.length()) - { - return; - } - - read(idx + 1 - buff.length()); - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/StringCharacterIterator.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/StringCharacterIterator.java deleted file mode 100644 index bc6c859973c..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/StringCharacterIterator.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -/** - * Encapsulates String as CharacterIterator. - * - * @author <a href="mailto:ales.novak@netbeans.com">Ales Novak</a> - */ -public final class StringCharacterIterator implements CharacterIterator -{ - /** encapsulated */ - private final String src; - - /** @param src - encapsulated String */ - public StringCharacterIterator(String src) - { - this.src = src; - } - - /** @return a substring */ - public String substring(int beginIndex, int endIndex) - { - return src.substring(beginIndex, endIndex); - } - - /** @return a substring */ - public String substring(int beginIndex) - { - return src.substring(beginIndex); - } - - /** @return a character at the specified position. */ - public char charAt(int pos) - { - return src.charAt(pos); - } - - /** @return <tt>true</tt> iff if the specified index is after the end of the character stream */ - public boolean isEnd(int pos) - { - return (pos >= src.length()); - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/recompile.java b/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/recompile.java deleted file mode 100644 index fc0cbb3b977..00000000000 --- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/regexp/internal/recompile.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 1999-2004 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.sun.org.apache.regexp.internal; - -import com.sun.org.apache.regexp.internal.RECompiler; -import com.sun.org.apache.regexp.internal.RESyntaxException; - -/** - * 'recompile' is a command line tool that pre-compiles one or more regular expressions - * for use with the regular expression matcher class 'RE'. For example, the command - * "java recompile a*b" produces output like this: - * - * <pre> - * - * // Pre-compiled regular expression "a*b" - * char[] re1Instructions = - * { - * 0x007c, 0x0000, 0x001a, 0x007c, 0x0000, 0x000d, 0x0041, - * 0x0001, 0x0004, 0x0061, 0x007c, 0x0000, 0x0003, 0x0047, - * 0x0000, 0xfff6, 0x007c, 0x0000, 0x0003, 0x004e, 0x0000, - * 0x0003, 0x0041, 0x0001, 0x0004, 0x0062, 0x0045, 0x0000, - * 0x0000, - * }; - * - * REProgram re1 = new REProgram(re1Instructions); - * - * </pre> - * - * By pasting this output into your code, you can construct a regular expression matcher - * (RE) object directly from the pre-compiled data (the character array re1), thus avoiding - * the overhead of compiling the expression at runtime. For example: - * - * <pre> - * - * RE r = new RE(re1); - * - * </pre> - * - * @see RE - * @see RECompiler - * - * @author <a href="mailto:jonl@muppetlabs.com">Jonathan Locke</a> - */ -public class recompile -{ - /** - * Main application entrypoint. - * @param arg Command line arguments - */ - static public void main(String[] arg) - { - // Create a compiler object - RECompiler r = new RECompiler(); - - // Print usage if arguments are incorrect - if (arg.length <= 0 || arg.length % 2 != 0) - { - System.out.println("Usage: recompile <patternname> <pattern>"); - System.exit(0); - } - - // Loop through arguments, compiling each - for (int i = 0; i < arg.length; i += 2) - { - try - { - // Compile regular expression - String name = arg[i]; - String pattern = arg[i+1]; - String instructions = name + "PatternInstructions"; - - // Output program as a nice, formatted character array - System.out.print("\n // Pre-compiled regular expression '" + pattern + "'\n" - + " private static char[] " + instructions + " = \n {"); - - // Compile program for pattern - REProgram program = r.compile(pattern); - - // Number of columns in output - int numColumns = 7; - - // Loop through program - char[] p = program.getInstructions(); - for (int j = 0; j < p.length; j++) - { - // End of column? - if ((j % numColumns) == 0) - { - System.out.print("\n "); - } - - // Print character as padded hex number - String hex = Integer.toHexString(p[j]); - while (hex.length() < 4) - { - hex = "0" + hex; - } - System.out.print("0x" + hex + ", "); - } - - // End of program block - System.out.println("\n };"); - System.out.println("\n private static RE " + name + "Pattern = new RE(new REProgram(" + instructions + "));"); - } - catch (RESyntaxException e) - { - System.out.println("Syntax error in expression \"" + arg[i] + "\": " + e.toString()); - } - catch (Exception e) - { - System.out.println("Unexpected exception: " + e.toString()); - } - catch (Error e) - { - System.out.println("Internal error: " + e.toString()); - } - } - } -} diff --git a/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java b/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java index 8262111f444..f3b9b50397a 100644 --- a/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java +++ b/jaxp/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, 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 @@ -1345,6 +1345,15 @@ public final class XMLStreamWriterImpl extends AbstractMap implements XMLStreamW } } + /** + * Writes character reference in hex format. + */ + private void writeCharRef(int codePoint) throws IOException { + fWriter.write( "&#x" ); + fWriter.write( Integer.toHexString(codePoint) ); + fWriter.write( ';' ); + } + /** * Writes XML content to underlying writer. Escapes characters unless * escaping character feature is turned off. @@ -1368,10 +1377,14 @@ public final class XMLStreamWriterImpl extends AbstractMap implements XMLStreamW if (fEncoder != null && !fEncoder.canEncode(ch)){ fWriter.write(content, startWritePos, index - startWritePos ); - // Escape this char as underlying encoder cannot handle it - fWriter.write( "&#x" ); - fWriter.write(Integer.toHexString(ch)); - fWriter.write( ';' ); + // Check if current and next characters forms a surrogate pair + // and escape it to avoid generation of invalid xml content + if ( index != end - 1 && Character.isSurrogatePair(ch, content[index+1])) { + writeCharRef(Character.toCodePoint(ch, content[index+1])); + index++; + } else { + writeCharRef(ch); + } startWritePos = index + 1; continue; } @@ -1439,10 +1452,15 @@ public final class XMLStreamWriterImpl extends AbstractMap implements XMLStreamW if (fEncoder != null && !fEncoder.canEncode(ch)){ fWriter.write(content, startWritePos, index - startWritePos ); - // Escape this char as underlying encoder cannot handle it - fWriter.write( "&#x" ); - fWriter.write(Integer.toHexString(ch)); - fWriter.write( ';' ); + // Check if current and next characters forms a surrogate pair + // and escape it to avoid generation of invalid xml content + if ( index != end - 1 && Character.isSurrogatePair(ch, content.charAt(index+1))) { + writeCharRef(Character.toCodePoint(ch, content.charAt(index+1))); + index++; + } else { + writeCharRef(ch); + } + startWritePos = index + 1; continue; } diff --git a/jaxp/src/java.xml/share/classes/module-info.java b/jaxp/src/java.xml/share/classes/module-info.java index 3bd3fa340e7..ed48672adfc 100644 --- a/jaxp/src/java.xml/share/classes/module-info.java +++ b/jaxp/src/java.xml/share/classes/module-info.java @@ -86,5 +86,6 @@ module java.xml { uses javax.xml.transform.TransformerFactory; uses javax.xml.validation.SchemaFactory; uses javax.xml.xpath.XPathFactory; + uses org.xml.sax.XMLReader; } diff --git a/jaxp/src/java.xml/share/classes/org/xml/sax/AttributeList.java b/jaxp/src/java.xml/share/classes/org/xml/sax/AttributeList.java index 3b9f0f0f376..f79d5067c31 100644 --- a/jaxp/src/java.xml/share/classes/org/xml/sax/AttributeList.java +++ b/jaxp/src/java.xml/share/classes/org/xml/sax/AttributeList.java @@ -93,6 +93,7 @@ package org.xml.sax; * @see org.xml.sax.DocumentHandler#startElement startElement * @see org.xml.sax.helpers.AttributeListImpl AttributeListImpl */ +@Deprecated(since="5") public interface AttributeList { diff --git a/jaxp/src/java.xml/share/classes/org/xml/sax/DocumentHandler.java b/jaxp/src/java.xml/share/classes/org/xml/sax/DocumentHandler.java index 0c8b93b85b2..91cdac156ca 100644 --- a/jaxp/src/java.xml/share/classes/org/xml/sax/DocumentHandler.java +++ b/jaxp/src/java.xml/share/classes/org/xml/sax/DocumentHandler.java @@ -68,6 +68,7 @@ package org.xml.sax; * @see org.xml.sax.Locator * @see org.xml.sax.HandlerBase */ +@Deprecated(since="5") public interface DocumentHandler { diff --git a/jaxp/src/java.xml/share/classes/org/xml/sax/Parser.java b/jaxp/src/java.xml/share/classes/org/xml/sax/Parser.java index 099df32951b..fef6e44843b 100644 --- a/jaxp/src/java.xml/share/classes/org/xml/sax/Parser.java +++ b/jaxp/src/java.xml/share/classes/org/xml/sax/Parser.java @@ -73,6 +73,7 @@ import java.util.Locale; * @see org.xml.sax.HandlerBase * @see org.xml.sax.InputSource */ +@Deprecated(since="5") public interface Parser { diff --git a/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/NewInstance.java b/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/NewInstance.java index c3516b17b5a..acd3996d014 100644 --- a/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/NewInstance.java +++ b/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/NewInstance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,8 +32,7 @@ package org.xml.sax.helpers; -import java.lang.reflect.Method; -import java.lang.reflect.InvocationTargetException; +import java.util.Objects; /** * Create a new instance of a class by name. @@ -57,31 +56,26 @@ import java.lang.reflect.InvocationTargetException; * @version 2.0.1 (sax2r2) */ class NewInstance { + private static final String DEFAULT_PACKAGE = "com.sun.org.apache.xerces.internal"; /** * Creates a new instance of the specified class name * * Package private so this code is not exposed at the API level. */ - static Object newInstance (ClassLoader classLoader, String className) + static <T> T newInstance (Class<T> type, ClassLoader loader, String clsName) throws ClassNotFoundException, IllegalAccessException, InstantiationException { - // make sure we have access to restricted packages - boolean internal = false; - if (System.getSecurityManager() != null) { - if (className != null && className.startsWith(DEFAULT_PACKAGE)) { - internal = true; - } + ClassLoader classLoader = Objects.requireNonNull(loader); + String className = Objects.requireNonNull(clsName); + + if (className.startsWith(DEFAULT_PACKAGE)) { + return type.cast(new com.sun.org.apache.xerces.internal.parsers.SAXParser()); } - Class driverClass; - if (classLoader == null || internal) { - driverClass = Class.forName(className); - } else { - driverClass = classLoader.loadClass(className); - } - return driverClass.newInstance(); + Class<?> driverClass = classLoader.loadClass(className); + return type.cast(driverClass.newInstance()); } } diff --git a/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/ParserFactory.java b/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/ParserFactory.java index efbefe01509..6e658867220 100644 --- a/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/ParserFactory.java +++ b/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/ParserFactory.java @@ -30,8 +30,6 @@ package org.xml.sax.helpers; -import org.xml.sax.Parser; - /** * Java-specific class for dynamically loading SAX parsers. @@ -65,6 +63,8 @@ import org.xml.sax.Parser; * @author David Megginson * @version 2.0.1 (sax2r2) */ +@SuppressWarnings( "deprecation" ) +@Deprecated(since="5") public class ParserFactory { private static SecuritySupport ss = new SecuritySupport(); @@ -97,7 +97,7 @@ public class ParserFactory { * @see #makeParser(java.lang.String) * @see org.xml.sax.Parser */ - public static Parser makeParser () + public static org.xml.sax.Parser makeParser () throws ClassNotFoundException, IllegalAccessException, InstantiationException, @@ -134,14 +134,13 @@ public class ParserFactory { * @see #makeParser() * @see org.xml.sax.Parser */ - public static Parser makeParser (String className) + public static org.xml.sax.Parser makeParser (String className) throws ClassNotFoundException, IllegalAccessException, InstantiationException, ClassCastException { - return (Parser) NewInstance.newInstance ( - ss.getContextClassLoader(), className); + return NewInstance.newInstance (org.xml.sax.Parser.class, ss.getClassLoader(), className); } } diff --git a/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/SecuritySupport.java b/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/SecuritySupport.java index ecd5696942d..3d753b1dcd3 100644 --- a/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/SecuritySupport.java +++ b/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/SecuritySupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,72 +37,56 @@ import java.security.*; */ class SecuritySupport { - - ClassLoader getContextClassLoader() throws SecurityException{ - return (ClassLoader) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - ClassLoader cl = null; - //try { - cl = Thread.currentThread().getContextClassLoader(); - //} catch (SecurityException ex) { } - - if (cl == null) - cl = ClassLoader.getSystemClassLoader(); - - return cl; + /** + * Returns the current thread's context class loader, or the system class loader + * if the context class loader is null. + * @return the current thread's context class loader, or the system class loader + * @throws SecurityException + */ + ClassLoader getClassLoader() throws SecurityException{ + return AccessController.doPrivileged((PrivilegedAction<ClassLoader>)() -> { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if (cl == null) { + cl = ClassLoader.getSystemClassLoader(); } + + return cl; }); } String getSystemProperty(final String propName) { - return (String) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return System.getProperty(propName); - } - }); + return AccessController.doPrivileged((PrivilegedAction<String>)() + -> System.getProperty(propName)); } FileInputStream getFileInputStream(final File file) throws FileNotFoundException { try { - return (FileInputStream) - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws FileNotFoundException { - return new FileInputStream(file); - } - }); + return AccessController.doPrivileged((PrivilegedExceptionAction<FileInputStream>)() -> + new FileInputStream(file)); } catch (PrivilegedActionException e) { throw (FileNotFoundException)e.getException(); } } - InputStream getResourceAsStream(final ClassLoader cl, - final String name) + + InputStream getResourceAsStream(final ClassLoader cl, final String name) { - return (InputStream) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - InputStream ris; - if (cl == null) { - ris = SecuritySupport.class.getResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - } - }); + return AccessController.doPrivileged((PrivilegedAction<InputStream>) () -> { + InputStream ris; + if (cl == null) { + ris = SecuritySupport.class.getResourceAsStream(name); + } else { + ris = cl.getResourceAsStream(name); + } + return ris; + }); } boolean doesFileExist(final File f) { - return ((Boolean) - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return new Boolean(f.exists()); - } - })).booleanValue(); + return (AccessController.doPrivileged((PrivilegedAction<Boolean>)() -> + new Boolean(f.exists()))); } } diff --git a/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java b/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java index 9635e4cf777..6b183ff7350 100644 --- a/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java +++ b/jaxp/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,10 +32,17 @@ package org.xml.sax.helpers; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import org.xml.sax.XMLReader; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Iterator; +import java.util.Objects; +import java.util.ServiceConfigurationError; +import java.util.ServiceLoader; import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; /** @@ -70,7 +77,11 @@ import org.xml.sax.SAXException; * @since 1.4, SAX 2.0 * @author David Megginson, David Brownell * @version 2.0.1 (sax2r2) + * + * @deprecated It is recommended to use {@link javax.xml.parsers.SAXParserFactory} + * instead. */ +@Deprecated(since="9") final public class XMLReaderFactory { /** @@ -83,47 +94,43 @@ final public class XMLReaderFactory } private static final String property = "org.xml.sax.driver"; - private static SecuritySupport ss = new SecuritySupport(); + private static final SecuritySupport ss = new SecuritySupport(); - private static String _clsFromJar = null; - private static boolean _jarread = false; /** - * Attempt to create an XMLReader from system defaults. - * In environments which can support it, the name of the XMLReader - * class is determined by trying each these options in order, and - * using the first one which succeeds: - * <ul> - * + * Obtains a new instance of a {@link org.xml.sax.XMLReader}. + * This method uses the following ordered lookup procedure to find and load + * the {@link org.xml.sax.XMLReader} implementation class: + * <p> + * <ol> * <li>If the system property {@code org.xml.sax.driver} * has a value, that is used as an XMLReader class name. </li> + * <li> + * Use the service-provider loading facility, defined by the + * {@link java.util.ServiceLoader} class, to attempt to locate and load an + * implementation of the service {@link org.xml.sax.XMLReader} by using the + * {@linkplain java.lang.Thread#getContextClassLoader() current thread's context class loader}. + * If the context class loader is null, the + * {@linkplain ClassLoader#getSystemClassLoader() system class loader} will + * be used. + * </li> + * <li> + * Deprecated. Look for a class name in the {@code META-INF/services/org.xml.sax.driver} + * file in a jar file available to the runtime.</li> + * <li> + * <p> + * Otherwise, the system-default implementation is returned. + * </li> + * </ol> * - * <li>The JAR "Services API" is used to look for a class name - * in the <em>META-INF/services/org.xml.sax.driver</em> file in - * jarfiles available to the runtime.</li> + * @apiNote + * The process that looks for a class name in the + * {@code META-INF/services/org.xml.sax.driver} file in a jar file does not + * conform to the specification of the service-provider loading facility + * as defined in {@link java.util.ServiceLoader} and therefore does not + * support modularization. It is deprecated as of Java SE 9 and subject to + * removal in a future release. * - * <li> SAX parser distributions are strongly encouraged to provide - * a default XMLReader class name that will take effect only when - * previous options (on this list) are not successful.</li> - * - * <li>Finally, if {@link ParserFactory#makeParser()} can - * return a system default SAX1 parser, that parser is wrapped in - * a {@link ParserAdapter}. (This is a migration aid for SAX1 - * environments, where the {@code org.xml.sax.parser} system - * property will often be usable.) </li> - * </ul> - * - * <p> In environments such as small embedded systems, which can not - * support that flexibility, other mechanisms to determine the default - * may be used. - * - * <p>Note that many Java environments allow system properties to be - * initialized on a command line. This means that <em>in most cases</em> - * setting a good value for that property ensures that calls to this - * method will succeed, except when security policies intervene. - * This will also maximize application portability to older SAX - * environments, with less robust implementations of this method. - * - * @return A new XMLReader. + * @return a new XMLReader. * @exception org.xml.sax.SAXException If no default XMLReader class * can be identified and instantiated. * @see #createXMLReader(java.lang.String) @@ -132,7 +139,7 @@ final public class XMLReaderFactory throws SAXException { String className = null; - ClassLoader cl = ss.getContextClassLoader(); + ClassLoader cl = ss.getClassLoader(); // 1. try the JVM-instance-wide system property try { @@ -140,62 +147,26 @@ final public class XMLReaderFactory } catch (RuntimeException e) { /* continue searching */ } - // 2. if that fails, try META-INF/services/ + // 2. try the ServiceLoader if (className == null) { - if (!_jarread) { - _jarread = true; - String service = "META-INF/services/" + property; - InputStream in; - BufferedReader reader; - - try { - if (cl != null) { - in = ss.getResourceAsStream(cl, service); - - // If no provider found then try the current ClassLoader - if (in == null) { - cl = null; - in = ss.getResourceAsStream(cl, service); - } - } else { - // No Context ClassLoader, try the current ClassLoader - in = ss.getResourceAsStream(cl, service); - } - - if (in != null) { - reader = new BufferedReader (new InputStreamReader (in, "UTF8")); - _clsFromJar = reader.readLine (); - in.close (); - } - } catch (Exception e) { - } + final XMLReader provider = findServiceProvider(XMLReader.class, cl); + if (provider != null) { + return provider; } - className = _clsFromJar; } - // 3. Distro-specific fallback + // 3. try META-INF/services/org.xml.sax.driver. This old process allows + // legacy providers to be found if (className == null) { -// BEGIN DISTRIBUTION-SPECIFIC - - // EXAMPLE: - // className = "com.example.sax.XmlReader"; - // or a $JAVA_HOME/jre/lib/*properties setting... - className = "com.sun.org.apache.xerces.internal.parsers.SAXParser"; - -// END DISTRIBUTION-SPECIFIC + className = jarLookup(cl); } - // do we know the XMLReader implementation class yet? - if (className != null) - return loadClass (cl, className); - - // 4. panic -- adapt any SAX1 parser - try { - return new ParserAdapter (ParserFactory.makeParser ()); - } catch (Exception e) { - throw new SAXException ("Can't create default XMLReader; " - + "is system property org.xml.sax.driver set?"); + // 4. Distro-specific fallback + if (className == null) { + return new com.sun.org.apache.xerces.internal.parsers.SAXParser(); } + + return loadClass (cl, className); } @@ -217,14 +188,14 @@ final public class XMLReaderFactory public static XMLReader createXMLReader (String className) throws SAXException { - return loadClass (ss.getContextClassLoader(), className); + return loadClass (ss.getClassLoader(), className); } private static XMLReader loadClass (ClassLoader loader, String className) throws SAXException { try { - return (XMLReader) NewInstance.newInstance (loader, className); + return NewInstance.newInstance (XMLReader.class, loader, className); } catch (ClassNotFoundException e1) { throw new SAXException("SAX2 driver class " + className + " not found", e1); @@ -240,4 +211,64 @@ final public class XMLReaderFactory " does not implement XMLReader", e4); } } + + /** + * Locates a provider by directly reading the jar service file. + * @param loader the ClassLoader to be used to read the service file + * @return the name of the provider, or null if nothing is found + */ + private static String jarLookup(final ClassLoader loader) { + final ClassLoader cl = Objects.requireNonNull(loader); + String clsFromJar = null; + String service = "META-INF/services/" + property; + InputStream in; + BufferedReader reader; + + try { + in = ss.getResourceAsStream(cl, service); + + // If no provider found then try the current ClassLoader + if (in == null) { + in = ss.getResourceAsStream(null, service); + } + + if (in != null) { + reader = new BufferedReader (new InputStreamReader (in, "UTF8")); + clsFromJar = reader.readLine (); + in.close (); + } + } catch (IOException e) { + } + return clsFromJar; + } + + /* + * Try to find provider using the ServiceLoader API + * + * @param type Base class / Service interface of the factory to find. + * + * @return instance of provider class if found or null + */ + private static <T> T findServiceProvider(final Class<T> type, final ClassLoader loader) + throws SAXException { + ClassLoader cl = Objects.requireNonNull(loader); + try { + return AccessController.doPrivileged((PrivilegedAction<T>) () -> { + final ServiceLoader<T> serviceLoader; + serviceLoader = ServiceLoader.load(type, cl); + final Iterator<T> iterator = serviceLoader.iterator(); + if (iterator.hasNext()) { + return iterator.next(); + } else { + return null; + } + }); + } catch(ServiceConfigurationError e) { + final RuntimeException x = new RuntimeException( + "Provider for " + type + " cannot be created", e); + throw new SAXException("Provider for " + type + " cannot be created", x); + + } + } + } diff --git a/jaxp/test/Makefile b/jaxp/test/Makefile index 912f2b98406..bf94d252889 100644 --- a/jaxp/test/Makefile +++ b/jaxp/test/Makefile @@ -76,14 +76,20 @@ endif TEST_ROOT := $(shell $(PWD)) # Root of all test results -ifdef ALT_OUTPUTDIR - ABS_OUTPUTDIR = $(shell $(CD) $(ALT_OUTPUTDIR) && $(PWD)) +ifdef TEST_OUTPUT_DIR + $(shell $(MKDIR) -p $(TEST_OUTPUT_DIR)/jtreg) + ABS_TEST_OUTPUT_DIR := \ + $(shell $(CD) $(TEST_OUTPUT_DIR)/jtreg && $(PWD)) else - ABS_OUTPUTDIR = $(shell $(CD) $(TEST_ROOT)/.. && $(PWD)) -endif + ifdef ALT_OUTPUTDIR + ABS_OUTPUTDIR = $(shell $(CD) $(ALT_OUTPUTDIR) && $(PWD)) + else + ABS_OUTPUTDIR = $(shell $(CD) $(TEST_ROOT)/.. && $(PWD)) + endif -ABS_PLATFORM_BUILD_ROOT = $(ABS_OUTPUTDIR) -ABS_TEST_OUTPUT_DIR := $(ABS_PLATFORM_BUILD_ROOT)/testoutput/$(UNIQUE_DIR) + ABS_PLATFORM_BUILD_ROOT = $(ABS_OUTPUTDIR) + ABS_TEST_OUTPUT_DIR := $(ABS_PLATFORM_BUILD_ROOT)/testoutput/$(UNIQUE_DIR) +endif # Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test) ifndef PRODUCT_HOME diff --git a/jaxp/test/ProblemList.txt b/jaxp/test/ProblemList.txt index c9aaf13d1fb..b6b8b41ba4f 100644 --- a/jaxp/test/ProblemList.txt +++ b/jaxp/test/ProblemList.txt @@ -29,3 +29,5 @@ javax/xml/jaxp/isolatedjdk/catalog/PropertiesTest.sh generic-all # 8150145 javax/xml/jaxp/unittest/common/TransformationWarningsTest.java generic-all +# 8156508 +javax/xml/jaxp/unittest/stream/FactoryFindTest.java generic-all diff --git a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/BasicModularXMLParserTest.java b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/BasicModularXMLParserTest.java index c3403f9d1d0..c2bf928ba1f 100644 --- a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/BasicModularXMLParserTest.java +++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/BasicModularXMLParserTest.java @@ -38,7 +38,7 @@ import org.testng.annotations.Test; * @library /javax/xml/jaxp/libs * @build jdk.testlibrary.* * @run testng BasicModularXMLParserTest - * @bug 8078820 + * @bug 8078820 8156119 * @summary Tests JAXP lib can instantiate the following interfaces * with customized provider module on boot layer * @@ -51,6 +51,7 @@ import org.testng.annotations.Test; * javax.xml.transform.TransformerFactory * javax.xml.validation.SchemaFactory * javax.xml.xpath.XPathFactory + * org.xml.sax.XMLReader */ @Test diff --git a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/LayerModularXMLParserTest.java b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/LayerModularXMLParserTest.java index 45f24001278..3e157679b9e 100644 --- a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/LayerModularXMLParserTest.java +++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/LayerModularXMLParserTest.java @@ -50,7 +50,7 @@ import jdk.testlibrary.CompilerUtils; * @library /javax/xml/jaxp/libs * @build jdk.testlibrary.* * @run testng LayerModularXMLParserTest - * @bug 8078820 + * @bug 8078820 8156119 * @summary Tests JAXP lib works with layer and TCCL */ @@ -75,7 +75,7 @@ public class LayerModularXMLParserTest { * services provided by provider2 */ private static final String[] services2 = { "javax.xml.datatype.DatatypeFactory", - "javax.xml.stream.XMLEventFactory" }; + "javax.xml.stream.XMLEventFactory", "org.xml.sax.XMLReader" }; /* * Compiles all modules used by the test diff --git a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/XMLReaderFactoryTest.java b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/XMLReaderFactoryTest.java new file mode 100644 index 00000000000..ef3507fe9d1 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/XMLReaderFactoryTest.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2016, 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 static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import java.io.File; +import java.net.URL; +import java.net.URLClassLoader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import jdk.testlibrary.CompilerUtils; + +import org.testng.Assert; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.XMLReaderFactory; + +/* + * @test + * @library /javax/xml/jaxp/libs + * @build jdk.testlibrary.* + * @run testng XMLReaderFactoryTest + * @bug 8152912 8015099 8156119 + * @summary Tests XMLReaderFactory can work as ServiceLoader compliant, as well as backward compatible + */ + +@Test +public class XMLReaderFactoryTest { + private static final String TEST_SRC = System.getProperty("test.src"); + + private static final Path SRC_DIR = Paths.get(TEST_SRC, "src").resolve("xmlprovider3"); + private static final Path CLASSES_DIR = Paths.get("classes"); + private static final Path LEGACY_DIR = CLASSES_DIR.resolve("legacy"); + private static final Path SERVICE_DIR = CLASSES_DIR.resolve("service"); + + // resources to copy to the class path + private static final String LEGACY_SERVICE_FILE = "legacy/META-INF/services/org.xml.sax.driver"; + private static final String SERVICE_FILE = "service/META-INF/services/org.xml.sax.XMLReader"; + + /* + * Compile class and copy service files + */ + @BeforeTest + public void setup() throws Exception { + setup(LEGACY_DIR, LEGACY_SERVICE_FILE); + setup(SERVICE_DIR, SERVICE_FILE); + } + + private void setup(Path dest, String serviceFile) throws Exception { + Files.createDirectories(dest); + assertTrue(CompilerUtils.compile(SRC_DIR, dest)); + + Path file = Paths.get(serviceFile.replace('/', File.separatorChar)); + Path source = SRC_DIR.resolve(file); + Path target = CLASSES_DIR.resolve(file); + Files.createDirectories(target.getParent()); + Files.copy(source, target); + + } + + public void testService() throws Exception { + ClassLoader clBackup = Thread.currentThread().getContextClassLoader(); + try { + URL[] classUrls = { SERVICE_DIR.toUri().toURL() }; + URLClassLoader loader = new URLClassLoader(classUrls, ClassLoader.getSystemClassLoader().getParent()); + + // set TCCL and try locating the provider + Thread.currentThread().setContextClassLoader(loader); + XMLReader reader = XMLReaderFactory.createXMLReader(); + assertEquals(reader.getClass().getName(), "xp3.XMLReaderImpl"); + } finally { + Thread.currentThread().setContextClassLoader(clBackup); + } + } + + public void testLegacy() throws Exception { + ClassLoader clBackup = Thread.currentThread().getContextClassLoader(); + try { + URL[] classUrls = { LEGACY_DIR.toUri().toURL() }; + URLClassLoader loader = new URLClassLoader(classUrls, ClassLoader.getSystemClassLoader().getParent()); + + // set TCCL and try locating the provider + Thread.currentThread().setContextClassLoader(loader); + XMLReader reader1 = XMLReaderFactory.createXMLReader(); + assertEquals(reader1.getClass().getName(), "xp3.XMLReaderImpl"); + + // now point to a random URL + Thread.currentThread().setContextClassLoader( + new URLClassLoader(new URL[0], ClassLoader.getSystemClassLoader().getParent())); + // ClassNotFoundException if also trying to load class of reader1, which + // would be the case before 8152912 + XMLReader reader2 = XMLReaderFactory.createXMLReader(); + assertEquals(reader2.getClass().getName(), "com.sun.org.apache.xerces.internal.parsers.SAXParser"); + } finally { + Thread.currentThread().setContextClassLoader(clBackup); + } + } +} diff --git a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/test/test/XMLFactoryHelper.java b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/test/test/XMLFactoryHelper.java index 6dfaec5cedf..4f4a530a288 100644 --- a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/test/test/XMLFactoryHelper.java +++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/test/test/XMLFactoryHelper.java @@ -31,6 +31,8 @@ import java.lang.System; import java.util.Iterator; import java.util.ServiceLoader; +import org.xml.sax.helpers.XMLReaderFactory; + public class XMLFactoryHelper { /* * instantiate a xml factory by reflection e.g. @@ -41,7 +43,9 @@ public class XMLFactoryHelper { try { // set thread context class loader to module class loader Thread.currentThread().setContextClassLoader(XMLFactoryHelper.class.getClassLoader()); - if (serviceName.equals("javax.xml.validation.SchemaFactory")) + if (serviceName.equals("org.xml.sax.XMLReader")) + return XMLReaderFactory.createXMLReader(); + else if (serviceName.equals("javax.xml.validation.SchemaFactory")) return Class.forName(serviceName).getMethod("newInstance", String.class) .invoke(null, W3C_XML_SCHEMA_NS_URI); else diff --git a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/unnamed/Main.java b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/unnamed/Main.java index cb0a37e916b..ee3e3e004d5 100644 --- a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/unnamed/Main.java +++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/unnamed/Main.java @@ -30,6 +30,8 @@ import java.util.HashSet; import java.util.Set; import java.util.stream.Stream; +import org.xml.sax.helpers.XMLReaderFactory; + public class Main { /* * @param args, the names of provider modules, which have been loaded @@ -69,7 +71,9 @@ public class Main { */ private static Object instantiateXMLService(String serviceName) { try { - if (serviceName.equals("javax.xml.validation.SchemaFactory")) + if (serviceName.equals("org.xml.sax.XMLReader")) + return XMLReaderFactory.createXMLReader(); + else if (serviceName.equals("javax.xml.validation.SchemaFactory")) return Class.forName(serviceName).getMethod("newInstance", String.class) .invoke(null, W3C_XML_SCHEMA_NS_URI); else @@ -102,6 +106,7 @@ public class Main { "javax.xml.parsers.DocumentBuilderFactory", "javax.xml.parsers.SAXParserFactory", "javax.xml.stream.XMLEventFactory", "javax.xml.stream.XMLInputFactory", "javax.xml.stream.XMLOutputFactory", "javax.xml.transform.TransformerFactory", - "javax.xml.validation.SchemaFactory", "javax.xml.xpath.XPathFactory" }; + "javax.xml.validation.SchemaFactory", "javax.xml.xpath.XPathFactory", + "org.xml.sax.XMLReader"}; } diff --git a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/module-info.java b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/module-info.java index d55645e58e9..c8bc623aa7a 100644 --- a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/module-info.java +++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/module-info.java @@ -26,4 +26,5 @@ module xmlprovider2 { provides javax.xml.datatype.DatatypeFactory with xp2.DatatypeFactoryImpl; provides javax.xml.stream.XMLEventFactory with xp2.XMLEventFactoryImpl; + provides org.xml.sax.XMLReader with xp2.XMLReaderImpl; } \ No newline at end of file diff --git a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/xp2/XMLReaderImpl.java b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/xp2/XMLReaderImpl.java new file mode 100644 index 00000000000..0b6276f818e --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider2/xp2/XMLReaderImpl.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package xp2; + +import java.io.IOException; + +import org.xml.sax.ContentHandler; +import org.xml.sax.DTDHandler; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.XMLReader; + +public class XMLReaderImpl implements XMLReader { + + @Override + public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { + return false; + } + + @Override + public void setFeature(String name, boolean value) throws SAXNotRecognizedException, + SAXNotSupportedException { + } + + @Override + public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { + return null; + } + + @Override + public void setProperty(String name, Object value) throws SAXNotRecognizedException, + SAXNotSupportedException { + } + + @Override + public void setEntityResolver(EntityResolver resolver) { + // TODO Auto-generated method stub + + } + + @Override + public EntityResolver getEntityResolver() { + return null; + } + + @Override + public void setDTDHandler(DTDHandler handler) { + } + + @Override + public DTDHandler getDTDHandler() { + return null; + } + + @Override + public void setContentHandler(ContentHandler handler) { + } + + @Override + public ContentHandler getContentHandler() { + return null; + } + + @Override + public void setErrorHandler(ErrorHandler handler) { + } + + @Override + public ErrorHandler getErrorHandler() { + return null; + } + + @Override + public void parse(InputSource input) throws IOException, SAXException { + } + + @Override + public void parse(String systemId) throws IOException, SAXException { + } + +} diff --git a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider3/legacy/META-INF/services/org.xml.sax.driver b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider3/legacy/META-INF/services/org.xml.sax.driver new file mode 100644 index 00000000000..ef9ddc888ef --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider3/legacy/META-INF/services/org.xml.sax.driver @@ -0,0 +1 @@ +xp3.XMLReaderImpl diff --git a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider3/service/META-INF/services/org.xml.sax.XMLReader b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider3/service/META-INF/services/org.xml.sax.XMLReader new file mode 100644 index 00000000000..ef9ddc888ef --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider3/service/META-INF/services/org.xml.sax.XMLReader @@ -0,0 +1 @@ +xp3.XMLReaderImpl diff --git a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider3/xp3/XMLReaderImpl.java b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider3/xp3/XMLReaderImpl.java new file mode 100644 index 00000000000..80738a961c1 --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/src/xmlprovider3/xp3/XMLReaderImpl.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package xp3; + +import java.io.IOException; + +import org.xml.sax.ContentHandler; +import org.xml.sax.DTDHandler; +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; +import org.xml.sax.XMLReader; + +public class XMLReaderImpl implements XMLReader { + + @Override + public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { + return false; + } + + @Override + public void setFeature(String name, boolean value) throws SAXNotRecognizedException, + SAXNotSupportedException { + } + + @Override + public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { + return null; + } + + @Override + public void setProperty(String name, Object value) throws SAXNotRecognizedException, + SAXNotSupportedException { + } + + @Override + public void setEntityResolver(EntityResolver resolver) { + // TODO Auto-generated method stub + + } + + @Override + public EntityResolver getEntityResolver() { + return null; + } + + @Override + public void setDTDHandler(DTDHandler handler) { + } + + @Override + public DTDHandler getDTDHandler() { + return null; + } + + @Override + public void setContentHandler(ContentHandler handler) { + } + + @Override + public ContentHandler getContentHandler() { + return null; + } + + @Override + public void setErrorHandler(ErrorHandler handler) { + } + + @Override + public ErrorHandler getErrorHandler() { + return null; + } + + @Override + public void parse(InputSource input) throws IOException, SAXException { + } + + @Override + public void parse(String systemId) throws IOException, SAXException { + } + +} diff --git a/jaxp/test/javax/xml/jaxp/unittest/stream/XMLStreamWriterTest/SurrogatesTest.java b/jaxp/test/javax/xml/jaxp/unittest/stream/XMLStreamWriterTest/SurrogatesTest.java new file mode 100644 index 00000000000..a24c6b8b54f --- /dev/null +++ b/jaxp/test/javax/xml/jaxp/unittest/stream/XMLStreamWriterTest/SurrogatesTest.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2016, 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 stream.XMLStreamWriterTest; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.OutputStreamWriter; + +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamWriter; + +import org.testng.Assert; +import org.testng.annotations.Test; +import org.testng.annotations.DataProvider; + +/* + * @test + * @bug 8145974 + * @modules javax.xml + * @summary Check that XMLStreamWriter generates valid xml with surrogate pair + * used within element text + */ + +public class SurrogatesTest { + + // Test that valid surrogate characters can be written/readen by xml stream + // reader/writer + @Test(dataProvider = "validData") + public void xmlWithValidSurrogatesTest(String content) + throws Exception { + generateAndReadXml(content); + } + + // Test that unbalanced surrogate character will + @Test(dataProvider = "invalidData", + expectedExceptions = XMLStreamException.class) + public void xmlWithUnbalancedSurrogatesTest(String content) + throws Exception { + generateAndReadXml(content); + } + + // Generates xml content with XMLStreamWriter and read it to check + // for correctness of xml and generated data + void generateAndReadXml(String content) throws Exception { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + XMLOutputFactory factory = XMLOutputFactory.newInstance(); + OutputStreamWriter streamWriter = new OutputStreamWriter(stream); + XMLStreamWriter writer = factory.createXMLStreamWriter(streamWriter); + + // Generate xml with selected stream writer type + generateXML(writer, content); + String output = stream.toString(); + System.out.println("Generated xml: " + output); + // Read generated xml with StAX parser + readXML(output.getBytes(), content); + } + + // Generates XML with provided xml stream writer. Provided string + // is inserted into xml twice: with usage of writeCharacters( String ) + // and writeCharacters( char [], int , int ) + private void generateXML(XMLStreamWriter writer, String sequence) + throws XMLStreamException { + char[] seqArr = sequence.toCharArray(); + writer.writeStartDocument(); + writer.writeStartElement("root"); + + // Use writeCharacters( String ) to write characters + writer.writeStartElement("writeCharactersWithString"); + writer.writeCharacters(sequence); + writer.writeEndElement(); + + // Use writeCharacters( char [], int , int ) to write characters + writer.writeStartElement("writeCharactersWithArray"); + writer.writeCharacters(seqArr, 0, seqArr.length); + writer.writeEndElement(); + + // Close root element and document + writer.writeEndElement(); + writer.writeEndDocument(); + writer.flush(); + writer.close(); + } + + // Reads generated XML data and check if it contains expected + // text in writeCharactersWithString and writeCharactersWithArray + // elements + private void readXML(byte[] xmlData, String expectedContent) + throws Exception { + InputStream stream = new ByteArrayInputStream(xmlData); + XMLInputFactory factory = XMLInputFactory.newInstance(); + XMLStreamReader xmlReader + = factory.createXMLStreamReader(stream); + boolean inTestElement = false; + StringBuilder sb = new StringBuilder(); + while (xmlReader.hasNext()) { + String ename; + switch (xmlReader.getEventType()) { + case XMLStreamConstants.START_ELEMENT: + ename = xmlReader.getLocalName(); + if (ename.equals("writeCharactersWithString") + || ename.equals("writeCharactersWithArray")) { + inTestElement = true; + } + break; + case XMLStreamConstants.END_ELEMENT: + ename = xmlReader.getLocalName(); + if (ename.equals("writeCharactersWithString") + || ename.equals("writeCharactersWithArray")) { + inTestElement = false; + String content = sb.toString(); + System.out.println(ename + " text:'" + content + "' expected:'" + expectedContent+"'"); + Assert.assertEquals(content, expectedContent); + sb.setLength(0); + } + break; + case XMLStreamConstants.CHARACTERS: + if (inTestElement) { + sb.append(xmlReader.getText()); + } + break; + } + xmlReader.next(); + } + } + + @DataProvider(name = "validData") + Object[][] getValidData() { + return new Object[][] { + {"Don't Worry Be \uD83D\uDE0A"}, + {"BMP characters \uE000\uFFFD"}, + {"Simple text"}, + }; + } + + @DataProvider(name = "invalidData") + Object[][] getInvalidData() { + return new Object[][] { + {"Unbalanced surrogate \uD83D"}, + {"Unbalanced surrogate \uD83Dis here"}, + {"Surrogate with followup BMP\uD83D\uFFF9"}, + }; + } +} diff --git a/jaxws/.hgtags b/jaxws/.hgtags index 514c6a8ced9..4d92200f4dc 100644 --- a/jaxws/.hgtags +++ b/jaxws/.hgtags @@ -363,3 +363,4 @@ b314bb02182b9ca94708a91f312c377f5435f740 jdk-9+114 4ff86e5489e4c0513dadfa69def8601c110ca5cd jdk-9+115 529f0bf896e58525614d863e283ad155531941cb jdk-9+116 58265b39fc74b932bda4d4f4649c530a89f55c4e jdk-9+117 +6ba73d04589ccc0705a5d8ae5111b63632b6ad20 jdk-9+118 diff --git a/jdk/.hgtags b/jdk/.hgtags index 59c7f91c625..2b6d80debed 100644 --- a/jdk/.hgtags +++ b/jdk/.hgtags @@ -360,3 +360,4 @@ bb8379287f3736f38c52b2d1418784e2592461d1 jdk-9+114 35225b837d66582037eeadeb471c13235dfd793d jdk-9+115 baeb5edb38939cdb78ae0ac6f4fd368465cbf188 jdk-9+116 4da0f73ce03aaf245b92cc040cc0ab0e3fa54dc2 jdk-9+117 +e1eba5cfa5cc8c66d524396a05323dc93568730a jdk-9+118 diff --git a/jdk/make/Import.gmk b/jdk/make/Import.gmk index d479b095514..29e4ce0f19e 100644 --- a/jdk/make/Import.gmk +++ b/jdk/make/Import.gmk @@ -112,7 +112,7 @@ $(BASE_INSTALL_LIBRARIES_HERE)/server/%$(SHARED_LIBRARY_SUFFIX): $(BASE_INSTALL_ $(LN) -s ../$(@F) $@ ifeq ($(OPENJDK_TARGET_OS), macosx) - $(BASE_INSTALL_LIBRARIES_HERE)/server/%.dSYM : $(BASE_INSTALL_LIBRARIES_HERE)/%.dSYM + $(BASE_INSTALL_LIBRARIES_HERE)/server/%.dSYM: $(MKDIR) -p $(@D) $(RM) $@ $(LN) -s ../$(@F) $@ diff --git a/jdk/make/launcher/Launcher-java.base.gmk b/jdk/make/launcher/Launcher-java.base.gmk index 77d241405c3..d5ded27b9ea 100644 --- a/jdk/make/launcher/Launcher-java.base.gmk +++ b/jdk/make/launcher/Launcher-java.base.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011, 2016, 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,11 +25,11 @@ include LauncherCommon.gmk -JAVA_RC_FLAGS += -i $(JDK_TOPDIR)/src/java.base/windows/native/common +JAVA_RC_FLAGS += -I $(JDK_TOPDIR)/src/java.base/windows/native/common ifdef OPENJDK - JAVA_RC_FLAGS += -i "$(JDK_TOPDIR)/src/java.base/windows/native/launcher/icons" + JAVA_RC_FLAGS += -I $(JDK_TOPDIR)/src/java.base/windows/native/launcher/icons else - JAVA_RC_FLAGS += -i "$(JDK_TOPDIR)/src/closed/java.base/windows/native/launcher/icons" + JAVA_RC_FLAGS += -I $(JDK_TOPDIR)/src/closed/java.base/windows/native/launcher/icons endif ################################################################################ diff --git a/jdk/make/lib/Awt2dLibraries.gmk b/jdk/make/lib/Awt2dLibraries.gmk index 57067da008d..b4c6f5e20a3 100644 --- a/jdk/make/lib/Awt2dLibraries.gmk +++ b/jdk/make/lib/Awt2dLibraries.gmk @@ -213,9 +213,9 @@ ifeq ($(OPENJDK_TARGET_OS), windows) endif ifdef OPENJDK - LIBAWT_RC_FLAGS := -i "$(JDK_TOPDIR)/src/java.base/windows/native/launcher/icons" + LIBAWT_RC_FLAGS := -I $(JDK_TOPDIR)/src/java.base/windows/native/launcher/icons else - LIBAWT_RC_FLAGS := -i "$(JDK_TOPDIR)/src/closed/java.base/windows/native/launcher/icons" + LIBAWT_RC_FLAGS := -I $(JDK_TOPDIR)/src/closed/java.base/windows/native/launcher/icons endif LIBAWT_VERSIONINFO_RESOURCE := $(JDK_TOPDIR)/src/java.desktop/windows/native/libawt/windows/awt.rc endif diff --git a/jdk/make/mapfiles/libj2ucrypto/mapfile-vers b/jdk/make/mapfiles/libj2ucrypto/mapfile-vers index 833da53297e..2f2b8d6a4dd 100644 --- a/jdk/make/mapfiles/libj2ucrypto/mapfile-vers +++ b/jdk/make/mapfiles/libj2ucrypto/mapfile-vers @@ -1,5 +1,5 @@ # -# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2012, 2016, 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,28 +30,35 @@ SUNWprivate_1.1 { JNI_OnLoad; Java_com_oracle_security_ucrypto_UcryptoProvider_loadLibraries; Java_com_oracle_security_ucrypto_UcryptoProvider_getMechList; - Java_com_oracle_security_ucrypto_NativeDigest_nativeInit; + Java_com_oracle_security_ucrypto_NativeDigestMD_nativeInit; + Java_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate; + Java_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest; + Java_com_oracle_security_ucrypto_NativeDigestMD_nativeClone; + Java_com_oracle_security_ucrypto_NativeDigestMD_nativeFree; + Java_com_oracle_security_ucrypto_NativeDigest_nativeInit; Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdate; Java_com_oracle_security_ucrypto_NativeDigest_nativeDigest; - Java_com_oracle_security_ucrypto_NativeDigest_nativeClone; Java_com_oracle_security_ucrypto_NativeDigest_nativeFree; - Java_com_oracle_security_ucrypto_NativeCipher_nativeInit; - Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate; - Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal; + Java_com_oracle_security_ucrypto_NativeCipher_nativeInit; + Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdate; + Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal; Java_com_oracle_security_ucrypto_NativeKey_nativeFree; Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit; Java_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit; Java_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit; - Java_com_oracle_security_ucrypto_NativeRSASignature_nativeInit; - Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII; - Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI; - Java_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal; - Java_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic; - + Java_com_oracle_security_ucrypto_NativeRSASignature_nativeInit; + Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII; + Java_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI; + Java_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal; + Java_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic; + JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeInit; + JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate; + JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest; + JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeClone; + JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeFree; JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate; JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest; - JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone; JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree; JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeUpdate; @@ -60,10 +67,10 @@ SUNWprivate_1.1 { JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivate_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPrivateCrt_nativeInit; JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeInit; - JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit; - JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII; - JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI; - JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal; + JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit; + JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZ_3BII; + JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__JZJI; + JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal; JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic; local: diff --git a/jdk/make/mapfiles/libjava/mapfile-vers b/jdk/make/mapfiles/libjava/mapfile-vers index 118b0fd3ddf..693f5a87fb8 100644 --- a/jdk/make/mapfiles/libjava/mapfile-vers +++ b/jdk/make/mapfiles/libjava/mapfile-vers @@ -262,7 +262,7 @@ SUNWprivate_1.1 { Java_jdk_internal_reflect_Reflection_getCallerClass__; Java_jdk_internal_reflect_Reflection_getCallerClass__I; Java_jdk_internal_reflect_Reflection_getClassAccessFlags; - Java_jdk_internal_misc_VM_latestUserDefinedLoader; + Java_jdk_internal_misc_VM_latestUserDefinedLoader0; Java_jdk_internal_misc_VM_getuid; Java_jdk_internal_misc_VM_geteuid; Java_jdk_internal_misc_VM_getgid; diff --git a/jdk/src/java.base/share/classes/java/io/BufferedWriter.java b/jdk/src/java.base/share/classes/java/io/BufferedWriter.java index 28e170fe800..3d8e1ee1b19 100644 --- a/jdk/src/java.base/share/classes/java/io/BufferedWriter.java +++ b/jdk/src/java.base/share/classes/java/io/BufferedWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -153,13 +153,18 @@ public class BufferedWriter extends Writer { * needed. If the requested length is at least as large as the buffer, * however, then this method will flush the buffer and write the characters * directly to the underlying stream. Thus redundant - * <code>BufferedWriter</code>s will not copy data unnecessarily. + * {@code BufferedWriter}s will not copy data unnecessarily. * * @param cbuf A character array * @param off Offset from which to start reading characters * @param len Number of characters to write * - * @exception IOException If an I/O error occurs + * @throws IndexOutOfBoundsException + * If {@code off} is negative, or {@code len} is negative, + * or {@code off + len} is negative or greater than the length + * of the given array + * + * @throws IOException If an I/O error occurs */ public void write(char cbuf[], int off, int len) throws IOException { synchronized (lock) { @@ -195,17 +200,24 @@ public class BufferedWriter extends Writer { /** * Writes a portion of a String. * - * <p> If the value of the {@code len} parameter is negative then no - * characters are written. This is contrary to the specification of this - * method in the {@linkplain java.io.Writer#write(java.lang.String,int,int) - * superclass}, which requires that an {@link IndexOutOfBoundsException} be - * thrown. + * @implSpec + * While the specification of this method in the + * {@linkplain java.io.Writer#write(java.lang.String,int,int) superclass} + * recommends that an {@link IndexOutOfBoundsException} be thrown + * if {@code len} is negative or {@code off + len} is negative, + * the implementation in this class does not throw such an exception in + * these cases but instead simply writes no characters. * * @param s String to be written * @param off Offset from which to start reading characters * @param len Number of characters to be written * - * @exception IOException If an I/O error occurs + * @throws IndexOutOfBoundsException + * If {@code off} is negative, + * or {@code off + len} is greater than the length + * of the given string + * + * @throws IOException If an I/O error occurs */ public void write(String s, int off, int len) throws IOException { synchronized (lock) { diff --git a/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java b/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java index ed27bbae314..773b59614d9 100644 --- a/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java +++ b/jdk/src/java.base/share/classes/java/io/CharArrayWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -91,6 +91,11 @@ class CharArrayWriter extends Writer { * @param c the data to be written * @param off the start offset in the data * @param len the number of chars that are written + * + * @throws IndexOutOfBoundsException + * If {@code off} is negative, or {@code len} is negative, + * or {@code off + len} is negative or greater than the length + * of the given array */ public void write(char c[], int off, int len) { if ((off < 0) || (off > c.length) || (len < 0) || @@ -114,6 +119,11 @@ class CharArrayWriter extends Writer { * @param str String to be written from * @param off Offset from which to start reading characters * @param len Number of characters to be written + * + * @throws IndexOutOfBoundsException + * If {@code off} is negative, or {@code len} is negative, + * or {@code off + len} is negative or greater than the length + * of the given string */ public void write(String str, int off, int len) { synchronized (lock) { diff --git a/jdk/src/java.base/share/classes/java/io/FilterWriter.java b/jdk/src/java.base/share/classes/java/io/FilterWriter.java index 303c674e0c0..8272b3cc8bf 100644 --- a/jdk/src/java.base/share/classes/java/io/FilterWriter.java +++ b/jdk/src/java.base/share/classes/java/io/FilterWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -72,7 +72,12 @@ public abstract class FilterWriter extends Writer { * @param off Offset from which to start reading characters * @param len Number of characters to be written * - * @exception IOException If an I/O error occurs + * @throws IndexOutOfBoundsException + * If the values of the {@code off} and {@code len} parameters + * cause the corresponding method of the underlying {@code Writer} + * to throw an {@code IndexOutOfBoundsException} + * + * @throws IOException If an I/O error occurs */ public void write(char cbuf[], int off, int len) throws IOException { out.write(cbuf, off, len); @@ -85,7 +90,12 @@ public abstract class FilterWriter extends Writer { * @param off Offset from which to start reading characters * @param len Number of characters to be written * - * @exception IOException If an I/O error occurs + * @throws IndexOutOfBoundsException + * If the values of the {@code off} and {@code len} parameters + * cause the corresponding method of the underlying {@code Writer} + * to throw an {@code IndexOutOfBoundsException} + * + * @throws IOException If an I/O error occurs */ public void write(String str, int off, int len) throws IOException { out.write(str, off, len); diff --git a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java index a591136419d..9f13c9216a3 100644 --- a/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java +++ b/jdk/src/java.base/share/classes/java/io/ObjectInputStream.java @@ -603,12 +603,12 @@ public class ObjectInputStream * Class.forName(desc.getName(), false, loader) * </pre> * where <code>loader</code> is determined as follows: if there is a - * method on the current thread's stack whose declaring class was - * defined by a user-defined class loader (and was not a generated to - * implement reflective invocations), then <code>loader</code> is class - * loader corresponding to the closest such method to the currently - * executing frame; otherwise, <code>loader</code> is - * <code>null</code>. If this call results in a + * method on the current thread's stack whose declaring class is not a + * <a href="../lang/ClassLoader.html#builtinLoaders"> + * <em>platform class</em></a>, then <code>loader</code> is + * the class loader of such class; otherwise, <code>loader</code> + * is the {@linkplain ClassLoader#getPlatformClassLoader() + * platform class loader}. If this call results in a * <code>ClassNotFoundException</code> and the name of the passed * <code>ObjectStreamClass</code> instance is the Java language keyword * for a primitive type or void, then the <code>Class</code> object @@ -666,12 +666,15 @@ public class ObjectInputStream * <pre> * Class.forName(i, false, loader) * </pre> - * where <code>loader</code> is that of the first non-<code>null</code> - * class loader up the execution stack, or <code>null</code> if no - * non-<code>null</code> class loaders are on the stack (the same class - * loader choice used by the <code>resolveClass</code> method). Unless any - * of the resolved interfaces are non-public, this same value of - * <code>loader</code> is also the class loader passed to + * where <code>loader</code> is determined as follows: if there is a + * method on the current thread's stack whose declaring class is not a + * <a href="../lang/ClassLoader.html#builtinLoaders"> + * <em>platform class</em></a>, then <code>loader</code> is + * the class loader of such class; otherwise, <code>loader</code> + * is the {@linkplain ClassLoader#getPlatformClassLoader() + * platform class loader}. + * Unless any of the resolved interfaces are non-public, this same value + * of <code>loader</code> is also the class loader passed to * <code>Proxy.getProxyClass</code>; if non-public interfaces are present, * their class loader is passed instead (if more than one non-public * interface class loader is encountered, an @@ -2154,10 +2157,11 @@ public class ObjectInputStream int ndoubles); /** - * Returns the first non-null class loader (not counting class loaders of - * generated reflection implementation classes) up the execution stack, or - * null if only code from the null class loader is on the stack. This - * method is also called via reflection by the following RMI-IIOP class: + * Returns the first non-null and non-platform class loader + * (not counting class loaders of generated reflection implementation classes) + * up the execution stack, or null if only code from the bootstrap and + * platform class loader is on the stack. + * This method is also called via reflection by the following RMI-IIOP class: * * com.sun.corba.se.internal.util.JDKClassLoader * diff --git a/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java b/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java index 0d597e6bef4..4fdb148baaf 100644 --- a/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java +++ b/jdk/src/java.base/share/classes/java/io/OutputStreamWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -202,7 +202,12 @@ public class OutputStreamWriter extends Writer { * @param off Offset from which to start writing characters * @param len Number of characters to write * - * @exception IOException If an I/O error occurs + * @throws IndexOutOfBoundsException + * If {@code off} is negative, or {@code len} is negative, + * or {@code off + len} is negative or greater than the length + * of the given array + * + * @throws IOException If an I/O error occurs */ public void write(char cbuf[], int off, int len) throws IOException { se.write(cbuf, off, len); @@ -215,7 +220,12 @@ public class OutputStreamWriter extends Writer { * @param off Offset from which to start writing characters * @param len Number of characters to write * - * @exception IOException If an I/O error occurs + * @throws IndexOutOfBoundsException + * If {@code off} is negative, or {@code len} is negative, + * or {@code off + len} is negative or greater than the length + * of the given string + * + * @throws IOException If an I/O error occurs */ public void write(String str, int off, int len) throws IOException { se.write(str, off, len); diff --git a/jdk/src/java.base/share/classes/java/io/PipedWriter.java b/jdk/src/java.base/share/classes/java/io/PipedWriter.java index 02201fbec1a..a4534b8604c 100644 --- a/jdk/src/java.base/share/classes/java/io/PipedWriter.java +++ b/jdk/src/java.base/share/classes/java/io/PipedWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -125,19 +125,25 @@ public class PipedWriter extends Writer { } /** - * Writes <code>len</code> characters from the specified character array - * starting at offset <code>off</code> to this piped output stream. + * Writes {@code len} characters from the specified character array + * starting at offset {@code off} to this piped output stream. * This method blocks until all the characters are written to the output * stream. * If a thread was reading data characters from the connected piped input * stream, but the thread is no longer alive, then an - * <code>IOException</code> is thrown. + * {@code IOException} is thrown. * * @param cbuf the data. * @param off the start offset in the data. * @param len the number of characters to write. - * @exception IOException if the pipe is - * <a href=PipedOutputStream.html#BROKEN> <code>broken</code></a>, + * + * @throws IndexOutOfBoundsException + * If {@code off} is negative, or {@code len} is negative, + * or {@code off + len} is negative or greater than the length + * of the given array + * + * @throws IOException if the pipe is + * <a href=PipedOutputStream.html#BROKEN><code>broken</code></a>, * {@link #connect(java.io.PipedReader) unconnected}, closed * or an I/O error occurs. */ diff --git a/jdk/src/java.base/share/classes/java/io/PrintWriter.java b/jdk/src/java.base/share/classes/java/io/PrintWriter.java index 662f930ef90..d516b8ef404 100644 --- a/jdk/src/java.base/share/classes/java/io/PrintWriter.java +++ b/jdk/src/java.base/share/classes/java/io/PrintWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -410,6 +410,11 @@ public class PrintWriter extends Writer { * @param buf Array of characters * @param off Offset from which to start writing characters * @param len Number of characters to write + * + * @throws IndexOutOfBoundsException + * If the values of the {@code off} and {@code len} parameters + * cause the corresponding method of the underlying {@code Writer} + * to throw an {@code IndexOutOfBoundsException} */ public void write(char buf[], int off, int len) { try { @@ -440,6 +445,11 @@ public class PrintWriter extends Writer { * @param s A String * @param off Offset from which to start writing characters * @param len Number of characters to write + * + * @throws IndexOutOfBoundsException + * If the values of the {@code off} and {@code len} parameters + * cause the corresponding method of the underlying {@code Writer} + * to throw an {@code IndexOutOfBoundsException} */ public void write(String s, int off, int len) { try { diff --git a/jdk/src/java.base/share/classes/java/io/StringWriter.java b/jdk/src/java.base/share/classes/java/io/StringWriter.java index 5d1babc3127..15022b353a8 100644 --- a/jdk/src/java.base/share/classes/java/io/StringWriter.java +++ b/jdk/src/java.base/share/classes/java/io/StringWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, 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 @@ -83,6 +83,11 @@ public class StringWriter extends Writer { * @param cbuf Array of characters * @param off Offset from which to start writing characters * @param len Number of characters to write + * + * @throws IndexOutOfBoundsException + * If {@code off} is negative, or {@code len} is negative, + * or {@code off + len} is negative or greater than the length + * of the given array */ public void write(char cbuf[], int off, int len) { if ((off < 0) || (off > cbuf.length) || (len < 0) || @@ -107,6 +112,11 @@ public class StringWriter extends Writer { * @param str String to be written * @param off Offset from which to start writing characters * @param len Number of characters to write + * + * @throws IndexOutOfBoundsException + * If {@code off} is negative, or {@code len} is negative, + * or {@code off + len} is negative or greater than the length + * of the given string */ public void write(String str, int off, int len) { buf.append(str, off, off + len); diff --git a/jdk/src/java.base/share/classes/java/io/Writer.java b/jdk/src/java.base/share/classes/java/io/Writer.java index 5ad5e554fb3..17e8de3ef8a 100644 --- a/jdk/src/java.base/share/classes/java/io/Writer.java +++ b/jdk/src/java.base/share/classes/java/io/Writer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,12 +32,11 @@ package java.io; * Most subclasses, however, will override some of the methods defined here in * order to provide higher efficiency, additional functionality, or both. * - * @see Writer * @see BufferedWriter * @see CharArrayWriter * @see FilterWriter * @see OutputStreamWriter - * @see FileWriter + * @see FileWriter * @see PipedWriter * @see PrintWriter * @see StringWriter @@ -139,6 +138,12 @@ public abstract class Writer implements Appendable, Closeable, Flushable { * @param len * Number of characters to write * + * @throws IndexOutOfBoundsException + * Implementations should throw this exception + * if {@code off} is negative, or {@code len} is negative, + * or {@code off + len} is negative or greater than the length + * of the given array + * * @throws IOException * If an I/O error occurs */ @@ -160,6 +165,11 @@ public abstract class Writer implements Appendable, Closeable, Flushable { /** * Writes a portion of a string. * + * @implSpec + * The implementation in this class throws an + * {@code IndexOutOfBoundsException} for the indicated conditions; + * overriding methods may choose to do otherwise. + * * @param str * A String * @@ -170,8 +180,9 @@ public abstract class Writer implements Appendable, Closeable, Flushable { * Number of characters to write * * @throws IndexOutOfBoundsException - * If {@code off} is negative, or {@code len} is negative, - * or {@code off+len} is negative or greater than the length + * Implementations should throw this exception + * if {@code off} is negative, or {@code len} is negative, + * or {@code off + len} is negative or greater than the length * of the given string * * @throws IOException diff --git a/jdk/src/java.base/share/classes/java/lang/Thread.java b/jdk/src/java.base/share/classes/java/lang/Thread.java index 54fc27f31b5..310ada1b470 100644 --- a/jdk/src/java.base/share/classes/java/lang/Thread.java +++ b/jdk/src/java.base/share/classes/java/lang/Thread.java @@ -340,6 +340,45 @@ class Thread implements Runnable { sleep(millis); } + /** + * Indicates that the caller is momentarily unable to progress, until the + * occurrence of one or more actions on the part of other activities. By + * invoking this method within each iteration of a spin-wait loop construct, + * the calling thread indicates to the runtime that it is busy-waiting. + * The runtime may take action to improve the performance of invoking + * spin-wait loop constructions. + * <p> + * @apiNote + * As an example consider a method in a class that spins in a loop until + * some flag is set outside of that method. A call to the {@code onSpinWait} + * method should be placed inside the spin loop. + * <pre>{@code + * class EventHandler { + * volatile boolean eventNotificationNotReceived; + * void waitForEventAndHandleIt() { + * while ( eventNotificationNotReceived ) { + * java.lang.Thread.onSpinWait(); + * } + * readAndProcessEvent(); + * } + * + * void readAndProcessEvent() { + * // Read event from some source and process it + * . . . + * } + * } + * }</pre> + * <p> + * The code above would remain correct even if the {@code onSpinWait} + * method was not called at all. However on some architectures the Java + * Virtual Machine may issue the processor instructions to address such + * code patterns in a more beneficial way. + * <p> + * @since 9 + */ + @HotSpotIntrinsicCandidate + public static void onSpinWait() {} + /** * Initializes a Thread with the current AccessControlContext. * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext,boolean) diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java index 08e38987bf2..da1700ffdb1 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java @@ -706,6 +706,9 @@ class InvokerBytecodeGenerator { case ARRAY_STORE: emitArrayStore(name); continue; + case ARRAY_LENGTH: + emitArrayLength(name); + continue; case IDENTITY: assert(name.arguments.length == 1); emitPushArguments(name); @@ -740,15 +743,16 @@ class InvokerBytecodeGenerator { return classFile; } - void emitArrayLoad(Name name) { emitArrayOp(name, Opcodes.AALOAD); } - void emitArrayStore(Name name) { emitArrayOp(name, Opcodes.AASTORE); } + void emitArrayLoad(Name name) { emitArrayOp(name, Opcodes.AALOAD); } + void emitArrayStore(Name name) { emitArrayOp(name, Opcodes.AASTORE); } + void emitArrayLength(Name name) { emitArrayOp(name, Opcodes.ARRAYLENGTH); } void emitArrayOp(Name name, int arrayOpcode) { - assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE; + assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE || arrayOpcode == Opcodes.ARRAYLENGTH; Class<?> elementType = name.function.methodType().parameterType(0).getComponentType(); assert elementType != null; emitPushArguments(name); - if (elementType.isPrimitive()) { + if (arrayOpcode != Opcodes.ARRAYLENGTH && elementType.isPrimitive()) { Wrapper w = Wrapper.forPrimitiveType(elementType); arrayOpcode = arrayInsnOpcode(arrayTypeCode(w), arrayOpcode); } diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java index 29cc430f877..1aca86298fe 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/Invokers.java @@ -95,12 +95,12 @@ class Invokers { /*non-public*/ MethodHandle varHandleMethodInvoker(VarHandle.AccessMode ak) { // TODO cache invoker - return makeVarHandleMethodInvoker(ak); + return makeVarHandleMethodInvoker(ak, false); } /*non-public*/ MethodHandle varHandleMethodExactInvoker(VarHandle.AccessMode ak) { // TODO cache invoker - return makeVarHandleMethodExactInvoker(ak); + return makeVarHandleMethodInvoker(ak, true); } private MethodHandle cachedInvoker(int idx) { @@ -127,26 +127,11 @@ class Invokers { return invoker; } - private MethodHandle makeVarHandleMethodInvoker(VarHandle.AccessMode ak) { + private MethodHandle makeVarHandleMethodInvoker(VarHandle.AccessMode ak, boolean isExact) { MethodType mtype = targetType; MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class); - LambdaForm lform = varHandleMethodGenericInvokerHandleForm(ak.methodName(), mtype); - VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal()); - MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad); - - invoker = invoker.withInternalMemberName(MemberName.makeVarHandleMethodInvoke(ak.methodName(), mtype), false); - assert(checkVarHandleInvoker(invoker)); - - maybeCompileToBytecode(invoker); - return invoker; - } - - private MethodHandle makeVarHandleMethodExactInvoker(VarHandle.AccessMode ak) { - MethodType mtype = targetType; - MethodType invokerType = mtype.insertParameterTypes(0, VarHandle.class); - - LambdaForm lform = varHandleMethodExactInvokerHandleForm(ak.methodName(), mtype); + LambdaForm lform = varHandleMethodInvokerHandleForm(ak.methodName(), mtype, isExact); VarHandle.AccessDescriptor ad = new VarHandle.AccessDescriptor(mtype, ak.at.ordinal(), ak.ordinal()); MethodHandle invoker = BoundMethodHandle.bindSingle(invokerType, lform, ad); @@ -400,59 +385,7 @@ class Invokers { return lform; } - private static LambdaForm varHandleMethodExactInvokerHandleForm(String name, MethodType mtype) { - // TODO Cache form? - - final int THIS_MH = 0; - final int CALL_VH = THIS_MH + 1; - final int ARG_BASE = CALL_VH + 1; - final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); - int nameCursor = ARG_LIMIT; - final int VAD_ARG = nameCursor++; - final int CHECK_TYPE = nameCursor++; - final int GET_MEMBER = nameCursor++; - final int LINKER_CALL = nameCursor++; - - MethodType invokerFormType = mtype.insertParameterTypes(0, VarHandle.class) - .basicType() - .appendParameterTypes(MemberName.class); - - MemberName linker = new MemberName(MethodHandle.class, "linkToStatic", invokerFormType, REF_invokeStatic); - try { - linker = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class); - } catch (ReflectiveOperationException ex) { - throw newInternalError(ex); - } - - Name[] names = new Name[LINKER_CALL + 1]; - names[THIS_MH] = argument(THIS_MH, BasicType.basicType(Object.class)); - names[CALL_VH] = argument(CALL_VH, BasicType.basicType(Object.class)); - for (int i = 0; i < mtype.parameterCount(); i++) { - names[ARG_BASE + i] = argument(ARG_BASE + i, BasicType.basicType(mtype.parameterType(i))); - } - - BoundMethodHandle.SpeciesData speciesData = BoundMethodHandle.speciesData_L(); - names[THIS_MH] = names[THIS_MH].withConstraint(speciesData); - - NamedFunction getter = speciesData.getterFunction(0); - names[VAD_ARG] = new Name(getter, names[THIS_MH]); - - Object[] outArgs = Arrays.copyOfRange(names, CALL_VH, ARG_LIMIT + 1, Object[].class); - - names[CHECK_TYPE] = new Name(NF_checkVarHandleExactType, names[CALL_VH], names[VAD_ARG]); - - names[GET_MEMBER] = new Name(NF_getVarHandleMemberName, names[CALL_VH], names[VAD_ARG]); - outArgs[outArgs.length - 1] = names[GET_MEMBER]; - - names[LINKER_CALL] = new Name(linker, outArgs); - LambdaForm lform = new LambdaForm(name + ":VarHandle_exactInvoker" + shortenSignature(basicTypeSignature(mtype)), - ARG_LIMIT, names); - - lform.compileToBytecode(); - return lform; - } - - private static LambdaForm varHandleMethodGenericInvokerHandleForm(String name, MethodType mtype) { + private static LambdaForm varHandleMethodInvokerHandleForm(String name, MethodType mtype, boolean isExact) { // TODO Cache form? final int THIS_MH = 0; @@ -477,8 +410,11 @@ class Invokers { NamedFunction getter = speciesData.getterFunction(0); names[VAD_ARG] = new Name(getter, names[THIS_MH]); - names[CHECK_TYPE] = new Name(NF_checkVarHandleGenericType, names[CALL_VH], names[VAD_ARG]); - + if (isExact) { + names[CHECK_TYPE] = new Name(NF_checkVarHandleExactType, names[CALL_VH], names[VAD_ARG]); + } else { + names[CHECK_TYPE] = new Name(NF_checkVarHandleGenericType, names[CALL_VH], names[VAD_ARG]); + } Object[] outArgs = new Object[ARG_LIMIT]; outArgs[0] = names[CHECK_TYPE]; for (int i = 1; i < ARG_LIMIT; i++) { @@ -488,7 +424,8 @@ class Invokers { MethodType outCallType = mtype.insertParameterTypes(0, VarHandle.class) .basicType(); names[LINKER_CALL] = new Name(outCallType, outArgs); - LambdaForm lform = new LambdaForm(name + ":VarHandle_invoker" + shortenSignature(basicTypeSignature(mtype)), + String debugName = isExact ? ":VarHandle_exactInvoker" : ":VarHandle_invoker"; + LambdaForm lform = new LambdaForm(name + debugName + shortenSignature(basicTypeSignature(mtype)), ARG_LIMIT, names); lform.prepare(); @@ -511,21 +448,13 @@ class Invokers { /*non-public*/ static @ForceInline - void checkVarHandleExactType(VarHandle handle, VarHandle.AccessDescriptor ad) { - MethodType erasedTarget = handle.vform.methodType_table[ad.type]; - MethodType erasedSymbolic = ad.symbolicMethodTypeErased; - if (erasedTarget != erasedSymbolic) - throw newWrongMethodTypeException(erasedTarget, erasedSymbolic); - } - - /*non-public*/ static - @ForceInline - MemberName getVarHandleMemberName(VarHandle handle, VarHandle.AccessDescriptor ad) { - MemberName mn = handle.vform.memberName_table[ad.mode]; - if (mn == null) { - throw handle.unsupported(); + MethodHandle checkVarHandleExactType(VarHandle handle, VarHandle.AccessDescriptor ad) { + MethodHandle mh = handle.getMethodHandle(ad.mode); + MethodType mt = mh.type(); + if (mt != ad.symbolicMethodTypeInvoker) { + throw newWrongMethodTypeException(mt, ad.symbolicMethodTypeInvoker); } - return mn; + return mh; } /*non-public*/ static @@ -649,8 +578,7 @@ class Invokers { NF_getCallSiteTarget, NF_checkCustomized, NF_checkVarHandleGenericType, - NF_checkVarHandleExactType, - NF_getVarHandleMemberName; + NF_checkVarHandleExactType; static { try { NamedFunction nfs[] = { @@ -666,8 +594,6 @@ class Invokers { .getDeclaredMethod("checkVarHandleGenericType", VarHandle.class, VarHandle.AccessDescriptor.class)), NF_checkVarHandleExactType = new NamedFunction(Invokers.class .getDeclaredMethod("checkVarHandleExactType", VarHandle.class, VarHandle.AccessDescriptor.class)), - NF_getVarHandleMemberName = new NamedFunction(Invokers.class - .getDeclaredMethod("getVarHandleMemberName", VarHandle.class, VarHandle.AccessDescriptor.class)) }; // Each nf must be statically invocable or we get tied up in our bootstraps. assert(InvokerBytecodeGenerator.isStaticallyInvocable(nfs)); diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java index 782eff613ae..6f2f35b8773 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandleImpl.java @@ -66,25 +66,28 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; /// Factory methods to create method handles: - static MethodHandle makeArrayElementAccessor(Class<?> arrayClass, boolean isSetter) { - if (arrayClass == Object[].class) - return (isSetter ? ArrayAccessor.OBJECT_ARRAY_SETTER : ArrayAccessor.OBJECT_ARRAY_GETTER); + static MethodHandle makeArrayElementAccessor(Class<?> arrayClass, ArrayAccess access) { + if (arrayClass == Object[].class) { + return ArrayAccess.objectAccessor(access); + } if (!arrayClass.isArray()) throw newIllegalArgumentException("not an array: "+arrayClass); MethodHandle[] cache = ArrayAccessor.TYPED_ACCESSORS.get(arrayClass); - int cacheIndex = (isSetter ? ArrayAccessor.SETTER_INDEX : ArrayAccessor.GETTER_INDEX); + int cacheIndex = ArrayAccess.cacheIndex(access); MethodHandle mh = cache[cacheIndex]; if (mh != null) return mh; - mh = ArrayAccessor.getAccessor(arrayClass, isSetter); - MethodType correctType = ArrayAccessor.correctType(arrayClass, isSetter); + mh = ArrayAccessor.getAccessor(arrayClass, access); + MethodType correctType = ArrayAccessor.correctType(arrayClass, access); if (mh.type() != correctType) { assert(mh.type().parameterType(0) == Object[].class); - assert((isSetter ? mh.type().parameterType(2) : mh.type().returnType()) == Object.class); - assert(isSetter || correctType.parameterType(0).getComponentType() == correctType.returnType()); + /* if access == SET */ assert(access != ArrayAccess.SET || mh.type().parameterType(2) == Object.class); + /* if access == GET */ assert(access != ArrayAccess.GET || + (mh.type().returnType() == Object.class && + correctType.parameterType(0).getComponentType() == correctType.returnType())); // safe to view non-strictly, because element type follows from array type mh = mh.viewAsType(correctType, false); } - mh = makeIntrinsic(mh, (isSetter ? Intrinsic.ARRAY_STORE : Intrinsic.ARRAY_LOAD)); + mh = makeIntrinsic(mh, ArrayAccess.intrinsic(access)); // Atomically update accessor cache. synchronized(cache) { if (cache[cacheIndex] == null) { @@ -97,9 +100,52 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; return mh; } + enum ArrayAccess { + GET, SET, LENGTH; + + // As ArrayAccess and ArrayAccessor have a circular dependency, the ArrayAccess properties cannot be stored in + // final fields. + + static String opName(ArrayAccess a) { + switch (a) { + case GET: return "getElement"; + case SET: return "setElement"; + case LENGTH: return "length"; + } + throw new AssertionError(); + } + + static MethodHandle objectAccessor(ArrayAccess a) { + switch (a) { + case GET: return ArrayAccessor.OBJECT_ARRAY_GETTER; + case SET: return ArrayAccessor.OBJECT_ARRAY_SETTER; + case LENGTH: return ArrayAccessor.OBJECT_ARRAY_LENGTH; + } + throw new AssertionError(); + } + + static int cacheIndex(ArrayAccess a) { + switch (a) { + case GET: return ArrayAccessor.GETTER_INDEX; + case SET: return ArrayAccessor.SETTER_INDEX; + case LENGTH: return ArrayAccessor.LENGTH_INDEX; + } + throw new AssertionError(); + } + + static Intrinsic intrinsic(ArrayAccess a) { + switch (a) { + case GET: return Intrinsic.ARRAY_LOAD; + case SET: return Intrinsic.ARRAY_STORE; + case LENGTH: return Intrinsic.ARRAY_LENGTH; + } + throw new AssertionError(); + } + } + static final class ArrayAccessor { - /// Support for array element access - static final int GETTER_INDEX = 0, SETTER_INDEX = 1, INDEX_LIMIT = 2; + /// Support for array element and length access + static final int GETTER_INDEX = 0, SETTER_INDEX = 1, LENGTH_INDEX = 2, INDEX_LIMIT = 3; static final ClassValue<MethodHandle[]> TYPED_ACCESSORS = new ClassValue<MethodHandle[]>() { @Override @@ -107,14 +153,16 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; return new MethodHandle[INDEX_LIMIT]; } }; - static final MethodHandle OBJECT_ARRAY_GETTER, OBJECT_ARRAY_SETTER; + static final MethodHandle OBJECT_ARRAY_GETTER, OBJECT_ARRAY_SETTER, OBJECT_ARRAY_LENGTH; static { MethodHandle[] cache = TYPED_ACCESSORS.get(Object[].class); - cache[GETTER_INDEX] = OBJECT_ARRAY_GETTER = makeIntrinsic(getAccessor(Object[].class, false), Intrinsic.ARRAY_LOAD); - cache[SETTER_INDEX] = OBJECT_ARRAY_SETTER = makeIntrinsic(getAccessor(Object[].class, true), Intrinsic.ARRAY_STORE); + cache[GETTER_INDEX] = OBJECT_ARRAY_GETTER = makeIntrinsic(getAccessor(Object[].class, ArrayAccess.GET), Intrinsic.ARRAY_LOAD); + cache[SETTER_INDEX] = OBJECT_ARRAY_SETTER = makeIntrinsic(getAccessor(Object[].class, ArrayAccess.SET), Intrinsic.ARRAY_STORE); + cache[LENGTH_INDEX] = OBJECT_ARRAY_LENGTH = makeIntrinsic(getAccessor(Object[].class, ArrayAccess.LENGTH), Intrinsic.ARRAY_LENGTH); assert(InvokerBytecodeGenerator.isStaticallyInvocable(ArrayAccessor.OBJECT_ARRAY_GETTER.internalMemberName())); assert(InvokerBytecodeGenerator.isStaticallyInvocable(ArrayAccessor.OBJECT_ARRAY_SETTER.internalMemberName())); + assert(InvokerBytecodeGenerator.isStaticallyInvocable(ArrayAccessor.OBJECT_ARRAY_LENGTH.internalMemberName())); } static int getElementI(int[] a, int i) { return a[i]; } @@ -137,31 +185,47 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; static void setElementC(char[] a, int i, char x) { a[i] = x; } static void setElementL(Object[] a, int i, Object x) { a[i] = x; } - static String name(Class<?> arrayClass, boolean isSetter) { + static int lengthI(int[] a) { return a.length; } + static int lengthJ(long[] a) { return a.length; } + static int lengthF(float[] a) { return a.length; } + static int lengthD(double[] a) { return a.length; } + static int lengthZ(boolean[] a) { return a.length; } + static int lengthB(byte[] a) { return a.length; } + static int lengthS(short[] a) { return a.length; } + static int lengthC(char[] a) { return a.length; } + static int lengthL(Object[] a) { return a.length; } + + static String name(Class<?> arrayClass, ArrayAccess access) { Class<?> elemClass = arrayClass.getComponentType(); if (elemClass == null) throw newIllegalArgumentException("not an array", arrayClass); - return (!isSetter ? "getElement" : "setElement") + Wrapper.basicTypeChar(elemClass); + return ArrayAccess.opName(access) + Wrapper.basicTypeChar(elemClass); } - static MethodType type(Class<?> arrayClass, boolean isSetter) { + static MethodType type(Class<?> arrayClass, ArrayAccess access) { Class<?> elemClass = arrayClass.getComponentType(); Class<?> arrayArgClass = arrayClass; if (!elemClass.isPrimitive()) { arrayArgClass = Object[].class; elemClass = Object.class; } - return !isSetter ? - MethodType.methodType(elemClass, arrayArgClass, int.class) : - MethodType.methodType(void.class, arrayArgClass, int.class, elemClass); + switch (access) { + case GET: return MethodType.methodType(elemClass, arrayArgClass, int.class); + case SET: return MethodType.methodType(void.class, arrayArgClass, int.class, elemClass); + case LENGTH: return MethodType.methodType(int.class, arrayArgClass); + } + throw new IllegalStateException("should not reach here"); } - static MethodType correctType(Class<?> arrayClass, boolean isSetter) { + static MethodType correctType(Class<?> arrayClass, ArrayAccess access) { Class<?> elemClass = arrayClass.getComponentType(); - return !isSetter ? - MethodType.methodType(elemClass, arrayClass, int.class) : - MethodType.methodType(void.class, arrayClass, int.class, elemClass); + switch (access) { + case GET: return MethodType.methodType(elemClass, arrayClass, int.class); + case SET: return MethodType.methodType(void.class, arrayClass, int.class, elemClass); + case LENGTH: return MethodType.methodType(int.class, arrayClass); + } + throw new IllegalStateException("should not reach here"); } - static MethodHandle getAccessor(Class<?> arrayClass, boolean isSetter) { - String name = name(arrayClass, isSetter); - MethodType type = type(arrayClass, isSetter); + static MethodHandle getAccessor(Class<?> arrayClass, ArrayAccess access) { + String name = name(arrayClass, access); + MethodType type = type(arrayClass, access); try { return IMPL_LOOKUP.findStatic(ArrayAccessor.class, name, type); } catch (ReflectiveOperationException ex) { @@ -1282,6 +1346,7 @@ import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP; NEW_ARRAY, ARRAY_LOAD, ARRAY_STORE, + ARRAY_LENGTH, IDENTITY, ZERO, NONE // no intrinsic associated diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index c3a97a178a3..2be727ffb0f 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -2244,6 +2244,20 @@ return mh1; return ani.asType(ani.type().changeReturnType(arrayClass)); } + /** + * Produces a method handle returning the length of an array. + * The type of the method handle will have {@code int} as return type, + * and its sole argument will be the array type. + * @param arrayClass an array type + * @return a method handle which can retrieve the length of an array of the given array type + * @throws NullPointerException if the argument is {@code null} + * @throws IllegalArgumentException if arrayClass is not an array type + */ + public static + MethodHandle arrayLength(Class<?> arrayClass) throws IllegalArgumentException { + return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.LENGTH); + } + /** * Produces a method handle giving read access to elements of an array. * The type of the method handle will have a return type of the array's @@ -2256,7 +2270,7 @@ return mh1; */ public static MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException { - return MethodHandleImpl.makeArrayElementAccessor(arrayClass, false); + return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.GET); } /** @@ -2271,7 +2285,7 @@ return mh1; */ public static MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException { - return MethodHandleImpl.makeArrayElementAccessor(arrayClass, true); + return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.SET); } /** diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java index 78a75bf05cc..ee7be4096bf 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java +++ b/jdk/src/java.base/share/classes/java/lang/invoke/VarHandle.java @@ -26,6 +26,7 @@ package java.lang.invoke; import jdk.internal.HotSpotIntrinsicCandidate; +import jdk.internal.util.Preconditions; import jdk.internal.vm.annotation.ForceInline; import jdk.internal.vm.annotation.Stable; @@ -33,7 +34,6 @@ import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Function; @@ -1475,11 +1475,11 @@ public abstract class VarHandle { TypesAndInvokers tis = getTypesAndInvokers(); MethodHandle mh = tis.methodHandle_table[mode]; if (mh == null) { - mh = tis.methodHandle_table[mode] = getMethodHandleUncached(tis, mode); + mh = tis.methodHandle_table[mode] = getMethodHandleUncached(mode); } return mh; } - private final MethodHandle getMethodHandleUncached(TypesAndInvokers tis, int mode) { + private final MethodHandle getMethodHandleUncached(int mode) { MethodType mt = accessModeType(AccessMode.values()[mode]). insertParameterTypes(0, VarHandle.class); MemberName mn = vform.getMemberName(mode); @@ -1501,7 +1501,7 @@ public abstract class VarHandle { } static final BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException> - AIOOBE_SUPPLIER = Objects.outOfBoundsExceptionFormatter( + AIOOBE_SUPPLIER = Preconditions.outOfBoundsExceptionFormatter( new Function<String, ArrayIndexOutOfBoundsException>() { @Override public ArrayIndexOutOfBoundsException apply(String s) { diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template index 7a058afedec..ebb6dd31b79 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template +++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template @@ -24,9 +24,11 @@ */ package java.lang.invoke; -import java.util.Objects; +import jdk.internal.util.Preconditions; import jdk.internal.vm.annotation.ForceInline; +import java.util.Objects; + import static java.lang.invoke.MethodHandleStatics.UNSAFE; #warn @@ -163,8 +165,7 @@ final class VarHandle$Type$s { @ForceInline static boolean weakCompareAndSetVolatile(FieldInstanceReadWrite handle, Object holder, $type$ expected, $type$ value) { - // TODO defer to strong form until new Unsafe method is added - return UNSAFE.compareAndSwap$Type$(Objects.requireNonNull(handle.receiverType.cast(holder)), + return UNSAFE.weakCompareAndSwap$Type$Volatile(Objects.requireNonNull(handle.receiverType.cast(holder)), handle.fieldOffset, {#if[Object]?handle.fieldType.cast(expected):expected}, {#if[Object]?handle.fieldType.cast(value):value}); @@ -345,8 +346,7 @@ final class VarHandle$Type$s { @ForceInline static boolean weakCompareAndSetVolatile(FieldStaticReadWrite handle, $type$ expected, $type$ value) { - // TODO defer to strong form until new Unsafe method is added - return UNSAFE.compareAndSwap$Type$(handle.base, + return UNSAFE.weakCompareAndSwap$Type$Volatile(handle.base, handle.fieldOffset, {#if[Object]?handle.fieldType.cast(expected):expected}, {#if[Object]?handle.fieldType.cast(value):value}); @@ -447,7 +447,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.get$Type$Volatile(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase); + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase); } @ForceInline @@ -458,7 +458,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] UNSAFE.put$Type$Volatile(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(value):value}); } @@ -470,7 +470,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.get$Type$Opaque(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase); + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase); } @ForceInline @@ -481,7 +481,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] UNSAFE.put$Type$Opaque(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(value):value}); } @@ -493,7 +493,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.get$Type$Acquire(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase); + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase); } @ForceInline @@ -504,7 +504,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] UNSAFE.put$Type$Release(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(value):value}); } #if[CAS] @@ -517,7 +517,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.compareAndSwap$Type$(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(expected):expected}, {#if[Object]?handle.componentType.cast(value):value}); } @@ -530,7 +530,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.compareAndExchange$Type$Volatile(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(expected):expected}, {#if[Object]?handle.componentType.cast(value):value}); } @@ -543,7 +543,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.compareAndExchange$Type$Acquire(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(expected):expected}, {#if[Object]?handle.componentType.cast(value):value}); } @@ -556,7 +556,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.compareAndExchange$Type$Release(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(expected):expected}, {#if[Object]?handle.componentType.cast(value):value}); } @@ -569,7 +569,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.weakCompareAndSwap$Type$(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(expected):expected}, {#if[Object]?handle.componentType.cast(value):value}); } @@ -581,9 +581,8 @@ final class VarHandle$Type$s { #else[Object] $type$[] array = ($type$[]) oarray; #end[Object] - // TODO defer to strong form until new Unsafe method is added - return UNSAFE.compareAndSwap$Type$(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + return UNSAFE.weakCompareAndSwap$Type$Volatile(array, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(expected):expected}, {#if[Object]?handle.componentType.cast(value):value}); } @@ -596,7 +595,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.weakCompareAndSwap$Type$Acquire(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(expected):expected}, {#if[Object]?handle.componentType.cast(value):value}); } @@ -609,7 +608,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.weakCompareAndSwap$Type$Release(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(expected):expected}, {#if[Object]?handle.componentType.cast(value):value}); } @@ -622,7 +621,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.getAndSet$Type$(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, {#if[Object]?handle.componentType.cast(value):value}); } #end[CAS] @@ -636,7 +635,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.getAndAdd$Type$(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, value); } @@ -648,7 +647,7 @@ final class VarHandle$Type$s { $type$[] array = ($type$[]) oarray; #end[Object] return UNSAFE.getAndAdd$Type$(array, - (((long) Objects.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, + (((long) Preconditions.checkIndex(index, array.length, AIOOBE_SUPPLIER)) << handle.ashift) + handle.abase, value) + value; } #end[AtomicAdd] diff --git a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template index 8639e0d342e..66bf267476e 100644 --- a/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template +++ b/jdk/src/java.base/share/classes/java/lang/invoke/X-VarHandleByteArrayView.java.template @@ -25,6 +25,7 @@ package java.lang.invoke; import jdk.internal.misc.Unsafe; +import jdk.internal.util.Preconditions; import jdk.internal.vm.annotation.ForceInline; import java.nio.ByteBuffer; @@ -81,7 +82,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase { @ForceInline static int index(byte[] ba, int index) { - return Objects.checkIndex(index, ba.length - ALIGN, null); + return Preconditions.checkIndex(index, ba.length - ALIGN, null); } @ForceInline @@ -233,8 +234,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase { @ForceInline static boolean weakCompareAndSetVolatile(ArrayHandle handle, Object oba, int index, $type$ expected, $type$ value) { byte[] ba = (byte[]) oba; - // TODO defer to strong form until new Unsafe method is added - return UNSAFE.compareAndSwap$RawType$( + return UNSAFE.weakCompareAndSwap$RawType$Volatile( ba, address(ba, index(ba, index)), convEndian(handle.be, expected), convEndian(handle.be, value)); @@ -271,22 +271,33 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase { #if[AtomicAdd] @ForceInline - static $type$ getAndAdd(ArrayHandle handle, Object oba, int index, $type$ value) { + static $type$ getAndAdd(ArrayHandle handle, Object oba, int index, $type$ delta) { byte[] ba = (byte[]) oba; - return convEndian(handle.be, - UNSAFE.getAndAdd$RawType$( - ba, - address(ba, index(ba, index)), - convEndian(handle.be, value))); + if (handle.be == BE) { + return UNSAFE.getAndAdd$RawType$( + ba, + address(ba, index(ba, index)), + delta); + } else { + return getAndAddConvEndianWithCAS(ba, index, delta); + } } @ForceInline - static $type$ addAndGet(ArrayHandle handle, Object oba, int index, $type$ value) { - byte[] ba = (byte[]) oba; - return convEndian(handle.be, UNSAFE.getAndAdd$RawType$( - ba, - address(ba, index(ba, index)), - convEndian(handle.be, value))) + value; + static $type$ getAndAddConvEndianWithCAS(byte[] ba, int index, $type$ delta) { + $type$ nativeExpectedValue, expectedValue; + long offset = address(ba, index(ba, index)); + do { + nativeExpectedValue = UNSAFE.get$RawType$Volatile(ba, offset); + expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue); + } while (!UNSAFE.weakCompareAndSwap$RawType$Volatile(ba, offset, + nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue + delta))); + return expectedValue; + } + + @ForceInline + static $type$ addAndGet(ArrayHandle handle, Object oba, int index, $type$ delta) { + return getAndAdd(handle, oba, index, delta) + delta; } #end[AtomicAdd] @@ -307,14 +318,14 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase { @ForceInline static int index(ByteBuffer bb, int index) { - return Objects.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null); + return Preconditions.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null); } @ForceInline static int indexRO(ByteBuffer bb, int index) { if (UNSAFE.getBoolean(bb, BYTE_BUFFER_IS_READ_ONLY)) throw new ReadOnlyBufferException(); - return Objects.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null); + return Preconditions.checkIndex(index, UNSAFE.getInt(bb, BUFFER_LIMIT) - ALIGN, null); } @ForceInline @@ -466,8 +477,7 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase { @ForceInline static boolean weakCompareAndSetVolatile(ByteBufferHandle handle, Object obb, int index, $type$ expected, $type$ value) { ByteBuffer bb = (ByteBuffer) obb; - // TODO defer to strong form until new Unsafe method is added - return UNSAFE.compareAndSwap$RawType$( + return UNSAFE.weakCompareAndSwap$RawType$Volatile( UNSAFE.getObject(bb, BYTE_BUFFER_HB), address(bb, indexRO(bb, index)), convEndian(handle.be, expected), convEndian(handle.be, value)); @@ -504,23 +514,34 @@ final class VarHandleByteArrayAs$Type$s extends VarHandleByteArrayBase { #if[AtomicAdd] @ForceInline - static $type$ getAndAdd(ByteBufferHandle handle, Object obb, int index, $type$ value) { + static $type$ getAndAdd(ByteBufferHandle handle, Object obb, int index, $type$ delta) { ByteBuffer bb = (ByteBuffer) obb; - return convEndian(handle.be, - UNSAFE.getAndAdd$RawType$( - UNSAFE.getObject(bb, BYTE_BUFFER_HB), - address(bb, indexRO(bb, index)), - convEndian(handle.be, value))); + if (handle.be == BE) { + return UNSAFE.getAndAdd$RawType$( + UNSAFE.getObject(bb, BYTE_BUFFER_HB), + address(bb, indexRO(bb, index)), + delta); + } else { + return getAndAddConvEndianWithCAS(bb, index, delta); + } } @ForceInline - static $type$ addAndGet(ByteBufferHandle handle, Object obb, int index, $type$ value) { - ByteBuffer bb = (ByteBuffer) obb; - return convEndian(handle.be, - UNSAFE.getAndAdd$RawType$( - UNSAFE.getObject(bb, BYTE_BUFFER_HB), - address(bb, indexRO(bb, index)), - convEndian(handle.be, value))) + value; + static $type$ getAndAddConvEndianWithCAS(ByteBuffer bb, int index, $type$ delta) { + $type$ nativeExpectedValue, expectedValue; + Object base = UNSAFE.getObject(bb, BYTE_BUFFER_HB); + long offset = address(bb, indexRO(bb, index)); + do { + nativeExpectedValue = UNSAFE.get$RawType$Volatile(base, offset); + expectedValue = $RawBoxType$.reverseBytes(nativeExpectedValue); + } while (!UNSAFE.weakCompareAndSwap$RawType$Volatile(base, offset, + nativeExpectedValue, $RawBoxType$.reverseBytes(expectedValue + delta))); + return expectedValue; + } + + @ForceInline + static $type$ addAndGet(ByteBufferHandle handle, Object obb, int index, $type$ delta) { + return getAndAdd(handle, obb, index, delta) + delta; } #end[AtomicAdd] diff --git a/jdk/src/java.base/share/classes/java/nio/Buffer.java b/jdk/src/java.base/share/classes/java/nio/Buffer.java index d534fb3ae73..1f6bef17960 100644 --- a/jdk/src/java.base/share/classes/java/nio/Buffer.java +++ b/jdk/src/java.base/share/classes/java/nio/Buffer.java @@ -111,7 +111,7 @@ import java.util.Spliterator; * to zero. * * - * <h2> Clearing, flipping, and rewinding </h2> + * <h2> Additional operations </h2> * * <p> In addition to methods for accessing the position, limit, and capacity * values and for marking and resetting, this class also defines the following @@ -131,6 +131,12 @@ import java.util.Spliterator; * it already contains: It leaves the limit unchanged and sets the position * to zero. </p></li> * + * <li><p> {@link #slice} creates a subsequence of a buffer: It leaves the + * limit and the position unchanged. </p></li> + * + * <li><p> {@link #duplicate} creates a shallow copy of a buffer: It leaves + * the limit and the position unchanged. </p></li> + * * </ul> * * @@ -567,6 +573,46 @@ public abstract class Buffer { */ public abstract boolean isDirect(); + /** + * Creates a new buffer whose content is a shared subsequence of + * this buffer's content. + * + * <p> The content of the new buffer will start at this buffer's current + * position. Changes to this buffer's content will be visible in the new + * buffer, and vice versa; the two buffers' position, limit, and mark + * values will be independent. + * + * <p> The new buffer's position will be zero, its capacity and its limit + * will be the number of elements remaining in this buffer, its mark will be + * undefined. The new buffer will be direct if, and only if, this buffer is + * direct, and it will be read-only if, and only if, this buffer is + * read-only. </p> + * + * @return The new buffer + * + * @since 9 + */ + public abstract Buffer slice(); + + /** + * Creates a new buffer that shares this buffer's content. + * + * <p> The content of the new buffer will be that of this buffer. Changes + * to this buffer's content will be visible in the new buffer, and vice + * versa; the two buffers' position, limit, and mark values will be + * independent. + * + * <p> The new buffer's capacity, limit, position and mark values will be + * identical to those of this buffer. The new buffer will be direct if, and + * only if, this buffer is direct, and it will be read-only if, and only if, + * this buffer is read-only. </p> + * + * @return The new buffer + * + * @since 9 + */ + public abstract Buffer duplicate(); + // -- Package-private methods for bounds checking, etc. -- diff --git a/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template b/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template index 104f504b551..1292ca458c6 100644 --- a/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template +++ b/jdk/src/java.base/share/classes/java/nio/X-Buffer.java.template @@ -70,8 +70,7 @@ import java.util.stream.$Streamtype$Stream; * #end[byte] * - * <li><p> Methods for {@link #compact compacting}, {@link - * #duplicate duplicating}, and {@link #slice slicing} + * <li><p> A method for {@link #compact compacting} * $a$ $type$ buffer. </p></li> * * </ul> @@ -535,6 +534,7 @@ public abstract class $Type$Buffer * @see #alignedSlice(int) #end[byte] */ + @Override public abstract $Type$Buffer slice(); /** @@ -557,6 +557,7 @@ public abstract class $Type$Buffer * * @return The new $type$ buffer */ + @Override public abstract $Type$Buffer duplicate(); /** diff --git a/jdk/src/java.base/share/classes/java/text/MessageFormat.java b/jdk/src/java.base/share/classes/java/text/MessageFormat.java index f907f4f9bb7..134f84661af 100644 --- a/jdk/src/java.base/share/classes/java/text/MessageFormat.java +++ b/jdk/src/java.base/share/classes/java/text/MessageFormat.java @@ -1068,7 +1068,7 @@ public class MessageFormat extends Format { * index information as described above. * @return An <code>Object</code> array parsed from the string. In case of * error, returns null. - * @throws NullPointerException if {@code source} or {@code pos} is null. + * @throws NullPointerException if {@code pos} is null. */ public Object parseObject(String source, ParsePosition pos) { return parse(source, pos); diff --git a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java index 9810a088b48..ec5fd9c8086 100644 --- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java +++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatter.java @@ -308,6 +308,7 @@ import java.util.Set; * N nano-of-day number 1234000000 * * V time-zone ID zone-id America/Los_Angeles; Z; -08:30 + * v generic time-zone name zone-name Pacific Time; PT * z time-zone name zone-name Pacific Standard Time; PST * O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00 * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15 @@ -365,9 +366,17 @@ import java.util.Set; * letters throws {@code IllegalArgumentException}. * <p> * <b>Zone names</b>: This outputs the display name of the time-zone ID. If the - * count of letters is one, two or three, then the short name is output. If the - * count of letters is four, then the full name is output. Five or more letters - * throws {@code IllegalArgumentException}. + * pattern letter is 'z' the output is the daylight savings aware zone name. + * If there is insufficient information to determine whether DST applies, + * the name ignoring daylight savings time will be used. + * If the count of letters is one, two or three, then the short name is output. + * If the count of letters is four, then the full name is output. + * Five or more letters throws {@code IllegalArgumentException}. + * <p> + * If the pattern letter is 'v' the output provides the zone name ignoring + * daylight savings time. If the count of letters is one, then the short name is output. + * If the count of letters is four, then the full name is output. + * Two, three and five or more letters throw {@code IllegalArgumentException}. * <p> * <b>Offset X and x</b>: This formats the offset based on the number of pattern * letters. One letter outputs just the hour, such as '+01', unless the minute diff --git a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java index 17364aef1e4..f3437950fc8 100644 --- a/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java +++ b/jdk/src/java.base/share/classes/java/time/format/DateTimeFormatterBuilder.java @@ -81,9 +81,11 @@ import java.time.DateTimeException; import java.time.Instant; import java.time.LocalDate; import java.time.LocalDateTime; +import java.time.LocalTime; import java.time.ZoneId; import java.time.ZoneOffset; import java.time.chrono.ChronoLocalDate; +import java.time.chrono.ChronoLocalDateTime; import java.time.chrono.Chronology; import java.time.chrono.Era; import java.time.chrono.IsoChronology; @@ -1157,10 +1159,11 @@ public final class DateTimeFormatterBuilder { * result of {@link ZoneOffset#getId()}. * If the zone is not an offset, the textual name will be looked up * for the locale set in the {@link DateTimeFormatter}. - * If the temporal object being printed represents an instant, then the text - * will be the summer or winter time text as appropriate. + * If the temporal object being printed represents an instant, or if it is a + * local date-time that is not in a daylight saving gap or overlap then + * the text will be the summer or winter time text as appropriate. * If the lookup for text does not find any suitable result, then the - * {@link ZoneId#getId() ID} will be printed instead. + * {@link ZoneId#getId() ID} will be printed. * If the zone cannot be obtained then an exception is thrown unless the * section of the formatter is optional. * <p> @@ -1177,7 +1180,7 @@ public final class DateTimeFormatterBuilder { * @return this, for chaining, not null */ public DateTimeFormatterBuilder appendZoneText(TextStyle textStyle) { - appendInternal(new ZoneTextPrinterParser(textStyle, null)); + appendInternal(new ZoneTextPrinterParser(textStyle, null, false)); return this; } @@ -1193,10 +1196,11 @@ public final class DateTimeFormatterBuilder { * result of {@link ZoneOffset#getId()}. * If the zone is not an offset, the textual name will be looked up * for the locale set in the {@link DateTimeFormatter}. - * If the temporal object being printed represents an instant, then the text + * If the temporal object being printed represents an instant, or if it is a + * local date-time that is not in a daylight saving gap or overlap, then the text * will be the summer or winter time text as appropriate. * If the lookup for text does not find any suitable result, then the - * {@link ZoneId#getId() ID} will be printed instead. + * {@link ZoneId#getId() ID} will be printed. * If the zone cannot be obtained then an exception is thrown unless the * section of the formatter is optional. * <p> @@ -1220,7 +1224,70 @@ public final class DateTimeFormatterBuilder { public DateTimeFormatterBuilder appendZoneText(TextStyle textStyle, Set<ZoneId> preferredZones) { Objects.requireNonNull(preferredZones, "preferredZones"); - appendInternal(new ZoneTextPrinterParser(textStyle, preferredZones)); + appendInternal(new ZoneTextPrinterParser(textStyle, preferredZones, false)); + return this; + } + //---------------------------------------------------------------------- + /** + * Appends the generic time-zone name, such as 'Pacific Time', to the formatter. + * <p> + * This appends an instruction to format/parse the generic textual + * name of the zone to the builder. The generic name is the same throughout the whole + * year, ignoring any daylight saving changes. For example, 'Pacific Time' is the + * generic name, whereas 'Pacific Standard Time' and 'Pacific Daylight Time' are the + * specific names, see {@link #appendZoneText(TextStyle)}. + * <p> + * During formatting, the zone is obtained using a mechanism equivalent + * to querying the temporal with {@link TemporalQueries#zoneId()}. + * If the zone is a {@code ZoneOffset} it will be printed using the + * result of {@link ZoneOffset#getId()}. + * If the zone is not an offset, the textual name will be looked up + * for the locale set in the {@link DateTimeFormatter}. + * If the lookup for text does not find any suitable result, then the + * {@link ZoneId#getId() ID} will be printed. + * If the zone cannot be obtained then an exception is thrown unless the + * section of the formatter is optional. + * <p> + * During parsing, either the textual zone name, the zone ID or the offset + * is accepted. Many textual zone names are not unique, such as CST can be + * for both "Central Standard Time" and "China Standard Time". In this + * situation, the zone id will be determined by the region information from + * formatter's {@link DateTimeFormatter#getLocale() locale} and the standard + * zone id for that area, for example, America/New_York for the America Eastern zone. + * The {@link #appendGenericZoneText(TextStyle, Set)} may be used + * to specify a set of preferred {@link ZoneId} in this situation. + * + * @param textStyle the text style to use, not null + * @return this, for chaining, not null + */ + public DateTimeFormatterBuilder appendGenericZoneText(TextStyle textStyle) { + appendInternal(new ZoneTextPrinterParser(textStyle, null, true)); + return this; + } + + /** + * Appends the generic time-zone name, such as 'Pacific Time', to the formatter. + * <p> + * This appends an instruction to format/parse the generic textual + * name of the zone to the builder. The generic name is the same throughout the whole + * year, ignoring any daylight saving changes. For example, 'Pacific Time' is the + * generic name, whereas 'Pacific Standard Time' and 'Pacific Daylight Time' are the + * specific names, see {@link #appendZoneText(TextStyle)}. + * <p> + * This method also allows a set of preferred {@link ZoneId} to be + * specified for parsing. The matched preferred zone id will be used if the + * textural zone name being parsed is not unique. + * <p> + * See {@link #appendGenericZoneText(TextStyle)} for details about + * formatting and parsing. + * + * @param textStyle the text style to use, not null + * @param preferredZones the set of preferred zone ids, not null + * @return this, for chaining, not null + */ + public DateTimeFormatterBuilder appendGenericZoneText(TextStyle textStyle, + Set<ZoneId> preferredZones) { + appendInternal(new ZoneTextPrinterParser(textStyle, preferredZones, true)); return this; } @@ -1416,6 +1483,7 @@ public final class DateTimeFormatterBuilder { * N nano-of-day number 1234000000 * * V time-zone ID zone-id America/Los_Angeles; Z; -08:30 + * v generic time-zone name zone-name PT, Pacific Time * z time-zone name zone-name Pacific Standard Time; PST * O localized zone-offset offset-O GMT+8; GMT+08:00; UTC-08:00; * X zone-offset 'Z' for zero offset-X Z; -08; -0830; -08:30; -083015; -08:30:15 @@ -1537,6 +1605,8 @@ public final class DateTimeFormatterBuilder { * Pattern Count Equivalent builder methods * ------- ----- -------------------------- * VV 2 appendZoneId() + * v 1 appendGenericZoneText(TextStyle.SHORT) + * vvvv 4 appendGenericZoneText(TextStyle.FULL) * z 1 appendZoneText(TextStyle.SHORT) * zz 2 appendZoneText(TextStyle.SHORT) * zzz 3 appendZoneText(TextStyle.SHORT) @@ -1643,6 +1713,14 @@ public final class DateTimeFormatterBuilder { throw new IllegalArgumentException("Pattern letter count must be 2: " + cur); } appendZoneId(); + } else if (cur == 'v') { + if (count == 1) { + appendGenericZoneText(TextStyle.SHORT); + } else if (count == 4) { + appendGenericZoneText(TextStyle.FULL); + } else { + throw new IllegalArgumentException("Wrong number of pattern letters: " + cur); + } } else if (cur == 'Z') { if (count < 4) { appendOffset("+HHMM", "+0000"); @@ -1894,6 +1972,8 @@ public final class DateTimeFormatterBuilder { // 310 - z - time-zone names, matches LDML and SimpleDateFormat 1 to 4 // 310 - Z - matches SimpleDateFormat and LDML // 310 - V - time-zone id, matches LDML + // 310 - v - general timezone names, not matching exactly with LDML because LDML specify to fall back + // to 'VVVV' if general-nonlocation unavailable but here it's not falling back because of lack of data // 310 - p - prefix for padding // 310 - X - matches LDML, almost matches SDF for 1, exact match 2&3, extended 4&5 // 310 - x - matches LDML @@ -1901,7 +1981,6 @@ public final class DateTimeFormatterBuilder { // LDML - U - cycle year name, not supported by 310 yet // LDML - l - deprecated // LDML - j - not relevant - // LDML - v,V - extended time-zone names } //----------------------------------------------------------------------- @@ -3723,9 +3802,12 @@ public final class DateTimeFormatterBuilder { /** The preferred zoneid map */ private Set<String> preferredZones; - ZoneTextPrinterParser(TextStyle textStyle, Set<ZoneId> preferredZones) { + /** Display in generic time-zone format. True in case of pattern letter 'v' */ + private final boolean isGeneric; + ZoneTextPrinterParser(TextStyle textStyle, Set<ZoneId> preferredZones, boolean isGeneric) { super(TemporalQueries.zone(), "ZoneText(" + textStyle + ")"); this.textStyle = Objects.requireNonNull(textStyle, "textStyle"); + this.isGeneric = isGeneric; if (preferredZones != null && preferredZones.size() != 0) { this.preferredZones = new HashSet<>(); for (ZoneId id : preferredZones) { @@ -3788,11 +3870,21 @@ public final class DateTimeFormatterBuilder { String zname = zone.getId(); if (!(zone instanceof ZoneOffset)) { TemporalAccessor dt = context.getTemporal(); - String name = getDisplayName(zname, - dt.isSupported(ChronoField.INSTANT_SECONDS) - ? (zone.getRules().isDaylightSavings(Instant.from(dt)) ? DST : STD) - : GENERIC, - context.getLocale()); + int type = GENERIC; + if (!isGeneric) { + if (dt.isSupported(ChronoField.INSTANT_SECONDS)) { + type = zone.getRules().isDaylightSavings(Instant.from(dt)) ? DST : STD; + } else if (dt.isSupported(ChronoField.EPOCH_DAY) && + dt.isSupported(ChronoField.NANO_OF_DAY)) { + LocalDate date = LocalDate.ofEpochDay(dt.getLong(ChronoField.EPOCH_DAY)); + LocalTime time = LocalTime.ofNanoOfDay(dt.getLong(ChronoField.NANO_OF_DAY)); + LocalDateTime ldt = date.atTime(time); + if (zone.getRules().getTransition(ldt) == null) { + type = zone.getRules().isDaylightSavings(ldt.atZone(zone).toInstant()) ? DST : STD; + } + } + } + String name = getDisplayName(zname, type, context.getLocale()); if (name != null) { zname = name; } diff --git a/jdk/src/java.base/share/classes/java/time/zone/ZoneRules.java b/jdk/src/java.base/share/classes/java/time/zone/ZoneRules.java index 47190984db1..f6154857b8d 100644 --- a/jdk/src/java.base/share/classes/java/time/zone/ZoneRules.java +++ b/jdk/src/java.base/share/classes/java/time/zone/ZoneRules.java @@ -614,7 +614,7 @@ public final class ZoneRules implements Serializable { * One technique, using this method, would be: * <pre> * ZoneOffsetTransition trans = rules.getTransition(localDT); - * if (trans == null) { + * if (trans != null) { * // Gap or Overlap: determine what to do from transition * } else { * // Normal case: only one valid offset diff --git a/jdk/src/java.base/share/classes/java/util/DualPivotQuicksort.java b/jdk/src/java.base/share/classes/java/util/DualPivotQuicksort.java index fbc0359ed37..97a48ae301c 100644 --- a/jdk/src/java.base/share/classes/java/util/DualPivotQuicksort.java +++ b/jdk/src/java.base/share/classes/java/util/DualPivotQuicksort.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2016, 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 @@ -146,12 +146,26 @@ final class DualPivotQuicksort { } } - // Check special cases - // Implementation note: variable "right" is increased by 1. - if (run[count] == right++) { // The last run contains one element - run[++count] = right; - } else if (count <= 1) { // The array is already sorted + // These invariants should hold true: + // run[0] = 0 + // run[<last>] = right + 1; (terminator) + + if (count == 0) { + // A single equal run return; + } else if (count == 1 && run[count] > right) { + // Either a single ascending or a transformed descending run. + // Always check that a final run is a proper terminator, otherwise + // we have an unterminated trailing run, to handle downstream. + return; + } + right++; + if (run[count] < right) { + // Corner case: the final run is not a terminator. This may happen + // if a final run is an equals run, or there is a single-element run + // at the end. Fix up by adding a proper terminator at the end. + // Note that we terminate with (right + 1), incremented earlier. + run[++count] = right; } // Determine alternation base for merge @@ -598,12 +612,26 @@ final class DualPivotQuicksort { } } - // Check special cases - // Implementation note: variable "right" is increased by 1. - if (run[count] == right++) { // The last run contains one element - run[++count] = right; - } else if (count <= 1) { // The array is already sorted + // These invariants should hold true: + // run[0] = 0 + // run[<last>] = right + 1; (terminator) + + if (count == 0) { + // A single equal run return; + } else if (count == 1 && run[count] > right) { + // Either a single ascending or a transformed descending run. + // Always check that a final run is a proper terminator, otherwise + // we have an unterminated trailing run, to handle downstream. + return; + } + right++; + if (run[count] < right) { + // Corner case: the final run is not a terminator. This may happen + // if a final run is an equals run, or there is a single-element run + // at the end. Fix up by adding a proper terminator at the end. + // Note that we terminate with (right + 1), incremented earlier. + run[++count] = right; } // Determine alternation base for merge @@ -1086,12 +1114,26 @@ final class DualPivotQuicksort { } } - // Check special cases - // Implementation note: variable "right" is increased by 1. - if (run[count] == right++) { // The last run contains one element - run[++count] = right; - } else if (count <= 1) { // The array is already sorted + // These invariants should hold true: + // run[0] = 0 + // run[<last>] = right + 1; (terminator) + + if (count == 0) { + // A single equal run return; + } else if (count == 1 && run[count] > right) { + // Either a single ascending or a transformed descending run. + // Always check that a final run is a proper terminator, otherwise + // we have an unterminated trailing run, to handle downstream. + return; + } + right++; + if (run[count] < right) { + // Corner case: the final run is not a terminator. This may happen + // if a final run is an equals run, or there is a single-element run + // at the end. Fix up by adding a proper terminator at the end. + // Note that we terminate with (right + 1), incremented earlier. + run[++count] = right; } // Determine alternation base for merge @@ -1574,12 +1616,26 @@ final class DualPivotQuicksort { } } - // Check special cases - // Implementation note: variable "right" is increased by 1. - if (run[count] == right++) { // The last run contains one element - run[++count] = right; - } else if (count <= 1) { // The array is already sorted + // These invariants should hold true: + // run[0] = 0 + // run[<last>] = right + 1; (terminator) + + if (count == 0) { + // A single equal run return; + } else if (count == 1 && run[count] > right) { + // Either a single ascending or a transformed descending run. + // Always check that a final run is a proper terminator, otherwise + // we have an unterminated trailing run, to handle downstream. + return; + } + right++; + if (run[count] < right) { + // Corner case: the final run is not a terminator. This may happen + // if a final run is an equals run, or there is a single-element run + // at the end. Fix up by adding a proper terminator at the end. + // Note that we terminate with (right + 1), incremented earlier. + run[++count] = right; } // Determine alternation base for merge @@ -2158,12 +2214,26 @@ final class DualPivotQuicksort { } } - // Check special cases - // Implementation note: variable "right" is increased by 1. - if (run[count] == right++) { // The last run contains one element - run[++count] = right; - } else if (count <= 1) { // The array is already sorted + // These invariants should hold true: + // run[0] = 0 + // run[<last>] = right + 1; (terminator) + + if (count == 0) { + // A single equal run return; + } else if (count == 1 && run[count] > right) { + // Either a single ascending or a transformed descending run. + // Always check that a final run is a proper terminator, otherwise + // we have an unterminated trailing run, to handle downstream. + return; + } + right++; + if (run[count] < right) { + // Corner case: the final run is not a terminator. This may happen + // if a final run is an equals run, or there is a single-element run + // at the end. Fix up by adding a proper terminator at the end. + // Note that we terminate with (right + 1), incremented earlier. + run[++count] = right; } // Determine alternation base for merge @@ -2701,12 +2771,26 @@ final class DualPivotQuicksort { } } - // Check special cases - // Implementation note: variable "right" is increased by 1. - if (run[count] == right++) { // The last run contains one element - run[++count] = right; - } else if (count <= 1) { // The array is already sorted + // These invariants should hold true: + // run[0] = 0 + // run[<last>] = right + 1; (terminator) + + if (count == 0) { + // A single equal run return; + } else if (count == 1 && run[count] > right) { + // Either a single ascending or a transformed descending run. + // Always check that a final run is a proper terminator, otherwise + // we have an unterminated trailing run, to handle downstream. + return; + } + right++; + if (run[count] < right) { + // Corner case: the final run is not a terminator. This may happen + // if a final run is an equals run, or there is a single-element run + // at the end. Fix up by adding a proper terminator at the end. + // Note that we terminate with (right + 1), incremented earlier. + run[++count] = right; } // Determine alternation base for merge diff --git a/jdk/src/java.base/share/classes/java/util/Objects.java b/jdk/src/java.base/share/classes/java/util/Objects.java index 28b39d08969..dad583b9206 100644 --- a/jdk/src/java.base/share/classes/java/util/Objects.java +++ b/jdk/src/java.base/share/classes/java/util/Objects.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,9 @@ package java.util; -import jdk.internal.HotSpotIntrinsicCandidate; +import jdk.internal.util.Preconditions; +import jdk.internal.vm.annotation.ForceInline; -import java.util.function.BiFunction; -import java.util.function.Function; import java.util.function.Supplier; /** @@ -348,172 +347,6 @@ public final class Objects { return obj; } - /** - * Maps out-of-bounds values to a runtime exception. - * - * @param checkKind the kind of bounds check, whose name may correspond - * to the name of one of the range check methods, checkIndex, - * checkFromToIndex, checkFromIndexSize - * @param args the out-of-bounds arguments that failed the range check. - * If the checkKind corresponds a the name of a range check method - * then the bounds arguments are those that can be passed in order - * to the method. - * @param oobef the exception formatter that when applied with a checkKind - * and a list out-of-bounds arguments returns a runtime exception. - * If {@code null} then, it is as if an exception formatter was - * supplied that returns {@link IndexOutOfBoundsException} for any - * given arguments. - * @return the runtime exception - */ - private static RuntimeException outOfBounds( - BiFunction<String, List<Integer>, ? extends RuntimeException> oobef, - String checkKind, - Integer... args) { - List<Integer> largs = List.of(args); - RuntimeException e = oobef == null - ? null : oobef.apply(checkKind, largs); - return e == null - ? new IndexOutOfBoundsException(outOfBoundsMessage(checkKind, largs)) : e; - } - - // Specific out-of-bounds exception producing methods that avoid - // the varargs-based code in the critical methods there by reducing their - // the byte code size, and therefore less likely to peturb inlining - - private static RuntimeException outOfBoundsCheckIndex( - BiFunction<String, List<Integer>, ? extends RuntimeException> oobe, - int index, int length) { - return outOfBounds(oobe, "checkIndex", index, length); - } - - private static RuntimeException outOfBoundsCheckFromToIndex( - BiFunction<String, List<Integer>, ? extends RuntimeException> oobe, - int fromIndex, int toIndex, int length) { - return outOfBounds(oobe, "checkFromToIndex", fromIndex, toIndex, length); - } - - private static RuntimeException outOfBoundsCheckFromIndexSize( - BiFunction<String, List<Integer>, ? extends RuntimeException> oobe, - int fromIndex, int size, int length) { - return outOfBounds(oobe, "checkFromIndexSize", fromIndex, size, length); - } - - /** - * Returns an out-of-bounds exception formatter from an given exception - * factory. The exception formatter is a function that formats an - * out-of-bounds message from its arguments and applies that message to the - * given exception factory to produce and relay an exception. - * - * <p>The exception formatter accepts two arguments: a {@code String} - * describing the out-of-bounds range check that failed, referred to as the - * <em>check kind</em>; and a {@code List<Integer>} containing the - * out-of-bound integer values that failed the check. The list of - * out-of-bound values is not modified. - * - * <p>Three check kinds are supported {@code checkIndex}, - * {@code checkFromToIndex} and {@code checkFromIndexSize} corresponding - * respectively to the specified application of an exception formatter as an - * argument to the out-of-bounds range check methods - * {@link #checkIndex(int, int, BiFunction) checkIndex}, - * {@link #checkFromToIndex(int, int, int, BiFunction) checkFromToIndex}, and - * {@link #checkFromIndexSize(int, int, int, BiFunction) checkFromIndexSize}. - * Thus a supported check kind corresponds to a method name and the - * out-of-bound integer values correspond to method argument values, in - * order, preceding the exception formatter argument (similar in many - * respects to the form of arguments required for a reflective invocation of - * such a range check method). - * - * <p>Formatter arguments conforming to such supported check kinds will - * produce specific exception messages describing failed out-of-bounds - * checks. Otherwise, more generic exception messages will be produced in - * any of the following cases: the check kind is supported but fewer - * or more out-of-bounds values are supplied, the check kind is not - * supported, the check kind is {@code null}, or the list of out-of-bound - * values is {@code null}. - * - * @apiNote - * This method produces an out-of-bounds exception formatter that can be - * passed as an argument to any of the supported out-of-bounds range check - * methods declared by {@code Objects}. For example, a formatter producing - * an {@code ArrayIndexOutOfBoundsException} may be produced and stored on a - * {@code static final} field as follows: - * <pre>{@code - * static final - * BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException> AIOOBEF = - * outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new); - * }</pre> - * The formatter instance {@code AIOOBEF} may be passed as an argument to an - * out-of-bounds range check method, such as checking if an {@code index} - * is within the bounds of a {@code limit}: - * <pre>{@code - * checkIndex(index, limit, AIOOBEF); - * }</pre> - * If the bounds check fails then the range check method will throw an - * {@code ArrayIndexOutOfBoundsException} with an appropriate exception - * message that is a produced from {@code AIOOBEF} as follows: - * <pre>{@code - * AIOOBEF.apply("checkIndex", List.of(index, limit)); - * }</pre> - * - * @param f the exception factory, that produces an exception from a message - * where the message is produced and formatted by the returned - * exception formatter. If this factory is stateless and side-effect - * free then so is the returned formatter. - * Exceptions thrown by the factory are relayed to the caller - * of the returned formatter. - * @param <X> the type of runtime exception to be returned by the given - * exception factory and relayed by the exception formatter - * @return the out-of-bounds exception formatter - */ - public static <X extends RuntimeException> - BiFunction<String, List<Integer>, X> outOfBoundsExceptionFormatter(Function<String, X> f) { - // Use anonymous class to avoid bootstrap issues if this method is - // used early in startup - return new BiFunction<String, List<Integer>, X>() { - @Override - public X apply(String checkKind, List<Integer> args) { - return f.apply(outOfBoundsMessage(checkKind, args)); - } - }; - } - - private static String outOfBoundsMessage(String checkKind, List<Integer> args) { - if (checkKind == null && args == null) { - return String.format("Range check failed"); - } else if (checkKind == null) { - return String.format("Range check failed: %s", args); - } else if (args == null) { - return String.format("Range check failed: %s", checkKind); - } - - int argSize = 0; - switch (checkKind) { - case "checkIndex": - argSize = 2; - break; - case "checkFromToIndex": - case "checkFromIndexSize": - argSize = 3; - break; - default: - } - - // Switch to default if fewer or more arguments than required are supplied - switch ((args.size() != argSize) ? "" : checkKind) { - case "checkIndex": - return String.format("Index %d out-of-bounds for length %d", - args.get(0), args.get(1)); - case "checkFromToIndex": - return String.format("Range [%d, %d) out-of-bounds for length %d", - args.get(0), args.get(1), args.get(2)); - case "checkFromIndexSize": - return String.format("Range [%d, %<d + %d) out-of-bounds for length %d", - args.get(0), args.get(1), args.get(2)); - default: - return String.format("Range check failed: %s %s", checkKind, args); - } - } - /** * Checks if the {@code index} is within the bounds of the range from * {@code 0} (inclusive) to {@code length} (exclusive). @@ -526,72 +359,16 @@ public final class Objects { * <li>{@code length < 0}, which is implied from the former inequalities</li> * </ul> * - * <p>This method behaves as if {@link #checkIndex(int, int, BiFunction)} - * was called with same out-of-bounds arguments and an exception formatter - * argument produced from an invocation of - * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may - * be more efficient). - * * @param index the index * @param length the upper-bound (exclusive) of the range * @return {@code index} if it is within bounds of the range * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds * @since 9 */ + @ForceInline public static int checkIndex(int index, int length) { - return checkIndex(index, length, null); - } - - /** - * Checks if the {@code index} is within the bounds of the range from - * {@code 0} (inclusive) to {@code length} (exclusive). - * - * <p>The {@code index} is defined to be out-of-bounds if any of the - * following inequalities is true: - * <ul> - * <li>{@code index < 0}</li> - * <li>{@code index >= length}</li> - * <li>{@code length < 0}, which is implied from the former inequalities</li> - * </ul> - * - * <p>If the {@code index} is out-of-bounds, then a runtime exception is - * thrown that is the result of applying the following arguments to the - * exception formatter: the name of this method, {@code checkIndex}; - * and an unmodifiable list integers whose values are, in order, the - * out-of-bounds arguments {@code index} and {@code length}. - * - * @param <X> the type of runtime exception to throw if the arguments are - * out-of-bounds - * @param index the index - * @param length the upper-bound (exclusive) of the range - * @param oobef the exception formatter that when applied with this - * method name and out-of-bounds arguments returns a runtime - * exception. If {@code null} or returns {@code null} then, it is as - * if an exception formatter produced from an invocation of - * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used - * instead (though it may be more efficient). - * Exceptions thrown by the formatter are relayed to the caller. - * @return {@code index} if it is within bounds of the range - * @throws X if the {@code index} is out-of-bounds and the exception - * formatter is non-{@code null} - * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds - * and the exception formatter is {@code null} - * @since 9 - * - * @implNote - * This method is made intrinsic in optimizing compilers to guide them to - * perform unsigned comparisons of the index and length when it is known the - * length is a non-negative value (such as that of an array length or from - * the upper bound of a loop) - */ - @HotSpotIntrinsicCandidate - public static <X extends RuntimeException> - int checkIndex(int index, int length, - BiFunction<String, List<Integer>, X> oobef) { - if (index < 0 || index >= length) - throw outOfBoundsCheckIndex(oobef, index, length); - return index; + return Preconditions.checkIndex(index, length, null); } /** @@ -608,12 +385,6 @@ public final class Objects { * <li>{@code length < 0}, which is implied from the former inequalities</li> * </ul> * - * <p>This method behaves as if {@link #checkFromToIndex(int, int, int, BiFunction)} - * was called with same out-of-bounds arguments and an exception formatter - * argument produced from an invocation of - * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may - * be more efficient). - * * @param fromIndex the lower-bound (inclusive) of the sub-range * @param toIndex the upper-bound (exclusive) of the sub-range * @param length the upper-bound (exclusive) the range @@ -623,54 +394,7 @@ public final class Objects { */ public static int checkFromToIndex(int fromIndex, int toIndex, int length) { - return checkFromToIndex(fromIndex, toIndex, length, null); - } - - /** - * Checks if the sub-range from {@code fromIndex} (inclusive) to - * {@code toIndex} (exclusive) is within the bounds of range from {@code 0} - * (inclusive) to {@code length} (exclusive). - * - * <p>The sub-range is defined to be out-of-bounds if any of the following - * inequalities is true: - * <ul> - * <li>{@code fromIndex < 0}</li> - * <li>{@code fromIndex > toIndex}</li> - * <li>{@code toIndex > length}</li> - * <li>{@code length < 0}, which is implied from the former inequalities</li> - * </ul> - * - * <p>If the sub-range is out-of-bounds, then a runtime exception is - * thrown that is the result of applying the following arguments to the - * exception formatter: the name of this method, {@code checkFromToIndex}; - * and an unmodifiable list integers whose values are, in order, the - * out-of-bounds arguments {@code fromIndex}, {@code toIndex}, and {@code length}. - * - * @param <X> the type of runtime exception to throw if the arguments are - * out-of-bounds - * @param fromIndex the lower-bound (inclusive) of the sub-range - * @param toIndex the upper-bound (exclusive) of the sub-range - * @param length the upper-bound (exclusive) the range - * @param oobef the exception formatter that when applied with this - * method name and out-of-bounds arguments returns a runtime - * exception. If {@code null} or returns {@code null} then, it is as - * if an exception formatter produced from an invocation of - * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used - * instead (though it may be more efficient). - * Exceptions thrown by the formatter are relayed to the caller. - * @return {@code fromIndex} if the sub-range within bounds of the range - * @throws X if the sub-range is out-of-bounds and the exception factory - * function is non-{@code null} - * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and - * the exception factory function is {@code null} - * @since 9 - */ - public static <X extends RuntimeException> - int checkFromToIndex(int fromIndex, int toIndex, int length, - BiFunction<String, List<Integer>, X> oobef) { - if (fromIndex < 0 || fromIndex > toIndex || toIndex > length) - throw outOfBoundsCheckFromToIndex(oobef, fromIndex, toIndex, length); - return fromIndex; + return Preconditions.checkFromToIndex(fromIndex, toIndex, length, null); } /** @@ -687,12 +411,6 @@ public final class Objects { * <li>{@code length < 0}, which is implied from the former inequalities</li> * </ul> * - * <p>This method behaves as if {@link #checkFromIndexSize(int, int, int, BiFunction)} - * was called with same out-of-bounds arguments and an exception formatter - * argument produced from an invocation of - * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} (though it may - * be more efficient). - * * @param fromIndex the lower-bound (inclusive) of the sub-interval * @param size the size of the sub-range * @param length the upper-bound (exclusive) of the range @@ -702,54 +420,7 @@ public final class Objects { */ public static int checkFromIndexSize(int fromIndex, int size, int length) { - return checkFromIndexSize(fromIndex, size, length, null); + return Preconditions.checkFromIndexSize(fromIndex, size, length, null); } - /** - * Checks if the sub-range from {@code fromIndex} (inclusive) to - * {@code fromIndex + size} (exclusive) is within the bounds of range from - * {@code 0} (inclusive) to {@code length} (exclusive). - * - * <p>The sub-range is defined to be out-of-bounds if any of the following - * inequalities is true: - * <ul> - * <li>{@code fromIndex < 0}</li> - * <li>{@code size < 0}</li> - * <li>{@code fromIndex + size > length}, taking into account integer overflow</li> - * <li>{@code length < 0}, which is implied from the former inequalities</li> - * </ul> - * - * <p>If the sub-range is out-of-bounds, then a runtime exception is - * thrown that is the result of applying the following arguments to the - * exception formatter: the name of this method, {@code checkFromIndexSize}; - * and an unmodifiable list integers whose values are, in order, the - * out-of-bounds arguments {@code fromIndex}, {@code size}, and - * {@code length}. - * - * @param <X> the type of runtime exception to throw if the arguments are - * out-of-bounds - * @param fromIndex the lower-bound (inclusive) of the sub-interval - * @param size the size of the sub-range - * @param length the upper-bound (exclusive) of the range - * @param oobef the exception formatter that when applied with this - * method name and out-of-bounds arguments returns a runtime - * exception. If {@code null} or returns {@code null} then, it is as - * if an exception formatter produced from an invocation of - * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used - * instead (though it may be more efficient). - * Exceptions thrown by the formatter are relayed to the caller. - * @return {@code fromIndex} if the sub-range within bounds of the range - * @throws X if the sub-range is out-of-bounds and the exception factory - * function is non-{@code null} - * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and - * the exception factory function is {@code null} - * @since 9 - */ - public static <X extends RuntimeException> - int checkFromIndexSize(int fromIndex, int size, int length, - BiFunction<String, List<Integer>, X> oobef) { - if ((length | fromIndex | size) < 0 || size > length - fromIndex) - throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length); - return fromIndex; - } } diff --git a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java index 1cba038d6e5..b97d0cf68c6 100644 --- a/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/jdk/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -462,9 +462,13 @@ class ZipFile implements ZipConstants, Closeable { private class ZipEntryIterator implements Enumeration<ZipEntry>, Iterator<ZipEntry> { private int i = 0; + private final int entryCount; public ZipEntryIterator() { - ensureOpen(); + synchronized (ZipFile.this) { + ensureOpen(); + this.entryCount = zsrc.total; + } } public boolean hasMoreElements() { @@ -472,10 +476,7 @@ class ZipFile implements ZipConstants, Closeable { } public boolean hasNext() { - synchronized (ZipFile.this) { - ensureOpen(); - return i < zsrc.total; - } + return i < entryCount; } public ZipEntry nextElement() { @@ -485,7 +486,7 @@ class ZipFile implements ZipConstants, Closeable { public ZipEntry next() { synchronized (ZipFile.this) { ensureOpen(); - if (i >= zsrc.total) { + if (!hasNext()) { throw new NoSuchElementException(); } // each "entry" has 3 ints in table entries @@ -526,34 +527,34 @@ class ZipFile implements ZipConstants, Closeable { /* Checks ensureOpen() before invoke this method */ private ZipEntry getZipEntry(String name, int pos) { byte[] cen = zsrc.cen; - ZipEntry e = new ZipEntry(); int nlen = CENNAM(cen, pos); int elen = CENEXT(cen, pos); int clen = CENCOM(cen, pos); - e.flag = CENFLG(cen, pos); // get the flag first - if (name != null) { - e.name = name; - } else { - if (!zc.isUTF8() && (e.flag & EFS) != 0) { - e.name = zc.toStringUTF8(cen, pos + CENHDR, nlen); + int flag = CENFLG(cen, pos); + if (name == null) { + if (!zc.isUTF8() && (flag & EFS) != 0) { + name = zc.toStringUTF8(cen, pos + CENHDR, nlen); } else { - e.name = zc.toString(cen, pos + CENHDR, nlen); + name = zc.toString(cen, pos + CENHDR, nlen); } } + ZipEntry e = new ZipEntry(name); + e.flag = flag; e.xdostime = CENTIM(cen, pos); e.crc = CENCRC(cen, pos); e.size = CENLEN(cen, pos); e.csize = CENSIZ(cen, pos); e.method = CENHOW(cen, pos); if (elen != 0) { - e.setExtra0(Arrays.copyOfRange(cen, pos + CENHDR + nlen, - pos + CENHDR + nlen + elen), true); + int start = pos + CENHDR + nlen; + e.setExtra0(Arrays.copyOfRange(cen, start, start + elen), true); } if (clen != 0) { - if (!zc.isUTF8() && (e.flag & EFS) != 0) { - e.comment = zc.toStringUTF8(cen, pos + CENHDR + nlen + elen, clen); + int start = pos + CENHDR + nlen + elen; + if (!zc.isUTF8() && (flag & EFS) != 0) { + e.comment = zc.toStringUTF8(cen, start, clen); } else { - e.comment = zc.toString(cen, pos + CENHDR + nlen + elen, clen); + e.comment = zc.toString(cen, start, clen); } } return e; @@ -817,7 +818,7 @@ class ZipFile implements ZipConstants, Closeable { ); } - /* + /** * Returns an array of strings representing the names of all entries * that begin with "META-INF/" (case ignored). This method is used * in JarFile, via SharedSecrets, as an optimization when looking up @@ -827,14 +828,14 @@ class ZipFile implements ZipConstants, Closeable { private String[] getMetaInfEntryNames() { synchronized (this) { ensureOpen(); - if (zsrc.metanames.size() == 0) { + if (zsrc.metanames == null) { return null; } - String[] names = new String[zsrc.metanames.size()]; + String[] names = new String[zsrc.metanames.length]; byte[] cen = zsrc.cen; for (int i = 0; i < names.length; i++) { - int pos = zsrc.metanames.get(i); - names[i] = new String(cen, pos + CENHDR, CENNAM(cen, pos), + int pos = zsrc.metanames[i]; + names[i] = new String(cen, pos + CENHDR, CENNAM(cen, pos), StandardCharsets.UTF_8); } return names; @@ -850,7 +851,7 @@ class ZipFile implements ZipConstants, Closeable { private long locpos; // position of first LOC header (usually 0) private byte[] comment; // zip file comment // list of meta entries in META-INF dir - private ArrayList<Integer> metanames = new ArrayList<>(); + private int[] metanames; private final boolean startsWithLoc; // true, if zip file starts with LOCSIG (usually true) // A Hashmap for all entries. @@ -1159,7 +1160,7 @@ class ZipFile implements ZipConstants, Closeable { int next = -1; // list for all meta entries - metanames = new ArrayList<>(); + ArrayList<Integer> metanamesList = null; // Iterate through the entries in the central directory int i = 0; @@ -1194,13 +1195,21 @@ class ZipFile implements ZipConstants, Closeable { idx = addEntry(idx, hash, next, pos); // Adds name to metanames. if (isMetaName(cen, pos + CENHDR, nlen)) { - metanames.add(pos); + if (metanamesList == null) + metanamesList = new ArrayList<>(4); + metanamesList.add(pos); } // skip ext and comment pos += (CENHDR + nlen + elen + clen); i++; } total = i; + if (metanamesList != null) { + metanames = new int[metanamesList.size()]; + for (int j = 0, len = metanames.length; j < len; j++) { + metanames[j] = metanamesList.get(j); + } + } if (pos + ENDHDR != cen.length) { zerror("invalid CEN header (bad header size)"); } @@ -1265,30 +1274,23 @@ class ZipFile implements ZipConstants, Closeable { } } - private static byte[] metainf = new byte[] { - 'M', 'E', 'T', 'A', '-', 'I' , 'N', 'F', '/', - }; - - /* - * Returns true if the specified entry's name begins with the string - * "META-INF/" irrespective of case. + /** + * Returns true if the bytes represent a non-directory name + * beginning with "META-INF/", disregarding ASCII case. */ - private static boolean isMetaName(byte[] name, int off, int len) { - if (len < 9 || (name[off] != 'M' && name[off] != 'm')) { // sizeof("META-INF/") - 1 - return false; - } - off++; - for (int i = 1; i < metainf.length; i++) { - byte c = name[off++]; - // Avoid toupper; it's locale-dependent - if (c >= 'a' && c <= 'z') { - c += 'A' - 'a'; - } - if (metainf[i] != c) { - return false; - } - } - return true; + private static boolean isMetaName(byte[] name, int off, int len) { + // Use the "oldest ASCII trick in the book" + return len > 9 // "META-INF/".length() + && name[off + len - 1] != '/' // non-directory + && (name[off++] | 0x20) == 'm' + && (name[off++] | 0x20) == 'e' + && (name[off++] | 0x20) == 't' + && (name[off++] | 0x20) == 'a' + && (name[off++] ) == '-' + && (name[off++] | 0x20) == 'i' + && (name[off++] | 0x20) == 'n' + && (name[off++] | 0x20) == 'f' + && (name[off] ) == '/'; } /* diff --git a/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java b/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java index 7a946099fdf..bc2396f10c3 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java +++ b/jdk/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java @@ -68,13 +68,14 @@ public class ClassLoaders { if (s != null && s.length() > 0) bcp = toURLClassPath(s); - // we have a class path if -cp is specified or -m is not specified + // we have a class path if -cp is specified or -m is not specified. + // If neither is specified then default to -cp <working directory>. URLClassPath ucp = null; String mainMid = System.getProperty("jdk.module.main"); String cp = System.getProperty("java.class.path"); - if (mainMid == null && (cp == null || cp.length() == 0)) - cp = "."; - if (cp != null && cp.length() > 0) + if (mainMid == null && cp == null) + cp = ""; + if (cp != null) ucp = toURLClassPath(cp); @@ -197,7 +198,7 @@ public class ClassLoaders { * @see java.lang.instrument.Instrumentation#appendToSystemClassLoaderSearch */ void appendToClassPathForInstrumentation(String path) { - appendToUCP(path, ucp); + addClassPathToUCP(path, ucp); } /** @@ -224,7 +225,7 @@ public class ClassLoaders { */ private static URLClassPath toURLClassPath(String cp) { URLClassPath ucp = new URLClassPath(new URL[0]); - appendToUCP(cp, ucp); + addClassPathToUCP(cp, ucp); return ucp; } @@ -232,20 +233,28 @@ public class ClassLoaders { * Converts the elements in the given class path to file URLs and adds * them to the given URLClassPath. */ - private static void appendToUCP(String cp, URLClassPath ucp) { - String[] elements = cp.split(File.pathSeparator); - if (elements.length == 0) { - // contains path separator(s) only, default to current directory - // to be compatible with long standing behavior - elements = new String[] { "" }; + private static void addClassPathToUCP(String cp, URLClassPath ucp) { + int off = 0; + int next; + while ((next = cp.indexOf(File.pathSeparator, off)) != -1) { + addURLToUCP(cp.substring(off, next), ucp); + off = next + 1; } - for (String s: elements) { - try { - URL url = Paths.get(s).toRealPath().toUri().toURL(); - ucp.addURL(url); - } catch (InvalidPathException | IOException ignore) { - // malformed path string or class path element does not exist - } + + // remaining + addURLToUCP(cp.substring(off), ucp); + } + + /** + * Attempts to convert to the given string to a file URL and adds it + * to the given URLClassPath. + */ + private static void addURLToUCP(String s, URLClassPath ucp) { + try { + URL url = Paths.get(s).toRealPath().toUri().toURL(); + ucp.addURL(url); + } catch (InvalidPathException | IOException ignore) { + // malformed path string or class path element does not exist } } diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java index 735d1b86143..bc7aaa5a6f3 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/Unsafe.java @@ -33,6 +33,7 @@ import jdk.internal.reflect.Reflection; import jdk.internal.misc.VM; import jdk.internal.HotSpotIntrinsicCandidate; +import jdk.internal.vm.annotation.ForceInline; /** @@ -209,46 +210,103 @@ public final class Unsafe { /** @see #getInt(Object, long) */ @HotSpotIntrinsicCandidate public native boolean getBoolean(Object o, long offset); + /** @see #putInt(Object, long, int) */ @HotSpotIntrinsicCandidate public native void putBoolean(Object o, long offset, boolean x); + /** @see #getInt(Object, long) */ @HotSpotIntrinsicCandidate public native byte getByte(Object o, long offset); + /** @see #putInt(Object, long, int) */ @HotSpotIntrinsicCandidate public native void putByte(Object o, long offset, byte x); + /** @see #getInt(Object, long) */ @HotSpotIntrinsicCandidate public native short getShort(Object o, long offset); + /** @see #putInt(Object, long, int) */ @HotSpotIntrinsicCandidate public native void putShort(Object o, long offset, short x); + /** @see #getInt(Object, long) */ @HotSpotIntrinsicCandidate public native char getChar(Object o, long offset); + /** @see #putInt(Object, long, int) */ @HotSpotIntrinsicCandidate public native void putChar(Object o, long offset, char x); + /** @see #getInt(Object, long) */ @HotSpotIntrinsicCandidate public native long getLong(Object o, long offset); + /** @see #putInt(Object, long, int) */ @HotSpotIntrinsicCandidate public native void putLong(Object o, long offset, long x); + /** @see #getInt(Object, long) */ @HotSpotIntrinsicCandidate public native float getFloat(Object o, long offset); + /** @see #putInt(Object, long, int) */ @HotSpotIntrinsicCandidate public native void putFloat(Object o, long offset, float x); + /** @see #getInt(Object, long) */ @HotSpotIntrinsicCandidate public native double getDouble(Object o, long offset); + /** @see #putInt(Object, long, int) */ @HotSpotIntrinsicCandidate public native void putDouble(Object o, long offset, double x); + /** + * Fetches a native pointer from a given memory address. If the address is + * zero, or does not point into a block obtained from {@link + * #allocateMemory}, the results are undefined. + * + * <p>If the native pointer is less than 64 bits wide, it is extended as + * an unsigned number to a Java long. The pointer may be indexed by any + * given byte offset, simply by adding that offset (as a simple integer) to + * the long representing the pointer. The number of bytes actually read + * from the target address may be determined by consulting {@link + * #addressSize}. + * + * @see #allocateMemory + * @see #getInt(Object, long) + */ + @ForceInline + public long getAddress(Object o, long offset) { + if (ADDRESS_SIZE == 4) { + return Integer.toUnsignedLong(getInt(o, offset)); + } else { + return getLong(o, offset); + } + } + + /** + * Stores a native pointer into a given memory address. If the address is + * zero, or does not point into a block obtained from {@link + * #allocateMemory}, the results are undefined. + * + * <p>The number of bytes actually written at the target address may be + * determined by consulting {@link #addressSize}. + * + * @see #allocateMemory + * @see #putInt(Object, long, int) + */ + @ForceInline + public void putAddress(Object o, long offset, long x) { + if (ADDRESS_SIZE == 4) { + putInt(o, offset, (int)x); + } else { + putLong(o, offset, x); + } + } + // These read VM internal data. /** @@ -287,8 +345,10 @@ public final class Unsafe { * * @see #allocateMemory */ - @HotSpotIntrinsicCandidate - public native byte getByte(long address); + @ForceInline + public byte getByte(long address) { + return getByte(null, address); + } /** * Stores a value into a given memory address. If the address is zero, or @@ -297,75 +357,94 @@ public final class Unsafe { * * @see #getByte(long) */ - @HotSpotIntrinsicCandidate - public native void putByte(long address, byte x); + @ForceInline + public void putByte(long address, byte x) { + putByte(null, address, x); + } /** @see #getByte(long) */ - @HotSpotIntrinsicCandidate - public native short getShort(long address); - /** @see #putByte(long, byte) */ - @HotSpotIntrinsicCandidate - public native void putShort(long address, short x); - /** @see #getByte(long) */ - @HotSpotIntrinsicCandidate - public native char getChar(long address); - /** @see #putByte(long, byte) */ - @HotSpotIntrinsicCandidate - public native void putChar(long address, char x); - /** @see #getByte(long) */ - @HotSpotIntrinsicCandidate - public native int getInt(long address); - /** @see #putByte(long, byte) */ - @HotSpotIntrinsicCandidate - public native void putInt(long address, int x); - /** @see #getByte(long) */ - @HotSpotIntrinsicCandidate - public native long getLong(long address); - /** @see #putByte(long, byte) */ - @HotSpotIntrinsicCandidate - public native void putLong(long address, long x); - /** @see #getByte(long) */ - @HotSpotIntrinsicCandidate - public native float getFloat(long address); - /** @see #putByte(long, byte) */ - @HotSpotIntrinsicCandidate - public native void putFloat(long address, float x); - /** @see #getByte(long) */ - @HotSpotIntrinsicCandidate - public native double getDouble(long address); - /** @see #putByte(long, byte) */ - @HotSpotIntrinsicCandidate - public native void putDouble(long address, double x); + @ForceInline + public short getShort(long address) { + return getShort(null, address); + } - /** - * Fetches a native pointer from a given memory address. If the address is - * zero, or does not point into a block obtained from {@link - * #allocateMemory}, the results are undefined. - * - * <p>If the native pointer is less than 64 bits wide, it is extended as - * an unsigned number to a Java long. The pointer may be indexed by any - * given byte offset, simply by adding that offset (as a simple integer) to - * the long representing the pointer. The number of bytes actually read - * from the target address may be determined by consulting {@link - * #addressSize}. - * - * @see #allocateMemory - */ - @HotSpotIntrinsicCandidate - public native long getAddress(long address); + /** @see #putByte(long, byte) */ + @ForceInline + public void putShort(long address, short x) { + putShort(null, address, x); + } - /** - * Stores a native pointer into a given memory address. If the address is - * zero, or does not point into a block obtained from {@link - * #allocateMemory}, the results are undefined. - * - * <p>The number of bytes actually written at the target address may be - * determined by consulting {@link #addressSize}. - * - * @see #getAddress(long) - */ - @HotSpotIntrinsicCandidate - public native void putAddress(long address, long x); + /** @see #getByte(long) */ + @ForceInline + public char getChar(long address) { + return getChar(null, address); + } + + /** @see #putByte(long, byte) */ + @ForceInline + public void putChar(long address, char x) { + putChar(null, address, x); + } + + /** @see #getByte(long) */ + @ForceInline + public int getInt(long address) { + return getInt(null, address); + } + + /** @see #putByte(long, byte) */ + @ForceInline + public void putInt(long address, int x) { + putInt(null, address, x); + } + + /** @see #getByte(long) */ + @ForceInline + public long getLong(long address) { + return getLong(null, address); + } + + /** @see #putByte(long, byte) */ + @ForceInline + public void putLong(long address, long x) { + putLong(null, address, x); + } + + /** @see #getByte(long) */ + @ForceInline + public float getFloat(long address) { + return getFloat(null, address); + } + + /** @see #putByte(long, byte) */ + @ForceInline + public void putFloat(long address, float x) { + putFloat(null, address, x); + } + + /** @see #getByte(long) */ + @ForceInline + public double getDouble(long address) { + return getDouble(null, address); + } + + /** @see #putByte(long, byte) */ + @ForceInline + public void putDouble(long address, double x) { + putDouble(null, address, x); + } + + /** @see #getAddress(Object, long) */ + @ForceInline + public long getAddress(long address) { + return getAddress(null, address); + } + + /** @see #putAddress(Object, long, long) */ + @ForceInline + public void putAddress(long address, long x) { + putAddress(null, address, x); + } @@ -1271,6 +1350,13 @@ public final class Unsafe { return compareAndSwapObject(o, offset, expected, x); } + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapObjectVolatile(Object o, long offset, + Object expected, + Object x) { + return compareAndSwapObject(o, offset, expected, x); + } + /** * Atomically updates Java variable to {@code x} if it is currently * holding {@code expected}. @@ -1325,6 +1411,13 @@ public final class Unsafe { return compareAndSwapInt(o, offset, expected, x); } + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapIntVolatile(Object o, long offset, + int expected, + int x) { + return compareAndSwapInt(o, offset, expected, x); + } + /** * Atomically updates Java variable to {@code x} if it is currently * holding {@code expected}. @@ -1379,6 +1472,13 @@ public final class Unsafe { return compareAndSwapLong(o, offset, expected, x); } + @HotSpotIntrinsicCandidate + public final boolean weakCompareAndSwapLongVolatile(Object o, long offset, + long expected, + long x) { + return compareAndSwapLong(o, offset, expected, x); + } + /** * Fetches a reference value from a given Java variable, with volatile * load semantics. Otherwise identical to {@link #getObject(Object, long)} diff --git a/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java b/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java index e49d17b0830..af8d3253a22 100644 --- a/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java +++ b/jdk/src/java.base/share/classes/jdk/internal/misc/VM.java @@ -390,10 +390,25 @@ public class VM { private static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020; /* - * Returns the first non-null class loader up the execution stack, - * or null if only code from the null class loader is on the stack. + * Returns the first user-defined class loader up the execution stack, + * or the platform class loader if only code from the platform or + * bootstrap class loader is on the stack. */ - public static native ClassLoader latestUserDefinedLoader(); + public static ClassLoader latestUserDefinedLoader() { + ClassLoader loader = latestUserDefinedLoader0(); + return loader != null ? loader : ClassLoader.getPlatformClassLoader(); + } + + /* + * Returns the first user-defined class loader up the execution stack, + * or null if only code from the platform or bootstrap class loader is + * on the stack. VM does not keep a reference of platform loader and so + * it returns null. + * + * This method should be replaced with StackWalker::walk and then we can + * remove the logic in the VM. + */ + private static native ClassLoader latestUserDefinedLoader0(); /** * Returns {@code true} if we are in a set UID program. diff --git a/jdk/src/java.base/share/classes/jdk/internal/util/Preconditions.java b/jdk/src/java.base/share/classes/jdk/internal/util/Preconditions.java new file mode 100644 index 00000000000..cb1b748f620 --- /dev/null +++ b/jdk/src/java.base/share/classes/jdk/internal/util/Preconditions.java @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2016, 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.util; + +import jdk.internal.HotSpotIntrinsicCandidate; + +import java.util.List; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * Utility methods to check if state or arguments are correct. + * + */ +public class Preconditions { + + /** + * Maps out-of-bounds values to a runtime exception. + * + * @param checkKind the kind of bounds check, whose name may correspond + * to the name of one of the range check methods, checkIndex, + * checkFromToIndex, checkFromIndexSize + * @param args the out-of-bounds arguments that failed the range check. + * If the checkKind corresponds a the name of a range check method + * then the bounds arguments are those that can be passed in order + * to the method. + * @param oobef the exception formatter that when applied with a checkKind + * and a list out-of-bounds arguments returns a runtime exception. + * If {@code null} then, it is as if an exception formatter was + * supplied that returns {@link IndexOutOfBoundsException} for any + * given arguments. + * @return the runtime exception + */ + private static RuntimeException outOfBounds( + BiFunction<String, List<Integer>, ? extends RuntimeException> oobef, + String checkKind, + Integer... args) { + List<Integer> largs = List.of(args); + RuntimeException e = oobef == null + ? null : oobef.apply(checkKind, largs); + return e == null + ? new IndexOutOfBoundsException(outOfBoundsMessage(checkKind, largs)) : e; + } + + private static RuntimeException outOfBoundsCheckIndex( + BiFunction<String, List<Integer>, ? extends RuntimeException> oobe, + int index, int length) { + return outOfBounds(oobe, "checkIndex", index, length); + } + + private static RuntimeException outOfBoundsCheckFromToIndex( + BiFunction<String, List<Integer>, ? extends RuntimeException> oobe, + int fromIndex, int toIndex, int length) { + return outOfBounds(oobe, "checkFromToIndex", fromIndex, toIndex, length); + } + + private static RuntimeException outOfBoundsCheckFromIndexSize( + BiFunction<String, List<Integer>, ? extends RuntimeException> oobe, + int fromIndex, int size, int length) { + return outOfBounds(oobe, "checkFromIndexSize", fromIndex, size, length); + } + + /** + * Returns an out-of-bounds exception formatter from an given exception + * factory. The exception formatter is a function that formats an + * out-of-bounds message from its arguments and applies that message to the + * given exception factory to produce and relay an exception. + * + * <p>The exception formatter accepts two arguments: a {@code String} + * describing the out-of-bounds range check that failed, referred to as the + * <em>check kind</em>; and a {@code List<Integer>} containing the + * out-of-bound integer values that failed the check. The list of + * out-of-bound values is not modified. + * + * <p>Three check kinds are supported {@code checkIndex}, + * {@code checkFromToIndex} and {@code checkFromIndexSize} corresponding + * respectively to the specified application of an exception formatter as an + * argument to the out-of-bounds range check methods + * {@link #checkIndex(int, int, BiFunction) checkIndex}, + * {@link #checkFromToIndex(int, int, int, BiFunction) checkFromToIndex}, and + * {@link #checkFromIndexSize(int, int, int, BiFunction) checkFromIndexSize}. + * Thus a supported check kind corresponds to a method name and the + * out-of-bound integer values correspond to method argument values, in + * order, preceding the exception formatter argument (similar in many + * respects to the form of arguments required for a reflective invocation of + * such a range check method). + * + * <p>Formatter arguments conforming to such supported check kinds will + * produce specific exception messages describing failed out-of-bounds + * checks. Otherwise, more generic exception messages will be produced in + * any of the following cases: the check kind is supported but fewer + * or more out-of-bounds values are supplied, the check kind is not + * supported, the check kind is {@code null}, or the list of out-of-bound + * values is {@code null}. + * + * @apiNote + * This method produces an out-of-bounds exception formatter that can be + * passed as an argument to any of the supported out-of-bounds range check + * methods declared by {@code Objects}. For example, a formatter producing + * an {@code ArrayIndexOutOfBoundsException} may be produced and stored on a + * {@code static final} field as follows: + * <pre>{@code + * static final + * BiFunction<String, List<Integer>, ArrayIndexOutOfBoundsException> AIOOBEF = + * outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new); + * }</pre> + * The formatter instance {@code AIOOBEF} may be passed as an argument to an + * out-of-bounds range check method, such as checking if an {@code index} + * is within the bounds of a {@code limit}: + * <pre>{@code + * checkIndex(index, limit, AIOOBEF); + * }</pre> + * If the bounds check fails then the range check method will throw an + * {@code ArrayIndexOutOfBoundsException} with an appropriate exception + * message that is a produced from {@code AIOOBEF} as follows: + * <pre>{@code + * AIOOBEF.apply("checkIndex", List.of(index, limit)); + * }</pre> + * + * @param f the exception factory, that produces an exception from a message + * where the message is produced and formatted by the returned + * exception formatter. If this factory is stateless and side-effect + * free then so is the returned formatter. + * Exceptions thrown by the factory are relayed to the caller + * of the returned formatter. + * @param <X> the type of runtime exception to be returned by the given + * exception factory and relayed by the exception formatter + * @return the out-of-bounds exception formatter + */ + public static <X extends RuntimeException> + BiFunction<String, List<Integer>, X> outOfBoundsExceptionFormatter(Function<String, X> f) { + // Use anonymous class to avoid bootstrap issues if this method is + // used early in startup + return new BiFunction<String, List<Integer>, X>() { + @Override + public X apply(String checkKind, List<Integer> args) { + return f.apply(outOfBoundsMessage(checkKind, args)); + } + }; + } + + private static String outOfBoundsMessage(String checkKind, List<Integer> args) { + if (checkKind == null && args == null) { + return String.format("Range check failed"); + } else if (checkKind == null) { + return String.format("Range check failed: %s", args); + } else if (args == null) { + return String.format("Range check failed: %s", checkKind); + } + + int argSize = 0; + switch (checkKind) { + case "checkIndex": + argSize = 2; + break; + case "checkFromToIndex": + case "checkFromIndexSize": + argSize = 3; + break; + default: + } + + // Switch to default if fewer or more arguments than required are supplied + switch ((args.size() != argSize) ? "" : checkKind) { + case "checkIndex": + return String.format("Index %d out-of-bounds for length %d", + args.get(0), args.get(1)); + case "checkFromToIndex": + return String.format("Range [%d, %d) out-of-bounds for length %d", + args.get(0), args.get(1), args.get(2)); + case "checkFromIndexSize": + return String.format("Range [%d, %<d + %d) out-of-bounds for length %d", + args.get(0), args.get(1), args.get(2)); + default: + return String.format("Range check failed: %s %s", checkKind, args); + } + } + + /** + * Checks if the {@code index} is within the bounds of the range from + * {@code 0} (inclusive) to {@code length} (exclusive). + * + * <p>The {@code index} is defined to be out-of-bounds if any of the + * following inequalities is true: + * <ul> + * <li>{@code index < 0}</li> + * <li>{@code index >= length}</li> + * <li>{@code length < 0}, which is implied from the former inequalities</li> + * </ul> + * + * <p>If the {@code index} is out-of-bounds, then a runtime exception is + * thrown that is the result of applying the following arguments to the + * exception formatter: the name of this method, {@code checkIndex}; + * and an unmodifiable list integers whose values are, in order, the + * out-of-bounds arguments {@code index} and {@code length}. + * + * @param <X> the type of runtime exception to throw if the arguments are + * out-of-bounds + * @param index the index + * @param length the upper-bound (exclusive) of the range + * @param oobef the exception formatter that when applied with this + * method name and out-of-bounds arguments returns a runtime + * exception. If {@code null} or returns {@code null} then, it is as + * if an exception formatter produced from an invocation of + * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used + * instead (though it may be more efficient). + * Exceptions thrown by the formatter are relayed to the caller. + * @return {@code index} if it is within bounds of the range + * @throws X if the {@code index} is out-of-bounds and the exception + * formatter is non-{@code null} + * @throws IndexOutOfBoundsException if the {@code index} is out-of-bounds + * and the exception formatter is {@code null} + * @since 9 + * + * @implNote + * This method is made intrinsic in optimizing compilers to guide them to + * perform unsigned comparisons of the index and length when it is known the + * length is a non-negative value (such as that of an array length or from + * the upper bound of a loop) + */ + @HotSpotIntrinsicCandidate + public static <X extends RuntimeException> + int checkIndex(int index, int length, + BiFunction<String, List<Integer>, X> oobef) { + if (index < 0 || index >= length) + throw outOfBoundsCheckIndex(oobef, index, length); + return index; + } + + /** + * Checks if the sub-range from {@code fromIndex} (inclusive) to + * {@code toIndex} (exclusive) is within the bounds of range from {@code 0} + * (inclusive) to {@code length} (exclusive). + * + * <p>The sub-range is defined to be out-of-bounds if any of the following + * inequalities is true: + * <ul> + * <li>{@code fromIndex < 0}</li> + * <li>{@code fromIndex > toIndex}</li> + * <li>{@code toIndex > length}</li> + * <li>{@code length < 0}, which is implied from the former inequalities</li> + * </ul> + * + * <p>If the sub-range is out-of-bounds, then a runtime exception is + * thrown that is the result of applying the following arguments to the + * exception formatter: the name of this method, {@code checkFromToIndex}; + * and an unmodifiable list integers whose values are, in order, the + * out-of-bounds arguments {@code fromIndex}, {@code toIndex}, and {@code length}. + * + * @param <X> the type of runtime exception to throw if the arguments are + * out-of-bounds + * @param fromIndex the lower-bound (inclusive) of the sub-range + * @param toIndex the upper-bound (exclusive) of the sub-range + * @param length the upper-bound (exclusive) the range + * @param oobef the exception formatter that when applied with this + * method name and out-of-bounds arguments returns a runtime + * exception. If {@code null} or returns {@code null} then, it is as + * if an exception formatter produced from an invocation of + * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used + * instead (though it may be more efficient). + * Exceptions thrown by the formatter are relayed to the caller. + * @return {@code fromIndex} if the sub-range within bounds of the range + * @throws X if the sub-range is out-of-bounds and the exception factory + * function is non-{@code null} + * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and + * the exception factory function is {@code null} + * @since 9 + */ + public static <X extends RuntimeException> + int checkFromToIndex(int fromIndex, int toIndex, int length, + BiFunction<String, List<Integer>, X> oobef) { + if (fromIndex < 0 || fromIndex > toIndex || toIndex > length) + throw outOfBoundsCheckFromToIndex(oobef, fromIndex, toIndex, length); + return fromIndex; + } + + /** + * Checks if the sub-range from {@code fromIndex} (inclusive) to + * {@code fromIndex + size} (exclusive) is within the bounds of range from + * {@code 0} (inclusive) to {@code length} (exclusive). + * + * <p>The sub-range is defined to be out-of-bounds if any of the following + * inequalities is true: + * <ul> + * <li>{@code fromIndex < 0}</li> + * <li>{@code size < 0}</li> + * <li>{@code fromIndex + size > length}, taking into account integer overflow</li> + * <li>{@code length < 0}, which is implied from the former inequalities</li> + * </ul> + * + * <p>If the sub-range is out-of-bounds, then a runtime exception is + * thrown that is the result of applying the following arguments to the + * exception formatter: the name of this method, {@code checkFromIndexSize}; + * and an unmodifiable list integers whose values are, in order, the + * out-of-bounds arguments {@code fromIndex}, {@code size}, and + * {@code length}. + * + * @param <X> the type of runtime exception to throw if the arguments are + * out-of-bounds + * @param fromIndex the lower-bound (inclusive) of the sub-interval + * @param size the size of the sub-range + * @param length the upper-bound (exclusive) of the range + * @param oobef the exception formatter that when applied with this + * method name and out-of-bounds arguments returns a runtime + * exception. If {@code null} or returns {@code null} then, it is as + * if an exception formatter produced from an invocation of + * {@code outOfBoundsExceptionFormatter(IndexOutOfBounds::new)} is used + * instead (though it may be more efficient). + * Exceptions thrown by the formatter are relayed to the caller. + * @return {@code fromIndex} if the sub-range within bounds of the range + * @throws X if the sub-range is out-of-bounds and the exception factory + * function is non-{@code null} + * @throws IndexOutOfBoundsException if the sub-range is out-of-bounds and + * the exception factory function is {@code null} + * @since 9 + */ + public static <X extends RuntimeException> + int checkFromIndexSize(int fromIndex, int size, int length, + BiFunction<String, List<Integer>, X> oobef) { + if ((length | fromIndex | size) < 0 || size > length - fromIndex) + throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length); + return fromIndex; + } +} diff --git a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties index 6390b9792d4..32aa8ec65b3 100644 --- a/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties +++ b/jdk/src/java.base/share/classes/sun/launcher/resources/launcher.properties @@ -100,7 +100,6 @@ java.launcher.X.usage=\ \ -Xdiag show additional diagnostic messages\n\ \ -Xdiag:resolver show resolver diagnostic messages\n\ \ -Xnoclassgc disable class garbage collection\n\ -\ -Xincgc enable incremental garbage collection\n\ \ -Xloggc:<file> log GC status to a file with time stamps\n\ \ -Xbatch disable background compilation\n\ \ -Xms<size> set initial Java heap size\n\ diff --git a/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java b/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java index 64f1c9da9fe..ea4b77535b2 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/ByteArrayAccess.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, 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 @@ -441,17 +441,89 @@ final class ByteArrayAccess { (outOfs < 0) || ((out.length - outOfs) < len)) { throw new ArrayIndexOutOfBoundsException(); } - len += outOfs; - while (outOfs < len) { - long i = in[inOfs++]; - out[outOfs++] = (byte)(i >> 56); - out[outOfs++] = (byte)(i >> 48); - out[outOfs++] = (byte)(i >> 40); - out[outOfs++] = (byte)(i >> 32); - out[outOfs++] = (byte)(i >> 24); - out[outOfs++] = (byte)(i >> 16); - out[outOfs++] = (byte)(i >> 8); - out[outOfs++] = (byte)(i ); + if (littleEndianUnaligned) { + outOfs += byteArrayOfs; + len += outOfs; + while (outOfs < len) { + unsafe.putLong(out, (long)outOfs, reverseBytes(in[inOfs++])); + outOfs += 8; + } + } else { + len += outOfs; + while (outOfs < len) { + long i = in[inOfs++]; + out[outOfs++] = (byte)(i >> 56); + out[outOfs++] = (byte)(i >> 48); + out[outOfs++] = (byte)(i >> 40); + out[outOfs++] = (byte)(i >> 32); + out[outOfs++] = (byte)(i >> 24); + out[outOfs++] = (byte)(i >> 16); + out[outOfs++] = (byte)(i >> 8); + out[outOfs++] = (byte)(i ); + } + } + } + + /** + * byte[] to long[] conversion, little endian byte order + */ + static void b2lLittle(byte[] in, int inOfs, long[] out, int outOfs, int len) { + if ((inOfs < 0) || ((in.length - inOfs) < len) || + ((outOfs < 0) || (out.length - outOfs) < len/8)) { + throw new ArrayIndexOutOfBoundsException(); + } + if (littleEndianUnaligned) { + inOfs += byteArrayOfs; + len += inOfs; + while (inOfs < len) { + out[outOfs++] = unsafe.getLong(in, (long)inOfs); + inOfs += 8; + } + } else { + len += inOfs; + while (inOfs < len) { + out[outOfs++] = ((in[inOfs ] & 0xffL) + | ((in[inOfs + 1] & 0xffL) << 8) + | ((in[inOfs + 2] & 0xffL) << 16) + | ((in[inOfs + 3] & 0xffL) << 24) + | ((in[inOfs + 4] & 0xffL) << 32) + | ((in[inOfs + 5] & 0xffL) << 40) + | ((in[inOfs + 6] & 0xffL) << 48) + | ((in[inOfs + 7] & 0xffL) << 56)); + inOfs += 8; + } + } + } + + + /** + * long[] to byte[] conversion, little endian byte order + */ + static void l2bLittle(long[] in, int inOfs, byte[] out, int outOfs, int len) { + if ((inOfs < 0) || ((in.length - inOfs) < len/8) || + (outOfs < 0) || ((out.length - outOfs) < len)) { + throw new ArrayIndexOutOfBoundsException(); + } + if (littleEndianUnaligned) { + outOfs += byteArrayOfs; + len += outOfs; + while (outOfs < len) { + unsafe.putLong(out, (long)outOfs, in[inOfs++]); + outOfs += 8; + } + } else { + len += outOfs; + while (outOfs < len) { + long i = in[inOfs++]; + out[outOfs++] = (byte)(i ); + out[outOfs++] = (byte)(i >> 8); + out[outOfs++] = (byte)(i >> 16); + out[outOfs++] = (byte)(i >> 24); + out[outOfs++] = (byte)(i >> 32); + out[outOfs++] = (byte)(i >> 40); + out[outOfs++] = (byte)(i >> 48); + out[outOfs++] = (byte)(i >> 56); + } } } } diff --git a/jdk/src/java.base/share/classes/sun/security/provider/PolicyFile.java b/jdk/src/java.base/share/classes/sun/security/provider/PolicyFile.java index 5861b6c7a85..861fa692471 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/PolicyFile.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/PolicyFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -259,14 +259,10 @@ public class PolicyFile extends java.security.Policy { private static final Debug debug = Debug.getInstance("policy"); - private static final String NONE = "NONE"; - private static final String P11KEYSTORE = "PKCS11"; - private static final String SELF = "${{self}}"; private static final String X500PRINCIPAL = "javax.security.auth.x500.X500Principal"; private static final String POLICY = "java.security.policy"; - private static final String SECURITY_MANAGER = "java.security.manager"; private static final String POLICY_URL = "policy.url."; private static final String AUTH_POLICY = "java.security.auth.policy"; private static final String AUTH_POLICY_URL = "auth.policy.url."; @@ -287,6 +283,17 @@ public class PolicyFile extends java.security.Policy { private static final Class<?>[] PARAMS1 = { String.class }; private static final Class<?>[] PARAMS2 = { String.class, String.class }; + /** + * When a policy file has a syntax error, the exception code may generate + * another permission check and this can cause the policy file to be parsed + * repeatedly, leading to a StackOverflowError or ClassCircularityError. + * To avoid this, this set is populated with policy files that have been + * previously parsed and have syntax errors, so that they can be + * subsequently ignored. + */ + private static AtomicReference<Set<URL>> badPolicyURLs = + new AtomicReference<>(new HashSet<>()); + /** * Initializes the Policy object and reads the default policy * configuration file(s) into the Policy object. @@ -580,6 +587,16 @@ public class PolicyFile extends java.security.Policy { * @param policyFile the policy Reader object. */ private boolean init(URL policy, PolicyInfo newInfo) { + + // skip parsing policy file if it has been previously parsed and + // has syntax errors + if (badPolicyURLs.get().contains(policy)) { + if (debug != null) { + debug.println("skipping bad policy file: " + policy); + } + return false; + } + boolean success = false; PolicyParser pp = new PolicyParser(expandProperties); InputStreamReader isr = null; @@ -622,13 +639,18 @@ public class PolicyFile extends java.security.Policy { addGrantEntry(ge, keyStore, newInfo); } } catch (PolicyParser.ParsingException pe) { + // record bad policy file to avoid later reparsing it + badPolicyURLs.updateAndGet(k -> { + k.add(policy); + return k; + }); MessageFormat form = new MessageFormat(ResourcesMgr.getString (POLICY + ".error.parsing.policy.message")); Object[] source = {policy, pe.getLocalizedMessage()}; System.err.println(form.format(source)); - if (debug != null) + if (debug != null) { pe.printStackTrace(); - + } } catch (Exception e) { if (debug != null) { debug.println("error parsing "+policy); diff --git a/jdk/src/java.base/share/classes/sun/security/provider/PolicyParser.java b/jdk/src/java.base/share/classes/sun/security/provider/PolicyParser.java index ba8ed750254..f8aa620fc77 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/PolicyParser.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/PolicyParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2016, 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 @@ -213,7 +213,9 @@ public class PolicyParser { new MessageFormat(ResourcesMgr.getString( "duplicate.keystore.domain.name")); Object[] source = {domainName}; - throw new ParsingException(form.format(source)); + String msg = "duplicate keystore domain name: " + + domainName; + throw new ParsingException(msg, form, source); } } } else { @@ -743,7 +745,8 @@ public class PolicyParser { ResourcesMgr.getString ("expected.expect.read.end.of.file.")); Object[] source = {expect}; - throw new ParsingException(form.format(source)); + String msg = "expected [" + expect + "], read [end of file]"; + throw new ParsingException(msg, form, source); case StreamTokenizer.TT_WORD: if (expect.equalsIgnoreCase(st.sval)) { lookahead = st.nextToken(); @@ -1244,7 +1247,8 @@ public class PolicyParser { MessageFormat form = new MessageFormat(ResourcesMgr.getString( "duplicate.keystore.name")); Object[] source = {keystoreName}; - throw new ParsingException(form.format(source)); + String msg = "duplicate keystore name: " + keystoreName; + throw new ParsingException(msg, form, source); } } @@ -1316,6 +1320,8 @@ public class PolicyParser { private static final long serialVersionUID = -4330692689482574072L; private String i18nMessage; + private MessageFormat form; + private Object[] source; /** * Constructs a ParsingException with the specified @@ -1330,26 +1336,34 @@ public class PolicyParser { i18nMessage = msg; } + public ParsingException(String msg, MessageFormat form, + Object[] source) { + super(msg); + this.form = form; + this.source = source; + } + public ParsingException(int line, String msg) { super("line " + line + ": " + msg); - MessageFormat form = new MessageFormat - (ResourcesMgr.getString("line.number.msg")); - Object[] source = {line, msg}; - i18nMessage = form.format(source); + // don't call form.format unless getLocalizedMessage is called + // to avoid unnecessary permission checks + form = new MessageFormat(ResourcesMgr.getString("line.number.msg")); + source = new Object[] {line, msg}; } public ParsingException(int line, String expect, String actual) { super("line " + line + ": expected [" + expect + "], found [" + actual + "]"); - MessageFormat form = new MessageFormat(ResourcesMgr.getString + // don't call form.format unless getLocalizedMessage is called + // to avoid unnecessary permission checks + form = new MessageFormat(ResourcesMgr.getString ("line.number.expected.expect.found.actual.")); - Object[] source = {line, expect, actual}; - i18nMessage = form.format(source); + source = new Object[] {line, expect, actual}; } @Override public String getLocalizedMessage() { - return i18nMessage; + return i18nMessage != null ? i18nMessage : form.format(source); } } diff --git a/jdk/src/java.base/share/classes/sun/security/provider/SHA3.java b/jdk/src/java.base/share/classes/sun/security/provider/SHA3.java new file mode 100644 index 00000000000..1751c5b9fbb --- /dev/null +++ b/jdk/src/java.base/share/classes/sun/security/provider/SHA3.java @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2016, 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.provider; + +import static sun.security.provider.ByteArrayAccess.*; +import java.nio.*; +import java.util.*; +import java.security.*; + +/** + * This class implements the Secure Hash Algorithm SHA-3 developed by + * the National Institute of Standards and Technology along with the + * National Security Agency as defined in FIPS PUB 202. + * + * <p>It implements java.security.MessageDigestSpi, and can be used + * through Java Cryptography Architecture (JCA), as a pluggable + * MessageDigest implementation. + * + * @since 9 + * @author Valerie Peng + */ +abstract class SHA3 extends DigestBase { + + private static final int WIDTH = 200; // in bytes, e.g. 1600 bits + private static final int DM = 5; // dimension of lanes + + private static final int NR = 24; // number of rounds + + // precomputed round constants needed by the step mapping Iota + private static final long[] RC_CONSTANTS = { + 0x01L, 0x8082L, 0x800000000000808aL, + 0x8000000080008000L, 0x808bL, 0x80000001L, + 0x8000000080008081L, 0x8000000000008009L, 0x8aL, + 0x88L, 0x80008009L, 0x8000000aL, + 0x8000808bL, 0x800000000000008bL, 0x8000000000008089L, + 0x8000000000008003L, 0x8000000000008002L, 0x8000000000000080L, + 0x800aL, 0x800000008000000aL, 0x8000000080008081L, + 0x8000000000008080L, 0x80000001L, 0x8000000080008008L, + }; + + private byte[] state; + + /** + * Creates a new SHA-3 object. + */ + SHA3(String name, int digestLength) { + super(name, digestLength, (WIDTH - (2 * digestLength))); + implReset(); + } + + /** + * Core compression function. Processes blockSize bytes at a time + * and updates the state of this object. + */ + void implCompress(byte[] b, int ofs) { + for (int i = 0; i < buffer.length; i++) { + state[i] ^= b[ofs++]; + } + state = keccak(state); + } + + /** + * Return the digest. Subclasses do not need to reset() themselves, + * DigestBase calls implReset() when necessary. + */ + void implDigest(byte[] out, int ofs) { + int numOfPadding = + setPaddingBytes(buffer, (int)(bytesProcessed % buffer.length)); + if (numOfPadding < 1) { + throw new ProviderException("Incorrect pad size: " + numOfPadding); + } + for (int i = 0; i < buffer.length; i++) { + state[i] ^= buffer[i]; + } + state = keccak(state); + System.arraycopy(state, 0, out, ofs, engineGetDigestLength()); + } + + /** + * Resets the internal state to start a new hash. + */ + void implReset() { + state = new byte[WIDTH]; + } + + /** + * Utility function for circular shift the specified long + * value to the left for n bits. + */ + private static long circularShiftLeft(long lane, int n) { + return ((lane << n) | (lane >>> (64 - n))); + } + + /** + * Utility function for padding the specified data based on the + * pad10*1 algorithm (section 5.1) and the 2-bit suffix "01" required + * for SHA-3 hash (section 6.1). + */ + private static int setPaddingBytes(byte[] in, int len) { + if (len != in.length) { + // erase leftover values + Arrays.fill(in, len, in.length, (byte)0); + // directly store the padding bytes into the input + // as the specified buffer is allocated w/ size = rateR + in[len] |= (byte) 0x06; + in[in.length - 1] |= (byte) 0x80; + } + return (in.length - len); + } + + /** + * Utility function for transforming the specified state from + * the byte array format into array of lanes as defined in + * section 3.1.2. + */ + private static long[][] bytes2Lanes(byte[] s) { + if (s.length != WIDTH) { + throw new ProviderException("Error: incorrect input size " + + s.length); + } + // The conversion traverses along x-axis before y-axis. So, y is the + // first dimension and x is the second dimension. + long[][] s2 = new long[DM][DM]; + int sOfs = 0; + for (int y = 0; y < DM; y++, sOfs += 40) { + b2lLittle(s, sOfs, s2[y], 0, 40); + } + return s2; + } + + /** + * Utility function for transforming the specified arrays of + * lanes into a byte array as defined in section 3.1.3. + */ + private static byte[] lanes2Bytes(long[][] m) { + byte[] s = new byte[WIDTH]; + int sOfs = 0; + // The conversion traverses along x-axis before y-axis. So, y is the + // first dimension and x is the second dimension. + for (int y = 0; y < DM; y++, sOfs += 40) { + l2bLittle(m[y], 0, s, sOfs, 40); + } + return s; + } + + /** + * Step mapping Theta as defined in section 3.2.1 . + */ + private static long[][] smTheta(long[][] a) { + long[] c = new long[DM]; + for (int i = 0; i < DM; i++) { + c[i] = a[0][i]^a[1][i]^a[2][i]^a[3][i]^a[4][i]; + } + long[] d = new long[DM]; + for (int i = 0; i < DM; i++) { + long c1 = c[(i + 4) % DM]; + // left shift and wrap the leftmost bit into the rightmost bit + long c2 = circularShiftLeft(c[(i + 1) % DM], 1); + d[i] = c1^c2; + } + for (int y = 0; y < DM; y++) { + for (int x = 0; x < DM; x++) { + a[y][x] ^= d[x]; + } + } + return a; + } + + /** + * Step mapping Rho as defined in section 3.2.2. + */ + private static long[][] smRho(long[][] a) { + long[][] a2 = new long[DM][DM]; + a2[0][0] = a[0][0]; + int xNext, yNext; + for (int t = 0, x = 1, y = 0; t <= 23; t++, x = xNext, y = yNext) { + int numberOfShift = ((t + 1)*(t + 2)/2) % 64; + a2[y][x] = circularShiftLeft(a[y][x], numberOfShift); + xNext = y; + yNext = (2 * x + 3 * y) % DM; + } + return a2; + } + + /** + * Step mapping Pi as defined in section 3.2.3. + */ + private static long[][] smPi(long[][] a) { + long[][] a2 = new long[DM][DM]; + for (int y = 0; y < DM; y++) { + for (int x = 0; x < DM; x++) { + a2[y][x] = a[x][(x + 3 * y) % DM]; + } + } + return a2; + } + + /** + * Step mapping Chi as defined in section 3.2.4. + */ + private static long[][] smChi(long[][] a) { + long[][] a2 = new long[DM][DM]; + for (int y = 0; y < DM; y++) { + for (int x = 0; x < DM; x++) { + a2[y][x] = a[y][x] ^ + ((a[y][(x + 1) % DM] ^ 0xFFFFFFFFFFFFFFFFL) & + a[y][(x + 2) % DM]); + } + } + return a2; + } + + /** + * Step mapping Iota as defined in section 3.2.5. + * + * @return the processed state array + * @param state the state array to be processed + */ + private static long[][] smIota(long[][] a, int rndIndex) { + a[0][0] ^= RC_CONSTANTS[rndIndex]; + return a; + } + + /** + * The function Keccak as defined in section 5.2 with + * rate r = 1600 and capacity c = (digest length x 2). + */ + private static byte[] keccak(byte[] state) { + long[][] lanes = bytes2Lanes(state); + for (int ir = 0; ir < NR; ir++) { + lanes = smIota(smChi(smPi(smRho(smTheta(lanes)))), ir); + } + return lanes2Bytes(lanes); + } + + public Object clone() throws CloneNotSupportedException { + SHA3 copy = (SHA3) super.clone(); + copy.state = copy.state.clone(); + return copy; + } + + /** + * SHA3-224 implementation class. + */ + public static final class SHA224 extends SHA3 { + public SHA224() { + super("SHA3-224", 28); + } + } + + /** + * SHA3-256 implementation class. + */ + public static final class SHA256 extends SHA3 { + public SHA256() { + super("SHA3-256", 32); + } + } + + /** + * SHAs-384 implementation class. + */ + public static final class SHA384 extends SHA3 { + public SHA384() { + super("SHA3-384", 48); + } + } + + /** + * SHA3-512 implementation class. + */ + public static final class SHA512 extends SHA3 { + public SHA512() { + super("SHA3-512", 64); + } + } +} diff --git a/jdk/src/java.base/share/classes/sun/security/provider/SunEntries.java b/jdk/src/java.base/share/classes/sun/security/provider/SunEntries.java index 0ff50002713..ea090fa6898 100644 --- a/jdk/src/java.base/share/classes/sun/security/provider/SunEntries.java +++ b/jdk/src/java.base/share/classes/sun/security/provider/SunEntries.java @@ -211,6 +211,25 @@ final class SunEntries { map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.6", "SHA-512/256"); + map.put("MessageDigest.SHA3-224", "sun.security.provider.SHA3$SHA224"); + map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.7", "SHA3-224"); + map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.7", + "SHA3-224"); + + map.put("MessageDigest.SHA3-256", "sun.security.provider.SHA3$SHA256"); + map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.8", "SHA3-256"); + map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.8", + "SHA3-256"); + map.put("MessageDigest.SHA3-384", "sun.security.provider.SHA3$SHA384"); + map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.9", "SHA3-384"); + map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.9", + "SHA3-384"); + map.put("MessageDigest.SHA3-512", "sun.security.provider.SHA3$SHA512"); + map.put("Alg.Alias.MessageDigest.2.16.840.1.101.3.4.2.10", "SHA3-512"); + map.put("Alg.Alias.MessageDigest.OID.2.16.840.1.101.3.4.2.10", + "SHA3-512"); + + /* * Algorithm Parameter Generator engines */ diff --git a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeHash.java b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeHash.java index 4a32fdf902e..2a3775da7df 100644 --- a/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeHash.java +++ b/jdk/src/java.base/share/classes/sun/security/ssl/HandshakeHash.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, 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 @@ -108,7 +108,7 @@ final class HandshakeHash { * a hash for the certificate verify message is required. */ HandshakeHash(boolean needCertificateVerify) { - clonesNeeded = needCertificateVerify ? 3 : 2; + clonesNeeded = needCertificateVerify ? 4 : 3; } void reserve(ByteBuffer input) { diff --git a/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java b/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java index 20e66d561fb..0bf5fcbe1fc 100644 --- a/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java +++ b/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java @@ -145,11 +145,10 @@ public class SignatureFileVerifier { */ public static boolean isBlockOrSF(String s) { // we currently only support DSA and RSA PKCS7 blocks - if (s.endsWith(".SF") || s.endsWith(".DSA") || - s.endsWith(".RSA") || s.endsWith(".EC")) { - return true; - } - return false; + return s.endsWith(".SF") + || s.endsWith(".DSA") + || s.endsWith(".RSA") + || s.endsWith(".EC"); } /** diff --git a/jdk/src/java.base/share/classes/sun/security/x509/AlgorithmId.java b/jdk/src/java.base/share/classes/sun/security/x509/AlgorithmId.java index 60b0b922190..3ff90bf483a 100644 --- a/jdk/src/java.base/share/classes/sun/security/x509/AlgorithmId.java +++ b/jdk/src/java.base/share/classes/sun/security/x509/AlgorithmId.java @@ -552,58 +552,61 @@ public class AlgorithmId implements Serializable, DerEncoder { return AlgorithmId.sha512WithECDSA_oid; } - // See if any of the installed providers supply a mapping from - // the given algorithm name to an OID string - String oidString; - if (!initOidTable) { - Provider[] provs = Security.getProviders(); - for (int i=0; i<provs.length; i++) { - for (Enumeration<Object> enum_ = provs[i].keys(); - enum_.hasMoreElements(); ) { - String alias = (String)enum_.nextElement(); - String upperCaseAlias = alias.toUpperCase(Locale.ENGLISH); - int index; - if (upperCaseAlias.startsWith("ALG.ALIAS") && - (index=upperCaseAlias.indexOf("OID.", 0)) != -1) { - index += "OID.".length(); - if (index == alias.length()) { - // invalid alias entry - break; - } - if (oidTable == null) { - oidTable = new HashMap<>(); - } - oidString = alias.substring(index); - String stdAlgName = provs[i].getProperty(alias); - if (stdAlgName != null) { - stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH); - } - if (stdAlgName != null && - oidTable.get(stdAlgName) == null) { - oidTable.put(stdAlgName, - new ObjectIdentifier(oidString)); - } - } - } - } - - if (oidTable == null) { - oidTable = Collections.<String,ObjectIdentifier>emptyMap(); - } - initOidTable = true; - } - - return oidTable.get(name.toUpperCase(Locale.ENGLISH)); + return oidTable().get(name.toUpperCase(Locale.ENGLISH)); } private static ObjectIdentifier oid(int ... values) { return ObjectIdentifier.newInternal(values); } - private static boolean initOidTable = false; - private static Map<String,ObjectIdentifier> oidTable; + private static volatile Map<String,ObjectIdentifier> oidTable; private static final Map<ObjectIdentifier,String> nameTable; + /** Returns the oidTable, lazily initializing it on first access. */ + private static Map<String,ObjectIdentifier> oidTable() + throws IOException { + // Double checked locking; safe because oidTable is volatile + Map<String,ObjectIdentifier> tab; + if ((tab = oidTable) == null) { + synchronized (AlgorithmId.class) { + if ((tab = oidTable) == null) + oidTable = tab = computeOidTable(); + } + } + return tab; + } + + /** Collects the algorithm names from the installed providers. */ + private static HashMap<String,ObjectIdentifier> computeOidTable() + throws IOException { + HashMap<String,ObjectIdentifier> tab = new HashMap<>(); + for (Provider provider : Security.getProviders()) { + for (Object key : provider.keySet()) { + String alias = (String)key; + String upperCaseAlias = alias.toUpperCase(Locale.ENGLISH); + int index; + if (upperCaseAlias.startsWith("ALG.ALIAS") && + (index=upperCaseAlias.indexOf("OID.", 0)) != -1) { + index += "OID.".length(); + if (index == alias.length()) { + // invalid alias entry + break; + } + String oidString = alias.substring(index); + String stdAlgName = provider.getProperty(alias); + if (stdAlgName != null) { + stdAlgName = stdAlgName.toUpperCase(Locale.ENGLISH); + } + if (stdAlgName != null && + tab.get(stdAlgName) == null) { + tab.put(stdAlgName, new ObjectIdentifier(oidString)); + } + } + } + } + return tab; + } + /*****************************************************************/ /* diff --git a/jdk/src/java.base/share/conf/security/java.policy b/jdk/src/java.base/share/conf/security/java.policy index 0400ebfd546..32d31472394 100644 --- a/jdk/src/java.base/share/conf/security/java.policy +++ b/jdk/src/java.base/share/conf/security/java.policy @@ -80,6 +80,10 @@ grant codeBase "jrt:/jdk.naming.dns" { permission java.security.AllPermission; }; +grant codeBase "jrt:/java.scripting" { + permission java.security.AllPermission; +}; + grant codeBase "jrt:/jdk.scripting.nashorn" { permission java.security.AllPermission; }; diff --git a/jdk/src/java.base/share/native/include/jvmti.h b/jdk/src/java.base/share/native/include/jvmti.h index 684fd2d7046..5f8835c0baa 100644 --- a/jdk/src/java.base/share/native/include/jvmti.h +++ b/jdk/src/java.base/share/native/include/jvmti.h @@ -704,7 +704,8 @@ typedef struct { unsigned int can_generate_resource_exhaustion_heap_events : 1; unsigned int can_generate_resource_exhaustion_threads_events : 1; unsigned int can_generate_early_vmstart : 1; - unsigned int : 6; + unsigned int can_generate_early_class_hook_events : 1; + unsigned int : 5; unsigned int : 16; unsigned int : 16; unsigned int : 16; diff --git a/jdk/src/java.base/share/native/libjava/VM.c b/jdk/src/java.base/share/native/libjava/VM.c index 61bae65f815..53837efc518 100644 --- a/jdk/src/java.base/share/native/libjava/VM.c +++ b/jdk/src/java.base/share/native/libjava/VM.c @@ -36,7 +36,7 @@ static JNINativeMethod methods[] = { }; JNIEXPORT jobject JNICALL -Java_jdk_internal_misc_VM_latestUserDefinedLoader(JNIEnv *env, jclass cls) { +Java_jdk_internal_misc_VM_latestUserDefinedLoader0(JNIEnv *env, jclass cls) { return JVM_LatestUserDefinedLoader(env); } diff --git a/jdk/src/java.httpclient/share/classes/java/net/http/AsyncSSLDelegate.java b/jdk/src/java.httpclient/share/classes/java/net/http/AsyncSSLDelegate.java index b3ff5c311e4..ae0d19c6cde 100644 --- a/jdk/src/java.httpclient/share/classes/java/net/http/AsyncSSLDelegate.java +++ b/jdk/src/java.httpclient/share/classes/java/net/http/AsyncSSLDelegate.java @@ -26,7 +26,6 @@ package java.net.http; import java.io.Closeable; import java.io.IOException; import java.nio.ByteBuffer; -import java.util.Arrays; import java.util.LinkedList; import java.util.concurrent.ExecutorService; import java.util.function.Consumer; @@ -557,25 +556,37 @@ public class AsyncSSLDelegate implements Closeable, AsyncConnection { } static void logParams(SSLParameters p) { - if (!Log.ssl()) + if (!Log.ssl()) { return; + } + Log.logSSL("SSLParameters:"); if (p == null) { Log.logSSL("Null params"); return; } - for (String cipher : p.getCipherSuites()) { - Log.logSSL("cipher: {0}\n", cipher); + + if (p.getCipherSuites() != null) { + for (String cipher : p.getCipherSuites()) { + Log.logSSL("cipher: {0}\n", cipher); + } } + + // SSLParameters.getApplicationProtocols() can't return null for (String approto : p.getApplicationProtocols()) { Log.logSSL("application protocol: {0}\n", approto); } - for (String protocol : p.getProtocols()) { - Log.logSSL("protocol: {0}\n", protocol); + + if (p.getProtocols() != null) { + for (String protocol : p.getProtocols()) { + Log.logSSL("protocol: {0}\n", protocol); + } } - if (p.getServerNames() != null) + + if (p.getServerNames() != null) { for (SNIServerName sname : p.getServerNames()) { Log.logSSL("server name: {0}\n", sname.toString()); + } } } diff --git a/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java b/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java index 446987d6b5d..226cee95c55 100644 --- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java +++ b/jdk/src/java.httpclient/share/classes/java/net/http/HttpClientImpl.java @@ -35,6 +35,7 @@ import java.nio.channels.ClosedChannelException; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; +import java.nio.channels.SocketChannel; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Iterator; @@ -155,6 +156,15 @@ class HttpClientImpl extends HttpClient implements BufferHandler { selmgr.register(exchange); } + /** + * Only used from RawChannel to disconnect the channel from + * the selector + */ + void cancelRegistration(SocketChannel s) { + selmgr.cancel(s); + } + + Http2ClientImpl client2() { return client2; } @@ -220,6 +230,13 @@ class HttpClientImpl extends HttpClient implements BufferHandler { selector.wakeup(); } + synchronized void cancel(SocketChannel e) { + SelectionKey key = e.keyFor(selector); + if (key != null) + key.cancel(); + selector.wakeup(); + } + void wakeupSelector() { selector.wakeup(); } diff --git a/jdk/src/java.httpclient/share/classes/java/net/http/HttpResponseImpl.java b/jdk/src/java.httpclient/share/classes/java/net/http/HttpResponseImpl.java index 10758d6db99..dcbfbdb8f1a 100644 --- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpResponseImpl.java +++ b/jdk/src/java.httpclient/share/classes/java/net/http/HttpResponseImpl.java @@ -176,7 +176,7 @@ class HttpResponseImpl extends HttpResponse { * * @return */ - RawChannel rawChannel() { + RawChannel rawChannel() throws IOException { if (rawchan == null) { rawchan = new RawChannel(request.client(), connection); } diff --git a/jdk/src/java.httpclient/share/classes/java/net/http/Log.java b/jdk/src/java.httpclient/share/classes/java/net/http/Log.java index 991edfefa6c..51e5ce9633e 100644 --- a/jdk/src/java.httpclient/share/classes/java/net/http/Log.java +++ b/jdk/src/java.httpclient/share/classes/java/net/http/Log.java @@ -88,7 +88,7 @@ abstract class Log implements System.Logger { logging |= TRACE; break; case "all": - logging |= CONTENT|HEADERS|REQUESTS|FRAMES|ERRORS|TRACE; + logging |= CONTENT|HEADERS|REQUESTS|FRAMES|ERRORS|TRACE|SSL; break; } if (val.startsWith("frames")) { diff --git a/jdk/src/java.httpclient/share/classes/java/net/http/RawChannel.java b/jdk/src/java.httpclient/share/classes/java/net/http/RawChannel.java index e4dc3b00b8d..5f6fb4df6c0 100644 --- a/jdk/src/java.httpclient/share/classes/java/net/http/RawChannel.java +++ b/jdk/src/java.httpclient/share/classes/java/net/http/RawChannel.java @@ -29,6 +29,7 @@ import java.nio.channels.ByteChannel; import java.nio.channels.GatheringByteChannel; import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; +import java.nio.channels.SocketChannel; // // Used to implement WebSocket. Each RawChannel corresponds to a TCP connection @@ -56,9 +57,21 @@ final class RawChannel implements ByteChannel, GatheringByteChannel { interface NonBlockingEvent extends RawEvent { } - RawChannel(HttpClientImpl client, HttpConnection connection) { + RawChannel(HttpClientImpl client, HttpConnection connection) + throws IOException { this.client = client; this.connection = connection; + SocketChannel chan = connection.channel(); + client.cancelRegistration(chan); + chan.configureBlocking(false); + } + + SocketChannel socketChannel() { + return connection.channel(); + } + + ByteBuffer getRemaining() { + return connection.getRemaining(); } private class RawAsyncEvent extends AsyncEvent { diff --git a/jdk/src/java.httpclient/share/classes/java/net/http/Stream.java b/jdk/src/java.httpclient/share/classes/java/net/http/Stream.java index cea95c8f2f6..91252c93b88 100644 --- a/jdk/src/java.httpclient/share/classes/java/net/http/Stream.java +++ b/jdk/src/java.httpclient/share/classes/java/net/http/Stream.java @@ -32,6 +32,9 @@ import java.nio.ByteBuffer; import java.util.LinkedList; import java.util.List; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; import java.util.function.BiFunction; import java.util.function.LongConsumer; @@ -409,13 +412,20 @@ class Stream extends ExchangeImpl { @Override HttpResponseImpl getResponse() throws IOException { try { - return getResponseAsync(null).join(); - } catch (Throwable e) { + if (request.timeval() > 0) { + return getResponseAsync(null).get( + request.timeval(), TimeUnit.MILLISECONDS); + } else { + return getResponseAsync(null).join(); + } + } catch (TimeoutException e) { + throw new HttpTimeoutException("Response timed out"); + } catch (InterruptedException | ExecutionException e) { Throwable t = e.getCause(); if (t instanceof IOException) { throw (IOException)t; } - throw e; + throw new IOException(e); } } diff --git a/jdk/src/java.httpclient/share/classes/java/net/http/WSOpeningHandshake.java b/jdk/src/java.httpclient/share/classes/java/net/http/WSOpeningHandshake.java index 6a7ddaa882c..d3cc7da3520 100644 --- a/jdk/src/java.httpclient/share/classes/java/net/http/WSOpeningHandshake.java +++ b/jdk/src/java.httpclient/share/classes/java/net/http/WSOpeningHandshake.java @@ -24,6 +24,8 @@ */ package java.net.http; +import java.io.UncheckedIOException; +import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; @@ -126,6 +128,8 @@ final class WSOpeningHandshake { return CompletableFuture.completedFuture(result); } catch (WebSocketHandshakeException e) { return CompletableFuture.failedFuture(e); + } catch (UncheckedIOException ee) { + return CompletableFuture.failedFuture(ee.getCause()); } }); } @@ -149,7 +153,12 @@ final class WSOpeningHandshake { checkAccept(response, h); checkExtensions(response, h); String subprotocol = checkAndReturnSubprotocol(response, h); - RawChannel channel = ((HttpResponseImpl) response).rawChannel(); + RawChannel channel = null; + try { + channel = ((HttpResponseImpl) response).rawChannel(); + } catch (IOException e) { + throw new UncheckedIOException(e); + } return new Result(subprotocol, channel); } diff --git a/jdk/src/java.instrument/share/native/libinstrument/InvocationAdapter.c b/jdk/src/java.instrument/share/native/libinstrument/InvocationAdapter.c index 0c57f8b289d..a74b2b725ba 100644 --- a/jdk/src/java.instrument/share/native/libinstrument/InvocationAdapter.c +++ b/jdk/src/java.instrument/share/native/libinstrument/InvocationAdapter.c @@ -518,18 +518,22 @@ static void splitPathList(const char* str, int* pathCount, char*** paths) { int count = 0; char** segments = NULL; + char** new_segments; char* c = (char*) str; while (*c != '\0') { while (*c == ' ') c++; /* skip leading spaces */ if (*c == '\0') { break; } - if (segments == NULL) { - segments = (char**)malloc( sizeof(char**) ); - } else { - segments = (char**)realloc( segments, (count+1)*sizeof(char**) ); + new_segments = (char**)realloc(segments, (count+1)*sizeof(char*)); + if (new_segments == NULL) { + jplis_assert(0); + free(segments); + count = 0; + segments = NULL; + break; } - jplis_assert(segments != (char**)NULL); + segments = new_segments; segments[count++] = c; c = strchr(c, ' '); if (c == NULL) { diff --git a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java index bc06286e8da..f429452419e 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/LogManager.java @@ -2506,15 +2506,12 @@ public class LogManager { } } - // Management Support - private static LoggingMXBean loggingMXBean = null; /** * String representation of the * {@link javax.management.ObjectName} for the management interface * for the logging facility. * * @see java.lang.management.PlatformLoggingMXBean - * @see java.util.logging.LoggingMXBean * * @since 1.5 */ @@ -2523,24 +2520,21 @@ public class LogManager { /** * Returns {@code LoggingMXBean} for managing loggers. - * An alternative way to manage loggers is through the - * {@link java.lang.management.PlatformLoggingMXBean} interface - * that can be obtained by calling: - * <pre> - * PlatformLoggingMXBean logging = {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class) - * ManagementFactory.getPlatformMXBean}(PlatformLoggingMXBean.class); - * </pre> * * @return a {@link LoggingMXBean} object. * + * @deprecated {@code java.util.logging.LoggingMXBean} is deprecated and + * replaced with {@code java.lang.management.PlatformLoggingMXBean}. Use + * {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class) + * ManagementFactory.getPlatformMXBean}(PlatformLoggingMXBean.class) + * instead. + * * @see java.lang.management.PlatformLoggingMXBean * @since 1.5 */ + @Deprecated(since="9") public static synchronized LoggingMXBean getLoggingMXBean() { - if (loggingMXBean == null) { - loggingMXBean = new Logging(); - } - return loggingMXBean; + return Logging.getInstance(); } /** diff --git a/jdk/src/java.logging/share/classes/java/util/logging/Logging.java b/jdk/src/java.logging/share/classes/java/util/logging/Logging.java index 70c59503e4e..716e8bc150d 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/Logging.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/Logging.java @@ -44,16 +44,18 @@ import java.util.ArrayList; * @see Logger * @see LogManager */ -class Logging implements LoggingMXBean { +@SuppressWarnings("deprecation") // implements LoggingMXBean +final class Logging implements LoggingMXBean { private static LogManager logManager = LogManager.getLogManager(); /** Constructor of Logging which is the implementation class * of LoggingMXBean. */ - Logging() { + private Logging() { } + @Override public List<String> getLoggerNames() { Enumeration<String> loggers = logManager.getLoggerNames(); ArrayList<String> array = new ArrayList<>(); @@ -65,6 +67,7 @@ class Logging implements LoggingMXBean { } private static String EMPTY_STRING = ""; + @Override public String getLoggerLevel(String loggerName) { Logger l = logManager.getLogger(loggerName); if (l == null) { @@ -79,6 +82,7 @@ class Logging implements LoggingMXBean { } } + @Override public void setLoggerLevel(String loggerName, String levelName) { if (loggerName == null) { throw new NullPointerException("loggerName is null"); @@ -102,6 +106,7 @@ class Logging implements LoggingMXBean { logger.setLevel(level); } + @Override public String getParentLoggerName( String loggerName ) { Logger l = logManager.getLogger( loggerName ); if (l == null) { @@ -116,4 +121,11 @@ class Logging implements LoggingMXBean { return p.getName(); } } + + static Logging getInstance() { + return INSTANCE; + } + + private static final Logging INSTANCE = new Logging(); + } diff --git a/jdk/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java b/jdk/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java index 9d545d8d28d..812eb36622d 100644 --- a/jdk/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java +++ b/jdk/src/java.logging/share/classes/java/util/logging/LoggingMXBean.java @@ -27,30 +27,23 @@ package java.util.logging; /** - * The management interface for the logging facility. It is recommended - * to use the {@link java.lang.management.PlatformLoggingMXBean} management - * interface that implements all attributes defined in this - * {@code LoggingMXBean}. The - * {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class) - * ManagementFactory.getPlatformMXBean} method can be used to obtain - * the {@code PlatformLoggingMXBean} object representing the management - * interface for logging. + * The management interface for the logging facility. * - * <p>There is a single global instance of the {@code LoggingMXBean}. - * This instance is an {@link javax.management.MXBean MXBean} that - * can be obtained by calling the {@link LogManager#getLoggingMXBean} - * method or from the - * {@linkplain java.lang.management.ManagementFactory#getPlatformMBeanServer + * {@link java.lang.management.PlatformLoggingMXBean + * java.lang.management.PlatformLoggingMXBean} is the management interface + * for logging facility registered in the {@link + * java.lang.management.ManagementFactory#getPlatformMBeanServer() * platform MBeanServer}. - * <p> - * The {@link javax.management.ObjectName ObjectName} that uniquely identifies - * the management interface for logging within the {@code MBeanServer} is: - * <pre> - * {@link LogManager#LOGGING_MXBEAN_NAME java.util.logging:type=Logging} - * </pre> - * <p> - * The instance registered in the platform {@code MBeanServer} - * is also a {@link java.lang.management.PlatformLoggingMXBean}. + * It is recommended to use the {@code PlatformLoggingMXBean} obtained via + * the {@link java.lang.management.ManagementFactory#getPlatformMXBean(Class) + * ManagementFactory.getPlatformMXBean(PlatformLoggingMXBean.class)} method. + * + * @deprecated {@code LoggingMXBean} is no longer a {@link + * java.lang.management.PlatformManagedObject platform MXBean} and is replaced + * with {@link java.lang.management.PlatformLoggingMXBean}. + * It will not register in the platform {@code MBeanServer}. + * Use {@code ManagementFactory.getPlatformMXBean(PlatformLoggingMXBean.class)} + * instead. * * @author Ron Mann * @author Mandy Chung @@ -58,6 +51,7 @@ package java.util.logging; * * @see java.lang.management.PlatformLoggingMXBean */ +@Deprecated(since="9") public interface LoggingMXBean { /** diff --git a/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java b/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java index 8d0083ff807..9a6252add85 100644 --- a/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java +++ b/jdk/src/java.management/share/classes/java/lang/management/ManagementFactory.java @@ -598,9 +598,8 @@ public class ManagementFactory { try { final ObjectName objName = new ObjectName(mxbeanName); - // skip the isInstanceOf check for LoggingMXBean String intfName = mxbeanInterface.getName(); - if (!connection.isInstanceOf(objName, intfName)) { + if (!isInstanceOf(connection, objName, intfName)) { throw new IllegalArgumentException(mxbeanName + " is not an instance of " + mxbeanInterface); } @@ -616,6 +615,33 @@ public class ManagementFactory { } } + // This makes it possible to obtain an instance of LoggingMXBean + // using newPlatformMXBeanProxy(mbs, on, LoggingMXBean.class) + // even though the underlying MXBean no longer implements + // java.util.logging.LoggingMXBean. + // Altough java.util.logging.LoggingMXBean is deprecated, an application + // that uses newPlatformMXBeanProxy(mbs, on, LoggingMXBean.class) will + // continue to work. + // + private static boolean isInstanceOf(MBeanServerConnection connection, + ObjectName objName, String intfName) + throws InstanceNotFoundException, IOException + { + // special case for java.util.logging.LoggingMXBean. + // java.util.logging.LoggingMXBean is deprecated and + // replaced with java.lang.management.PlatformLoggingMXBean, + // so we will consider that any MBean implementing + // java.lang.management.PlatformLoggingMXBean also implements + // java.util.logging.LoggingMXBean. + if ("java.util.logging.LoggingMXBean".equals(intfName)) { + if (connection.isInstanceOf(objName, + PlatformLoggingMXBean.class.getName())) { + return true; + } + } + return connection.isInstanceOf(objName, intfName); + } + /** * Returns the platform MXBean implementing * the given {@code mxbeanInterface} which is specified diff --git a/jdk/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java b/jdk/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java index d18d0b30c40..80595dd75d6 100644 --- a/jdk/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java +++ b/jdk/src/java.management/share/classes/java/lang/management/PlatformLoggingMXBean.java @@ -44,10 +44,6 @@ package java.lang.management; * {@link java.util.logging.LogManager#LOGGING_MXBEAN_NAME java.util.logging:type=Logging} * </pre> * - * <p>The instance registered in the platform {@code MBeanServer} with - * this {@code ObjectName} implements all attributes defined by - * {@link java.util.logging.LoggingMXBean}. - * * @since 1.7 */ public interface PlatformLoggingMXBean extends PlatformManagedObject { diff --git a/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java b/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java index 44682b29971..4eb5742b2ba 100644 --- a/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java +++ b/jdk/src/java.management/share/classes/sun/management/ManagementFactoryHelper.java @@ -26,6 +26,8 @@ package sun.management; import java.lang.management.*; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import javax.management.InstanceAlreadyExistsException; import javax.management.InstanceNotFoundException; import javax.management.MBeanServer; @@ -43,9 +45,13 @@ import jdk.internal.misc.SharedSecrets; import java.util.ArrayList; import java.util.List; -import java.lang.reflect.Constructor; -import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Module; +import java.lang.reflect.UndeclaredThrowableException; import java.security.PrivilegedAction; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; /** * ManagementFactoryHelper provides static factory methods to create @@ -66,6 +72,7 @@ public class ManagementFactoryHelper { return jvm; } + static final String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging"; private static ClassLoadingImpl classMBean = null; private static MemoryImpl memoryMBean = null; private static ThreadImpl threadMBean = null; @@ -145,74 +152,138 @@ public class ManagementFactoryHelper { } public static PlatformLoggingMXBean getPlatformLoggingMXBean() { - if (LoggingMXBeanSupport.isAvailable()) { - return PlatformLoggingImpl.instance; + if (LoggingMXBeanAccess.isAvailable()) { + return PlatformLoggingImpl.MBEAN; } else { return null; } } public static boolean isPlatformLoggingMXBeanAvailable() { - return LoggingMXBeanSupport.isAvailable(); + return LoggingMXBeanAccess.isAvailable(); } - /** - * The logging MXBean object is an instance of - * PlatformLoggingMXBean and java.util.logging.LoggingMXBean - * but it can't directly implement two MXBean interfaces - * as a compliant MXBean implements exactly one MXBean interface, - * or if it implements one interface that is a subinterface of - * all the others; otherwise, it is a non-compliant MXBean - * and MBeanServer will throw NotCompliantMBeanException. - * See the Definition of an MXBean section in javax.management.MXBean spec. - * - * To create a compliant logging MXBean, define a LoggingMXBean interface - * that extend PlatformLoggingMXBean and j.u.l.LoggingMXBean - */ - public interface LoggingMXBean - extends PlatformLoggingMXBean, java.util.logging.LoggingMXBean { - } - - // This is a trick: if java.util.logging is not present then - // attempting to access something that implements - // java.util.logging.LoggingMXBean will trigger a CNFE. - // So we cannot directly call any static method or access any static field - // on PlatformLoggingImpl, as we would risk raising a CNFE. - // Instead we use this intermediate LoggingMXBeanSupport class to determine + // The LoggingMXBeanAccess class uses reflection to determine // whether java.util.logging is present, and load the actual LoggingMXBean // implementation. // - static final class LoggingMXBeanSupport { - final static Object loggingImpl = - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - try { - // create a LoggingProxyImpl instance when - // java.util.logging classes exist - Class<?> c = Class.forName("java.util.logging.Logging", true, null); - Constructor<?> cons = c.getDeclaredConstructor(); - cons.setAccessible(true); - return cons.newInstance(); - } catch (ClassNotFoundException cnf) { - return null; - } catch (NoSuchMethodException | InstantiationException - | IllegalAccessException | InvocationTargetException e) { - throw new AssertionError(e); - } - }}); + static final class LoggingMXBeanAccess { + + final static String LOG_MANAGER_CLASS_NAME = "java.util.logging.LogManager"; + final static String LOGGING_MXBEAN_CLASS_NAME = "java.util.logging.LoggingMXBean"; + final static Class<?> LOG_MANAGER_CLASS = loadLoggingClass(LOG_MANAGER_CLASS_NAME); static boolean isAvailable() { - return loggingImpl != null; + return LOG_MANAGER_CLASS != null; } + + private static Class<?> loadLoggingClass(String className) { + return AccessController.doPrivileged(new PrivilegedAction<>() { + @Override + public Class<?> run() { + Optional<Module> logging = java.lang.reflect.Layer.boot() + .findModule("java.logging"); + if (logging.isPresent()) { + return Class.forName(logging.get(), className); + } + return null; + } + }); + } + + private Map<String, Method> initMethodMap(Object impl) { + if (impl == null) { + return Collections.emptyMap(); + } + Class<?> intfClass = loadLoggingClass(LOGGING_MXBEAN_CLASS_NAME); + final Map<String, Method> methodsMap = new HashMap<>(); + for (Method m : intfClass.getMethods()) { + try { + // Sanity checking: all public methods present in + // java.util.logging.LoggingMXBean should + // also be in PlatformLoggingMXBean + Method specMethod = PlatformLoggingMXBean.class + .getMethod(m.getName(), m.getParameterTypes()); + if (specMethod.getReturnType().isAssignableFrom(m.getReturnType())) { + if (methodsMap.putIfAbsent(m.getName(), m) != null) { + throw new RuntimeException("unexpected polymorphic method: " + + m.getName()); + } + } + } catch (NoSuchMethodException x) { + // All methods in java.util.logging.LoggingMXBean should + // also be in PlatformLoggingMXBean + throw new InternalError(x); + } + } + return Collections.unmodifiableMap(methodsMap); + } + + private static Object getMXBeanImplementation() { + if (!isAvailable()) { + // should not happen + throw new NoClassDefFoundError(LOG_MANAGER_CLASS_NAME); + } + try { + final Method m = LOG_MANAGER_CLASS.getMethod("getLoggingMXBean"); + return m.invoke(null); + } catch (NoSuchMethodException + | IllegalAccessException + | InvocationTargetException x) { + throw new ExceptionInInitializerError(x); + } + } + + // The implementation object, which will be invoked through + // reflection. The implementation does not need to implement + // PlatformLoggingMXBean, but must declare the same methods + // with same signatures, and they must be public, with one + // exception: + // getObjectName will not be called on the implementation object, + // so the implementation object does not need to declare such + // a method. + final Object impl = getMXBeanImplementation(); + final Map<String, Method> methods = initMethodMap(impl); + + LoggingMXBeanAccess() { + } + + <T> T invoke(String methodName, Object... args) { + Method m = methods.get(methodName); + if (m == null) { + throw new UnsupportedOperationException(methodName); + } + try { + @SuppressWarnings("unchecked") + T result = (T) m.invoke(impl, args); + return result; + } catch (IllegalAccessException ex) { + throw new UnsupportedOperationException(ex); + } catch (InvocationTargetException ex) { + throw unwrap(ex); + } + } + + private static RuntimeException unwrap(InvocationTargetException x) { + Throwable t = x.getCause(); + if (t instanceof RuntimeException) { + return (RuntimeException)t; + } + if (t instanceof Error) { + throw (Error)t; + } + return new UndeclaredThrowableException(t == null ? x : t); + } + + } - static class PlatformLoggingImpl implements LoggingMXBean - { - final static java.util.logging.LoggingMXBean impl = - (java.util.logging.LoggingMXBean) LoggingMXBeanSupport.loggingImpl; - final static PlatformLoggingMXBean instance = new PlatformLoggingImpl(); - final static String LOGGING_MXBEAN_NAME = "java.util.logging:type=Logging"; + static final class PlatformLoggingImpl implements PlatformLoggingMXBean { + + private final LoggingMXBeanAccess loggingAccess; + private PlatformLoggingImpl(LoggingMXBeanAccess loggingAccess) { + this.loggingAccess = loggingAccess; + } private volatile ObjectName objname; // created lazily @Override @@ -232,23 +303,29 @@ public class ManagementFactoryHelper { @Override public java.util.List<String> getLoggerNames() { - return impl.getLoggerNames(); + return loggingAccess.invoke("getLoggerNames"); } @Override public String getLoggerLevel(String loggerName) { - return impl.getLoggerLevel(loggerName); + return loggingAccess.invoke("getLoggerLevel", loggerName); } @Override public void setLoggerLevel(String loggerName, String levelName) { - impl.setLoggerLevel(loggerName, levelName); + loggingAccess.invoke("setLoggerLevel", loggerName, levelName); } @Override public String getParentLoggerName(String loggerName) { - return impl.getParentLoggerName(loggerName); + return loggingAccess.invoke("getParentLoggerName", loggerName); } + + private static PlatformLoggingImpl getInstance() { + return new PlatformLoggingImpl(new LoggingMXBeanAccess()); + } + + static final PlatformLoggingMXBean MBEAN = getInstance(); } private static List<BufferPoolMXBean> bufferPools = null; diff --git a/jdk/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java b/jdk/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java index 59c0be3360e..2944e5d0f13 100644 --- a/jdk/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java +++ b/jdk/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java @@ -194,7 +194,7 @@ public class MarshalInputStream extends ObjectInputStream { /* * Unless we were told to skip this consideration, choose the * "default loader" to simulate the default ObjectInputStream - * resolveClass mechanism (that is, choose the first non-null + * resolveClass mechanism (that is, choose the first non-platform * loader on the execution stack) to maximize the likelihood of * type compatibility with calling code. (This consideration * is skipped during server parameter unmarshalling using the 1.2 @@ -268,8 +268,9 @@ public class MarshalInputStream extends ObjectInputStream { } /* - * Returns the first non-null class loader up the execution stack, or null - * if only code from the null class loader is on the stack. + * Returns the first non-platform class loader up the execution stack, + * or platform class loader if only code from the platform class loader or null + * is on the stack. */ private static ClassLoader latestUserDefinedLoader() { return jdk.internal.misc.VM.latestUserDefinedLoader(); diff --git a/jdk/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java b/jdk/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java index 4a9562b069f..a5e965e5ec3 100644 --- a/jdk/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java +++ b/jdk/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java @@ -258,7 +258,7 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine { /* * Convenience method for simple commands */ - private InputStream executeCommand(String cmd, Object ... args) throws IOException { + public InputStream executeCommand(String cmd, Object ... args) throws IOException { try { return execute(cmd, args); } catch (AgentLoadException x) { diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java new file mode 100644 index 00000000000..b2f2b569859 --- /dev/null +++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/LibMDMech.java @@ -0,0 +1,66 @@ +/** + * Copyright (c) 2016, 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 com.oracle.security.ucrypto; + +/** + * Enum for representing the ucrypto mechanisms. + * + * @since 9 + */ +public enum LibMDMech { + + MD5(new ServiceDesc[] + { sd("MessageDigest", "MD5", "com.oracle.security.ucrypto.NativeDigestMD$MD5") + }), + SHA_1(new ServiceDesc[] + { sd("MessageDigest", "SHA", "com.oracle.security.ucrypto.NativeDigestMD$SHA1", + "SHA-1", "SHA1") + }), + SHA_256(new ServiceDesc[] + { sd("MessageDigest", "SHA-256", "com.oracle.security.ucrypto.NativeDigestMD$SHA256", + "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1") + }), + SHA_384(new ServiceDesc[] + { sd("MessageDigest", "SHA-384", "com.oracle.security.ucrypto.NativeDigestMD$SHA384", + "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2") + }), + SHA_512(new ServiceDesc[] + { sd("MessageDigest", "SHA-512", "com.oracle.security.ucrypto.NativeDigestMD$SHA512", + "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3") + }); + + ServiceDesc[] serviceDescs; + + private static ServiceDesc sd(String type, String algo, String cn, String... aliases) { + return new ServiceDesc(type, algo, cn, aliases); + } + + LibMDMech(ServiceDesc[] serviceDescs) { + this.serviceDescs = serviceDescs; + } + + public ServiceDesc[] getServiceDescriptions() { return serviceDescs; } +} diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigest.java b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigest.java index 9c0929a95b2..98292eb5561 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigest.java +++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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,23 +33,67 @@ import java.util.concurrent.ConcurrentSkipListSet; import java.security.*; /** - * MessageDigest implementation class. This class currently supports - * MD5, SHA1, SHA256, SHA384, and SHA512 + * MessageDigest implementation class using native Ucrypto API. + * This class currently supports: MD5, SHA-2 (224, 256, 384, 512) + * and SHA-3 (224, 256, 384, 512) digests * * @since 9 */ -public abstract class NativeDigest extends MessageDigestSpi - implements Cloneable { +abstract class NativeDigest extends MessageDigestSpi { - private static final int MECH_MD5 = 1; - private static final int MECH_SHA1 = 2; - private static final int MECH_SHA256 = 3; - private static final int MECH_SHA224 = 4; - private static final int MECH_SHA384 = 5; - private static final int MECH_SHA512 = 6; + public static final class MD5 extends NativeDigest { + public MD5() { + super(UcryptoMech.CRYPTO_MD5, 16); + } + } + public static final class SHA1 extends NativeDigest { + public SHA1() { + super(UcryptoMech.CRYPTO_SHA1, 20); + } + } + public static final class SHA224 extends NativeDigest { + public SHA224() { + super(UcryptoMech.CRYPTO_SHA224, 28); + } + } + public static final class SHA256 extends NativeDigest { + public SHA256() { + super(UcryptoMech.CRYPTO_SHA256, 32); + } + } + public static final class SHA384 extends NativeDigest { + public SHA384() { + super(UcryptoMech.CRYPTO_SHA384, 48); + } + } + public static final class SHA512 extends NativeDigest { + public SHA512() { + super(UcryptoMech.CRYPTO_SHA512, 64); + } + } + public static final class SHA3_224 extends NativeDigest { + public SHA3_224() { + super(UcryptoMech.CRYPTO_SHA3_224, 28); + } + } + public static final class SHA3_256 extends NativeDigest { + public SHA3_256() { + super(UcryptoMech.CRYPTO_SHA3_256, 32); + } + } + public static final class SHA3_384 extends NativeDigest { + public SHA3_384() { + super(UcryptoMech.CRYPTO_SHA3_384, 48); + } + } + public static final class SHA3_512 extends NativeDigest { + public SHA3_512() { + super(UcryptoMech.CRYPTO_SHA3_512, 64); + } + } private final int digestLen; - private final int mech; + private final UcryptoMech mech; // field for ensuring native memory is freed private DigestContextRef pCtxt = null; @@ -64,10 +108,9 @@ public abstract class NativeDigest extends MessageDigestSpi // referents are GC'ed so we can do post-mortem processing private static Set<DigestContextRef> refList = new ConcurrentSkipListSet<DigestContextRef>(); - // Collections.synchronizedSortedSet(new TreeSet<DigestContextRef>()); private final long id; - private final int mech; + private final UcryptoMech mech; private static void drainRefQueueBounded() { while (true) { @@ -77,7 +120,7 @@ public abstract class NativeDigest extends MessageDigestSpi } } - DigestContextRef(NativeDigest nc, long id, int mech) { + DigestContextRef(NativeDigest nc, long id, UcryptoMech mech) { super(nc, refQueue); this.id = id; this.mech = mech; @@ -98,18 +141,22 @@ public abstract class NativeDigest extends MessageDigestSpi refList.remove(this); try { if (needFree) { - UcryptoProvider.debug("Resource: free Digest Ctxt " + this.id); - NativeDigest.nativeFree(mech, id); - } else UcryptoProvider.debug("Resource: stop tracking Digest Ctxt " + this.id); + UcryptoProvider.debug("Resource: free Digest Ctxt " + + this.id); + NativeDigest.nativeFree(mech.value(), id); + } else { + UcryptoProvider.debug("Resource: discard Digest Ctxt " + + this.id); + } } finally { this.clear(); } } } - NativeDigest(int mech, int digestLen) { - this.digestLen = digestLen; + NativeDigest(UcryptoMech mech, int digestLen) { this.mech = mech; + this.digestLen = digestLen; } // see JCA spec @@ -153,10 +200,10 @@ public abstract class NativeDigest extends MessageDigestSpi } if (pCtxt == null) { - pCtxt = new DigestContextRef(this, nativeInit(mech), mech); + pCtxt = new DigestContextRef(this, nativeInit(mech.value()), mech); } try { - int status = nativeDigest(mech, pCtxt.id, out, ofs, digestLen); + int status = nativeDigest(mech.value(), pCtxt.id, out, ofs, digestLen); if (status != 0) { throw new DigestException("Internal error: " + status); } @@ -183,64 +230,24 @@ public abstract class NativeDigest extends MessageDigestSpi + len + ". in.length: " + in.length); } if (pCtxt == null) { - pCtxt = new DigestContextRef(this, nativeInit(mech), mech); + pCtxt = new DigestContextRef(this, nativeInit(mech.value()), mech); } - nativeUpdate(mech, pCtxt.id, in, ofs, len); + nativeUpdate(mech.value(), pCtxt.id, in, ofs, len); } /** * Clone this digest. */ public synchronized Object clone() throws CloneNotSupportedException { - NativeDigest copy = (NativeDigest) super.clone(); - // re-work the fields that cannot be copied over - if (pCtxt != null) { - copy.pCtxt = new DigestContextRef(this, nativeClone(mech, pCtxt.id), mech); - } - return copy; + throw new CloneNotSupportedException("Clone is not supported"); } // return pointer to the context - protected static native long nativeInit(int mech); + protected static final native long nativeInit(int mech); // return status code; always 0 - protected static native int nativeUpdate(int mech, long pCtxt, byte[] in, int ofs, int inLen); + protected static final native int nativeUpdate(int mech, long pCtxt, byte[] in, int ofs, int inLen); // return status code; always 0 - protected static native int nativeDigest(int mech, long pCtxt, byte[] out, int ofs, int digestLen); - // return pointer to the duplicated context - protected static native long nativeClone(int mech, long pCtxt); + protected static final native int nativeDigest(int mech, long pCtxt, byte[] out, int ofs, int digestLen); // free the specified context - private native static void nativeFree(int mech, long id); - - - public static final class MD5 extends NativeDigest { - public MD5() { - super(MECH_MD5, 16); - } - } - - public static final class SHA1 extends NativeDigest { - public SHA1() { - super(MECH_SHA1, 20); - } - } - - public static final class SHA256 extends NativeDigest { - public SHA256() { - super(MECH_SHA256, 32); - } - } - - - public static final class SHA384 extends NativeDigest { - public SHA384() { - super(MECH_SHA384, 48); - } - } - - - public static final class SHA512 extends NativeDigest { - public SHA512() { - super(MECH_SHA512, 64); - } - } + private static final native void nativeFree(int mech, long id); } diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigestMD.java b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigestMD.java new file mode 100644 index 00000000000..132fcafa9b4 --- /dev/null +++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/NativeDigestMD.java @@ -0,0 +1,246 @@ +/* + * Copyright (c) 2016, 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 com.oracle.security.ucrypto; + +import java.lang.ref.*; + +import java.io.ByteArrayOutputStream; +import java.util.*; +import java.util.concurrent.ConcurrentSkipListSet; +import java.security.*; + +/** + * MessageDigest implementation class for libMD API. This class currently supports + * MD5, SHA1, SHA256, SHA384, and SHA512 + * + * @since 9 + */ +public abstract class NativeDigestMD extends MessageDigestSpi + implements Cloneable { + + private static final int MECH_MD5 = 1; + private static final int MECH_SHA1 = 2; + private static final int MECH_SHA256 = 3; + private static final int MECH_SHA224 = 4; + private static final int MECH_SHA384 = 5; + private static final int MECH_SHA512 = 6; + + private final int digestLen; + private final int mech; + + // field for ensuring native memory is freed + private DigestContextRef pCtxt = null; + + private static class DigestContextRef extends PhantomReference<NativeDigestMD> + implements Comparable<DigestContextRef> { + + private static ReferenceQueue<NativeDigestMD> refQueue = + new ReferenceQueue<NativeDigestMD>(); + + // Needed to keep these references from being GC'ed until when their + // referents are GC'ed so we can do post-mortem processing + private static Set<DigestContextRef> refList = + new ConcurrentSkipListSet<DigestContextRef>(); + // Collections.synchronizedSortedSet(new TreeSet<DigestContextRef>()); + + private final long id; + private final int mech; + + private static void drainRefQueueBounded() { + while (true) { + DigestContextRef next = (DigestContextRef) refQueue.poll(); + if (next == null) break; + next.dispose(true); + } + } + + DigestContextRef(NativeDigestMD nc, long id, int mech) { + super(nc, refQueue); + this.id = id; + this.mech = mech; + refList.add(this); + UcryptoProvider.debug("Resource: track Digest Ctxt " + this.id); + drainRefQueueBounded(); + } + + public int compareTo(DigestContextRef other) { + if (this.id == other.id) { + return 0; + } else { + return (this.id < other.id) ? -1 : 1; + } + } + + void dispose(boolean needFree) { + refList.remove(this); + try { + if (needFree) { + UcryptoProvider.debug("Resource: free Digest Ctxt " + this.id); + NativeDigestMD.nativeFree(mech, id); + } else UcryptoProvider.debug("Resource: stop tracking Digest Ctxt " + this.id); + } finally { + this.clear(); + } + } + } + + NativeDigestMD(int mech, int digestLen) { + this.digestLen = digestLen; + this.mech = mech; + } + + // see JCA spec + protected int engineGetDigestLength() { + return digestLen; + } + + // see JCA spec + protected synchronized void engineReset() { + if (pCtxt != null) { + pCtxt.dispose(true); + pCtxt = null; + } + } + + // see JCA spec + protected synchronized byte[] engineDigest() { + byte[] digest = new byte[digestLen]; + try { + int len = engineDigest(digest, 0, digestLen); + if (len != digestLen) { + throw new UcryptoException("Digest length mismatch." + + " Len: " + len + ". digestLen: " + digestLen); + } + return digest; + } catch (DigestException de) { + throw new UcryptoException("Internal error", de); + } + } + + // see JCA spec + protected synchronized int engineDigest(byte[] out, int ofs, int len) + throws DigestException { + if (len < digestLen) { + throw new DigestException("Output buffer must be at least " + + digestLen + " bytes long. Got: " + len); + } + if ((ofs < 0) || (len < 0) || (ofs > out.length - len)) { + throw new DigestException("Buffer too short to store digest. " + + "ofs: " + ofs + ". len: " + len + ". out.length: " + out.length); + } + + if (pCtxt == null) { + pCtxt = new DigestContextRef(this, nativeInit(mech), mech); + } + try { + int status = nativeDigest(mech, pCtxt.id, out, ofs, digestLen); + if (status != 0) { + throw new DigestException("Internal error: " + status); + } + } finally { + pCtxt.dispose(false); + pCtxt = null; + } + return digestLen; + } + + // see JCA spec + protected synchronized void engineUpdate(byte in) { + byte[] temp = { in }; + engineUpdate(temp, 0, 1); + } + + // see JCA spec + protected synchronized void engineUpdate(byte[] in, int ofs, int len) { + if (len == 0) { + return; + } + if ((ofs < 0) || (len < 0) || (ofs > in.length - len)) { + throw new ArrayIndexOutOfBoundsException("ofs: " + ofs + ". len: " + + len + ". in.length: " + in.length); + } + if (pCtxt == null) { + pCtxt = new DigestContextRef(this, nativeInit(mech), mech); + } + nativeUpdate(mech, pCtxt.id, in, ofs, len); + } + + /** + * Clone this digest. + */ + public synchronized Object clone() throws CloneNotSupportedException { + NativeDigestMD copy = (NativeDigestMD) super.clone(); + // re-work the fields that cannot be copied over + if (pCtxt != null) { + copy.pCtxt = new DigestContextRef(this, nativeClone(mech, pCtxt.id), mech); + } + return copy; + } + + // return pointer to the context + protected static final native long nativeInit(int mech); + // return status code; always 0 + protected static final native int nativeUpdate(int mech, long pCtxt, byte[] in, int ofs, int inLen); + // return status code; always 0 + protected static final native int nativeDigest(int mech, long pCtxt, byte[] out, int ofs, int digestLen); + // return pointer to the duplicated context + protected static final native long nativeClone(int mech, long pCtxt); + // free the specified context + private static final native void nativeFree(int mech, long id); + + + public static final class MD5 extends NativeDigestMD { + public MD5() { + super(MECH_MD5, 16); + } + } + + public static final class SHA1 extends NativeDigestMD { + public SHA1() { + super(MECH_SHA1, 20); + } + } + + public static final class SHA256 extends NativeDigestMD { + public SHA256() { + super(MECH_SHA256, 32); + } + } + + + public static final class SHA384 extends NativeDigestMD { + public SHA384() { + super(MECH_SHA384, 48); + } + } + + + public static final class SHA512 extends NativeDigestMD { + public SHA512() { + super(MECH_SHA512, 64); + } + } +} diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java index cb6b4ffe597..ebc436a52c8 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java +++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoMech.java @@ -1,5 +1,5 @@ /** - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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,8 +25,6 @@ package com.oracle.security.ucrypto; -import java.util.HashMap; - /** * Enum for representing the ucrypto mechanisms. * @@ -35,78 +33,126 @@ import java.util.HashMap; // Check /usr/include/libsoftcrypto.h for updates public enum UcryptoMech { - CRYPTO_AES_ECB(1, new ServiceDesc[] + CRYPTO_AES_ECB(new ServiceDesc[] { sd("Cipher", "AES/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding"), sd("Cipher", "AES/ECB/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesEcbPKCS5", "AES"), - sd("Cipher", "AES_128/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes128EcbNoPadding", + sd("Cipher", "AES_128/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding", "2.16.840.1.101.3.4.1.1", "OID.2.16.840.1.101.3.4.1.1"), - sd("Cipher", "AES_192/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes192EcbNoPadding", + sd("Cipher", "AES_192/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding", "2.16.840.1.101.3.4.1.21", "OID.2.16.840.1.101.3.4.1.21"), - sd("Cipher", "AES_256/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes256EcbNoPadding", + sd("Cipher", "AES_256/ECB/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesEcbNoPadding", "2.16.840.1.101.3.4.1.41", "OID.2.16.840.1.101.3.4.1.41") }), - CRYPTO_AES_CBC(2, new ServiceDesc[] + CRYPTO_AES_CBC(new ServiceDesc[] { sd("Cipher", "AES/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding"), sd("Cipher", "AES/CBC/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCbcPKCS5"), - sd("Cipher", "AES_128/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes128CbcNoPadding", + sd("Cipher", "AES_128/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding", "2.16.840.1.101.3.4.1.2", "OID.2.16.840.1.101.3.4.1.2"), - sd("Cipher", "AES_192/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes192CbcNoPadding", + sd("Cipher", "AES_192/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding", "2.16.840.1.101.3.4.1.22", "OID.2.16.840.1.101.3.4.1.22"), - sd("Cipher", "AES_256/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$Aes256CbcNoPadding", + sd("Cipher", "AES_256/CBC/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCbcNoPadding", "2.16.840.1.101.3.4.1.42", "OID.2.16.840.1.101.3.4.1.42") }), - CRYPTO_AES_CBC_PAD(3, null), // No support from Solaris yet - CRYPTO_AES_CTR(4, new ServiceDesc[] +// CRYPTO_AES_CBC_PAD(null), // Support added since S11.1; however we still use CRYPTO_AES_CBC due to known bug + CRYPTO_AES_CTR(new ServiceDesc[] { sd("Cipher", "AES/CTR/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCtrNoPadding") }), - CRYPTO_AES_CCM(5, null), // Cannot support due to lack of Java API which corresponds to CK_AES_CCM_PARAMS - CRYPTO_AES_GCM(6, new ServiceDesc[] +// CRYPTO_AES_CCM(null), // Need Java API for CK_AES_CCM_PARAMS + CRYPTO_AES_GCM(new ServiceDesc[] { sd("Cipher", "AES/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding"), - sd("Cipher", "AES_128/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$Aes128GcmNoPadding", + sd("Cipher", "AES_128/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding", "2.16.840.1.101.3.4.1.6", "OID.2.16.840.1.101.3.4.1.6"), - sd("Cipher", "AES_192/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$Aes192GcmNoPadding", + sd("Cipher", "AES_192/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding", "2.16.840.1.101.3.4.1.26", "OID.2.16.840.1.101.3.4.1.26"), - sd("Cipher", "AES_256/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$Aes256GcmNoPadding", + sd("Cipher", "AES_256/GCM/NoPadding", "com.oracle.security.ucrypto.NativeGCMCipher$AesGcmNoPadding", "2.16.840.1.101.3.4.1.46", "OID.2.16.840.1.101.3.4.1.46") }), - CRYPTO_AES_GMAC(7, null), // No support from Solaris yet - CRYPTO_AES_CFB128(8, new ServiceDesc[] +// CRYPTO_AES_GMAC(null), // No support from Solaris + CRYPTO_AES_CFB128(new ServiceDesc[] { sd("Cipher", "AES/CFB128/NoPadding", "com.oracle.security.ucrypto.NativeCipher$AesCfb128NoPadding"), - sd("Cipher", "AES/CFB128/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCfb128PKCS5") }), - CRYPTO_RSA_PKCS(31, new ServiceDesc[] + sd("Cipher", "AES/CFB128/PKCS5Padding", "com.oracle.security.ucrypto.NativeCipherWithJavaPadding$AesCfb128PKCS5") + }), + + CRYPTO_RSA_PKCS(new ServiceDesc[] { sd("Cipher", "RSA/ECB/PKCS1Padding", "com.oracle.security.ucrypto.NativeRSACipher$PKCS1Padding", - "RSA") }), - CRYPTO_RSA_X_509(32, new ServiceDesc[] + "RSA") + }), + CRYPTO_RSA_X_509(new ServiceDesc[] { sd("Cipher", "RSA/ECB/NoPadding", "com.oracle.security.ucrypto.NativeRSACipher$NoPadding") }), - CRYPTO_MD5_RSA_PKCS(33, new ServiceDesc[] + CRYPTO_MD5_RSA_PKCS(new ServiceDesc[] { sd("Signature", "MD5withRSA", "com.oracle.security.ucrypto.NativeRSASignature$MD5", - "1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4") }), - CRYPTO_SHA1_RSA_PKCS(34, new ServiceDesc[] + "1.2.840.113549.1.1.4", "OID.1.2.840.113549.1.1.4") + }), + CRYPTO_SHA1_RSA_PKCS(new ServiceDesc[] { sd("Signature", "SHA1withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA1", "1.2.840.113549.1.1.5", "OID.1.2.840.113549.1.1.5", - "1.3.14.3.2.29") }), - CRYPTO_SHA256_RSA_PKCS(35, new ServiceDesc[] + "1.3.14.3.2.29") + }), + CRYPTO_SHA256_RSA_PKCS(new ServiceDesc[] { sd("Signature", "SHA256withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA256", - "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11") }), - CRYPTO_SHA384_RSA_PKCS(36, new ServiceDesc[] + "1.2.840.113549.1.1.11", "OID.1.2.840.113549.1.1.11") + }), + CRYPTO_SHA384_RSA_PKCS(new ServiceDesc[] { sd("Signature", "SHA384withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA384", - "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12") }), - CRYPTO_SHA512_RSA_PKCS(37, new ServiceDesc[] + "1.2.840.113549.1.1.12", "OID.1.2.840.113549.1.1.12") + }), + CRYPTO_SHA512_RSA_PKCS(new ServiceDesc[] { sd("Signature", "SHA512withRSA", "com.oracle.security.ucrypto.NativeRSASignature$SHA512", - "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13") }); + "1.2.840.113549.1.1.13", "OID.1.2.840.113549.1.1.13") + }), - private final int mech; + CRYPTO_MD5(new ServiceDesc[] + { sd("MessageDigest", "MD5", "com.oracle.security.ucrypto.NativeDigest$MD5") }), + CRYPTO_SHA1(new ServiceDesc[] + { sd("MessageDigest", "SHA", "com.oracle.security.ucrypto.NativeDigest$SHA1", "SHA-1", "SHA1") }), + CRYPTO_SHA224(new ServiceDesc[] + { sd("MessageDigest", "SHA-224", "com.oracle.security.ucrypto.NativeDigest$SHA224", + "2.16.840.1.101.3.4.2.4", "OID.2.16.840.1.101.3.4.2.4") + }), + CRYPTO_SHA256(new ServiceDesc[] + { sd("MessageDigest", "SHA-256", "com.oracle.security.ucrypto.NativeDigest$SHA256", + "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1") + }), + CRYPTO_SHA384(new ServiceDesc[] + { sd("MessageDigest", "SHA-384", "com.oracle.security.ucrypto.NativeDigest$SHA384", + "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2") + }), + CRYPTO_SHA512(new ServiceDesc[] + { sd("MessageDigest", "SHA-512", "com.oracle.security.ucrypto.NativeDigest$SHA512", + "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3") + }), + CRYPTO_SHA3_224(new ServiceDesc[] + { sd("MessageDigest", "SHA3-224", "com.oracle.security.ucrypto.NativeDigest$SHA3_224", + "2.16.840.1.101.3.4.2.7", "OID.2.16.840.1.101.3.4.2.7") + }), + CRYPTO_SHA3_256(new ServiceDesc[] + { sd("MessageDigest", "SHA3-256", "com.oracle.security.ucrypto.NativeDigest$SHA3_256", + "2.16.840.1.101.3.4.2.8", "OID.2.16.840.1.101.3.4.2.8") + }), + CRYPTO_SHA3_384(new ServiceDesc[] + { sd("MessageDigest", "SHA3-384", "com.oracle.security.ucrypto.NativeDigest$SHA3_384", + "2.16.840.1.101.3.4.2.9", "OID.2.16.840.1.101.3.4.2.9") + }), + CRYPTO_SHA3_512(new ServiceDesc[] + { sd("MessageDigest", "SHA3-512", "com.oracle.security.ucrypto.NativeDigest$SHA3_512", + "2.16.840.1.101.3.4.2.10", "OID.2.16.840.1.101.3.4.2.10") + }); + + private int mech = 0; private final ServiceDesc[] serviceDescs; private static ServiceDesc sd(String type, String algo, String cn, String... aliases) { return new ServiceDesc(type, algo, cn, aliases); } - UcryptoMech(int mech, ServiceDesc[] serviceDescs) { - this.mech = mech; + UcryptoMech(ServiceDesc[] serviceDescs) { this.serviceDescs = serviceDescs; } + public void setValue(int nativeMechValue) { + this.mech = nativeMechValue; + } + public int value() { return mech; } public ServiceDesc[] getServiceDescriptions() { return serviceDescs; } } diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java index e3595359019..35cceda0757 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java +++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ package com.oracle.security.ucrypto; import java.io.IOException; import java.io.File; +import java.lang.reflect.Constructor; import java.util.*; import java.security.*; @@ -74,48 +75,52 @@ public final class UcryptoProvider extends Provider { if (provProp != null) { boolean[] result = loadLibraries(); if (result.length == 2) { - if (result[0]) { // successfully loaded libmd - provProp.put("MessageDigest.MD5", - sd("MessageDigest", "MD5", - "com.oracle.security.ucrypto.NativeDigest$MD5")); - provProp.put("MessageDigest.SHA", - sd("MessageDigest", "SHA", - "com.oracle.security.ucrypto.NativeDigest$SHA1", - "SHA-1", "SHA1")); - provProp.put("MessageDigest.SHA-256", - sd("MessageDigest", "SHA-256", - "com.oracle.security.ucrypto.NativeDigest$SHA256", - "2.16.840.1.101.3.4.2.1", "OID.2.16.840.1.101.3.4.2.1")); - - provProp.put("MessageDigest.SHA-384", - sd("MessageDigest", "SHA-384", - "com.oracle.security.ucrypto.NativeDigest$SHA384", - "2.16.840.1.101.3.4.2.2", "OID.2.16.840.1.101.3.4.2.2")); - - provProp.put("MessageDigest.SHA-512", - sd("MessageDigest", "SHA-512", - "com.oracle.security.ucrypto.NativeDigest$SHA512", - "2.16.840.1.101.3.4.2.3", "OID.2.16.840.1.101.3.4.2.3")); - }; - if (result[1]) { // successfully loaded libsoftcrypto + // true when libsoftcrypto or libucrypto(S12) has been successfully loaded + if (result[1]) { String supportedMechs = getMechList(); debug("Prov: supported mechs = " + supportedMechs); - for (UcryptoMech m : UcryptoMech.values()) { - if (supportedMechs.indexOf(m.name() + ",") != -1) { + StringTokenizer st = new StringTokenizer(supportedMechs, ":,;"); + // format: numOfSupportedMechs:[mechName,mechValue;]+ + // skip the first one which is numberOfSupportedMechs + st.nextToken(); + while (st.hasMoreTokens()) { + String mechName = st.nextToken(); + int nativeMechVal = Integer.parseInt(st.nextToken()); + try { + UcryptoMech m = Enum.valueOf(UcryptoMech.class, mechName); + m.setValue(nativeMechVal); ServiceDesc[] services = m.getServiceDescriptions(); - // skip unsupported UcryptoMech - if (services == null || services.length == 0) continue; + // defined in UcryptoMech as unsupported + if (services == null || services.length == 0) { + debug("Skip Unsupported Algorithm: " + mechName); + continue; + } for (int p = 0; p < services.length; p++) { ServiceDesc entry = services[p]; provProp.put(entry.getType() + "." + entry.getAlgorithm(), entry); } + } catch (IllegalArgumentException iae) { + // not defined in UcryptoMech + debug("Skip Unrecognized Algorithm: " + mechName); } } // NOTE: GCM support is only available since jdk 7 provProp.put("AlgorithmParameters.GCM", - sd("AlgorithmParameters", "GCM", "com.oracle.security.ucrypto.GCMParameters")); + sd("AlgorithmParameters", "GCM", + "com.oracle.security.ucrypto.GCMParameters")); } + // true when libmd is needed and has been successfully loaded + if (result[0]) { + for (LibMDMech m : LibMDMech.values()) { + ServiceDesc[] services = m.getServiceDescriptions(); + for (ServiceDesc entry : services) { + String sKey = entry.getType() + "." + entry.getAlgorithm(); + // only register if none has been registered + provProp.putIfAbsent(sKey, entry); + } + } + }; } else { debug("Prov: unexpected ucrypto library loading error, got " + result.length); } @@ -138,6 +143,7 @@ public final class UcryptoProvider extends Provider { sd.getAliases(), null); } + @SuppressWarnings("deprecation") @Override public Object newInstance(Object ctrParamObj) throws NoSuchAlgorithmException { @@ -152,53 +158,19 @@ public final class UcryptoProvider extends Provider { int keySize = -1; if (algo.charAt(3) == '_') { keySize = Integer.parseInt(algo.substring(4, 7))/8; - algo = algo.substring(0, 3) + algo.substring(7); } - if (algo.equals("AES/ECB/NoPadding")) { - return new NativeCipher.AesEcbNoPadding(keySize); - } else if (algo.equals("AES/ECB/PKCS5Padding")) { - return new NativeCipherWithJavaPadding.AesEcbPKCS5(); - } else if (algo.equals("AES/CBC/NoPadding")) { - return new NativeCipher.AesCbcNoPadding(keySize); - } else if (algo.equals("AES/CBC/PKCS5Padding")) { - return new NativeCipherWithJavaPadding.AesCbcPKCS5(); - } else if (algo.equals("AES/CTR/NoPadding")) { - return new NativeCipher.AesCtrNoPadding(); - } else if (algo.equals("AES/GCM/NoPadding")) { - return new NativeGCMCipher.AesGcmNoPadding(keySize); - } else if (algo.equals("AES/CFB128/NoPadding")) { - return new NativeCipher.AesCfb128NoPadding(); - } else if (algo.equals("AES/CFB128/PKCS5Padding")) { - return new NativeCipherWithJavaPadding.AesCfb128PKCS5(); - } else if (algo.equals("RSA/ECB/NoPadding")) { - return new NativeRSACipher.NoPadding(); - } else if (algo.equals("RSA/ECB/PKCS1Padding")) { - return new NativeRSACipher.PKCS1Padding(); - } - } else if (type.equals("Signature")) { - if (algo.equals("SHA1withRSA")) { - return new NativeRSASignature.SHA1(); - } else if (algo.equals("SHA256withRSA")) { - return new NativeRSASignature.SHA256(); - } else if (algo.equals("SHA384withRSA")) { - return new NativeRSASignature.SHA384(); - } else if (algo.equals("SHA512withRSA")) { - return new NativeRSASignature.SHA512(); - } else if (algo.equals("MD5withRSA")) { - return new NativeRSASignature.MD5(); - } - } else if (type.equals("MessageDigest")) { - if (algo.equals("SHA")) { - return new NativeDigest.SHA1(); - } else if (algo.equals("SHA-256")) { - return new NativeDigest.SHA256(); - } else if (algo.equals("SHA-384")) { - return new NativeDigest.SHA384(); - } else if (algo.equals("SHA-512")) { - return new NativeDigest.SHA512(); - } else if (algo.equals("MD5")) { - return new NativeDigest.MD5(); + String implClass = getClassName(); + Class<?> clz = Class.forName(implClass); + if (keySize != -1) { + Constructor<?> ctr = clz.getConstructor(int.class); + return ctr.newInstance(keySize); + } else { + return clz.newInstance(); } + } else if (type.equals("Signature") || type.equals("MessageDigest")) { + String implClass = getClassName(); + Class<?> clz = Class.forName(implClass); + return clz.newInstance(); } else if (type.equals("AlgorithmParameters")) { if (algo.equals("GCM")) { return new GCMParameters(); diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/libsoftcrypto.h b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/libsoftcrypto.h deleted file mode 100644 index 17c38557dc5..00000000000 --- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/libsoftcrypto.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ - -#ifndef _LIBSOFTCRYPTO_H -#define _LIBSOFTCRYPTO_H - -#include <sys/types.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> -#include <strings.h> - -typedef enum ucrypto_mech { - CRYPTO_AES_ECB = 1, - CRYPTO_AES_CBC, - CRYPTO_AES_CBC_PAD, - CRYPTO_AES_CTR, - CRYPTO_AES_CCM, - CRYPTO_AES_GCM, - CRYPTO_AES_GMAC, - CRYPTO_AES_CFB128, - CRYPTO_RSA_PKCS = 31, - CRYPTO_RSA_X_509, - CRYPTO_MD5_RSA_PKCS, - CRYPTO_SHA1_RSA_PKCS, - CRYPTO_SHA256_RSA_PKCS, - CRYPTO_SHA384_RSA_PKCS, - CRYPTO_SHA512_RSA_PKCS -} ucrypto_mech_t; - -typedef struct crypto_ctx { - void *cc_provider; - uint_t cc_session; - void *cc_provider_private; /* owned by provider */ - void *cc_framework_private; /* owned by framework */ - uint32_t cc_flags; /* flags */ - void *cc_opstate; /* state */ -} crypto_ctx_t; - -extern int ucrypto_encrypt_init(crypto_ctx_t *context, - ucrypto_mech_t mech_type, uchar_t *key_str, size_t key_len, - void *iv, size_t iv_len); - -extern int ucrypto_encrypt_update(crypto_ctx_t *context, uchar_t *in, - size_t in_len, uchar_t *out, size_t *out_len); - -extern int ucrypto_encrypt_final(crypto_ctx_t *context, uchar_t *out, - size_t *out_len); - -/* Encrypt atomic */ -extern int ucrypto_encrypt(ucrypto_mech_t mech_type, uchar_t *key_str, - size_t key_len, void *iv, size_t iv_len, uchar_t *in, - size_t in_len, uchar_t *out, size_t *out_len); - -/* Decrypt multi-part */ -extern int ucrypto_decrypt_init(crypto_ctx_t *context, - ucrypto_mech_t mech_type, uchar_t *key_str, size_t key_len, - void *iv, size_t iv_len); - -extern int ucrypto_decrypt_update(crypto_ctx_t *context, uchar_t *in, - size_t in_len, uchar_t *out, size_t *out_len); - -extern int ucrypto_decrypt_final(crypto_ctx_t *context, uchar_t *out, - size_t *out_len); - -/* Decrypt atomic */ -extern int ucrypto_decrypt(ucrypto_mech_t mech_type, uchar_t *key_str, - size_t key_len, void *iv, size_t iv_len, uchar_t *in, - size_t in_len, uchar_t *out, size_t *out_len); - -/* Sign multi-part */ -extern int ucrypto_sign_init(crypto_ctx_t *context, ucrypto_mech_t mech_type, - uchar_t *key_str, size_t key_len, void *iv, size_t iv_len); - -extern int ucrypto_sign_update(crypto_ctx_t *context, - uchar_t *data_str, size_t data_len); - -extern int ucrypto_sign_final(crypto_ctx_t *context, - uchar_t *sig_str, size_t *sig_len); - -/* Sign atomic */ -extern int ucrypto_sign(ucrypto_mech_t mech_type, - uchar_t *key_str, size_t key_len, void *iv, size_t iv_len, - uchar_t *data_str, size_t data_len, uchar_t *sig_str, size_t *sig_len); - -/* Verify multi-part */ -extern int ucrypto_verify_init(crypto_ctx_t *context, ucrypto_mech_t mech_type, - uchar_t *key_str, size_t key_len, void *iv, size_t iv_len); - -extern int ucrypto_verify_update(crypto_ctx_t *context, - uchar_t *data_str, size_t data_len); - -extern int ucrypto_verify_final(crypto_ctx_t *context, - uchar_t *sig_str, size_t *sig_len); - -/* Verify atomic */ -extern int ucrypto_verify(ucrypto_mech_t mech_type, - uchar_t *key_str, size_t key_len, void *iv, size_t iv_len, - uchar_t *data_str, size_t data_len, uchar_t *sig, size_t *sig_len); - -extern int ucrypto_get_mechlist(char *str); - -extern const char *ucrypto_id2mech(ucrypto_mech_t mech_type); - -extern ucrypto_mech_t ucrypto_mech2id(const char *str); - -extern int ucrypto_version(); - -typedef struct CK_AES_CTR_PARAMS { - ulong_t ulCounterBits; - uint8_t cb[16]; -} CK_AES_CTR_PARAMS; - -typedef struct CK_AES_GCM_PARAMS { - uchar_t *pIv; - ulong_t ulIvLen; - ulong_t ulIvBits; - uchar_t *pAAD; - ulong_t ulAADLen; - ulong_t ulTagBits; -} CK_AES_GCM_PARAMS; - -typedef struct crypto_object_attribute { - uint64_t oa_type; /* attribute type */ - caddr_t oa_value; /* attribute value */ - ssize_t oa_value_len; /* length of attribute value */ -} crypto_object_attribute_t; - -/* Attribute types to use for passing a RSA public key or a private key. */ -#define SUN_CKA_MODULUS 0x00000120 -#define SUN_CKA_MODULUS_BITS 0x00000121 -#define SUN_CKA_PUBLIC_EXPONENT 0x00000122 -#define SUN_CKA_PRIVATE_EXPONENT 0x00000123 -#define SUN_CKA_PRIME_1 0x00000124 -#define SUN_CKA_PRIME_2 0x00000125 -#define SUN_CKA_EXPONENT_1 0x00000126 -#define SUN_CKA_EXPONENT_2 0x00000127 -#define SUN_CKA_COEFFICIENT 0x00000128 -#define SUN_CKA_PRIME 0x00000130 -#define SUN_CKA_SUBPRIME 0x00000131 -#define SUN_CKA_BASE 0x00000132 - -#define CKK_EC 0x00000003 -#define CKK_GENERIC_SECRET 0x00000010 -#define CKK_RC4 0x00000012 -#define CKK_AES 0x0000001F -#define CKK_DES 0x00000013 -#define CKK_DES2 0x00000014 -#define CKK_DES3 0x00000015 - -#define CKO_PUBLIC_KEY 0x00000002 -#define CKO_PRIVATE_KEY 0x00000003 -#define CKA_CLASS 0x00000000 -#define CKA_VALUE 0x00000011 -#define CKA_KEY_TYPE 0x00000100 -#define CKA_VALUE_LEN 0x00000161 -#define CKA_EC_PARAMS 0x00000180 -#define CKA_EC_POINT 0x00000181 - -#endif /* _LIBSOFTCRYPTO_H */ diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c index 6ddbdc2bed2..126da6d37bd 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c +++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,22 @@ #include "nativeCrypto.h" #include "nativeFunc.h" +/* + * Dumps out byte array in hex with and name and length info + */ +void printError(char* header, int mech, int rv) { + if (mech != -1) { + printf("%s, mech = %d, rv = 0x%0x\n", header, mech, rv); + } else { + printf("%s, rv = 0x%0x\n", header, rv); + } + if (*ftab->ucryptoStrerror != NULL) { + char * reason = (*ftab->ucryptoStrerror)(rv); + printf("\tcause = %s\n", reason); + free(reason); + } +} + /* * Dumps out byte array in hex with and name and length info */ @@ -60,6 +76,16 @@ void throwOutOfMemoryError(JNIEnv *env, const char *msg) (*env)->DeleteLocalRef(env, jExClass); } +/* + * De-allocates all memory associated with crypto_ctx_t + */ +void freeContext(crypto_ctx_t *context) { + if (ftab->ucryptoFreeContext != NULL) { + (*ftab->ucryptoFreeContext)(context); + } + free(context); +} + JNIEXPORT jint JNICALL DEF_JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_VERSION_1_4; } @@ -203,10 +229,10 @@ CipherInit(crypto_ctx_t *context, int encrypt, ucrypto_mech_t mech, } if (encrypt) { rv = (*ftab->ucryptoEncryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen); - if (rv != 0 && DEBUG) printf("ucryptoEncryptInit: ret = 0x%x\n", rv); + if (rv != 0 && DEBUG) printError("ucryptoEncryptInit", mech, rv); } else { rv =(*ftab->ucryptoDecryptInit)(context, mech, jKey, (size_t)jKeyLen, iv, ivLen); - if (rv != 0 && DEBUG) printf("ucryptoDecryptInit: ret = 0x%x\n", rv); + if (rv != 0 && DEBUG) printError("ucryptoDecryptInit", mech, rv); } if (iv != jIv) { @@ -234,15 +260,15 @@ CipherUpdate(crypto_ctx_t *context, int encrypt, unsigned char *bufIn, int inOfs } if (encrypt) { rv = (*ftab->ucryptoEncryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength); - if (rv != 0) { - if (DEBUG) printf("ucryptoEncryptUpdate: ret = 0x%x\n", rv); + if (rv) { + if (DEBUG) printError("ucryptoEncryptUpdate", -1, rv); } else { *outLen = (int)outLength; } } else { rv = (*ftab->ucryptoDecryptUpdate)(context, (unsigned char*)(bufIn+inOfs), (size_t)inLen, (unsigned char*)(bufOut+outOfs), &outLength); - if (rv != 0) { - if (DEBUG) printf("ucryptoDecryptUpdate: ret = 0x%x\n", rv); + if (rv) { + if (DEBUG) printError("ucryptoDecryptUpdate", -1, rv); } else { if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength); *outLen = (int)outLength; @@ -263,16 +289,16 @@ CipherFinal(crypto_ctx_t *context, int encrypt, unsigned char *bufOut, int outOf if (DEBUG) printf("CipherFinal: OutOfs %i, outLen %i\n", outOfs, *outLen); if (encrypt) { rv = (*ftab->ucryptoEncryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength); - if (rv != 0) { - if (DEBUG) printf("ucryptoDecryptFinal: ret = 0x%x\n", rv); + if (rv) { + if (DEBUG) printError("ucryptoDecryptFinal", -1, rv); } else { if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength); *outLen = (int)outLength; } } else { rv = (*ftab->ucryptoDecryptFinal)(context, (unsigned char*)(bufOut+outOfs), &outLength); - if (rv != 0) { - if (DEBUG) printf("ucryptoDecryptFinal: ret = 0x%x\n", rv); + if (rv) { + if (DEBUG) printError("ucryptoDecryptFinal", -1, rv); } else { if (DEBUG) printBytes("BufOut=", (unsigned char*)(bufOut+outOfs), outLength); *outLen = (int)outLength; @@ -285,102 +311,61 @@ CipherFinal(crypto_ctx_t *context, int encrypt, unsigned char *bufOut, int outOf // SPECIAL ENTRIES FOR JVM JNI-BYPASSING OPTIMIZATION //////////////////////////////////////////////////////// jlong JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeInit(jint mech) { - void *pContext = NULL; + crypto_ctx_t *context = NULL; + int rv; - switch (mech) { - case com_oracle_security_ucrypto_NativeDigest_MECH_SHA1: - pContext = (SHA1_CTX *) malloc(sizeof(SHA1_CTX)); - if (pContext != NULL) { - (*ftab->sha1Init)((SHA1_CTX *)pContext); + context = malloc(sizeof(crypto_ctx_t)); + if (context != NULL) { + rv = (*ftab->ucryptoDigestInit)(context, (ucrypto_mech_t) mech, NULL, 0); + if (rv) { + freeContext(context); + if (DEBUG) printError("ucryptoDigestInit", mech, rv); + return 0L; } - break; - case com_oracle_security_ucrypto_NativeDigest_MECH_MD5: - pContext = (MD5_CTX *) malloc(sizeof(MD5_CTX)); - if (pContext != NULL) { - (*ftab->md5Init)((MD5_CTX *)pContext); - } - break; - case com_oracle_security_ucrypto_NativeDigest_MECH_SHA256: - pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX)); - if (pContext != NULL) { - (*ftab->sha2Init)(SHA256, (SHA2_CTX *)pContext); - } - break; - case com_oracle_security_ucrypto_NativeDigest_MECH_SHA384: - pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX)); - if (pContext != NULL) { - (*ftab->sha2Init)(SHA384, (SHA2_CTX *)pContext); - } - break; - case com_oracle_security_ucrypto_NativeDigest_MECH_SHA512: - pContext = (SHA2_CTX *) malloc(sizeof(SHA2_CTX)); - if (pContext != NULL) { - (*ftab->sha2Init)(SHA512, (SHA2_CTX *)pContext); - } - break; - default: - if (DEBUG) printf("ERROR: Unsupported mech %i\n", mech); } - return (jlong) pContext; + return (jlong) context; } jint JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate (jint mech, jlong pContext, int notUsed, unsigned char* in, jint ofs, jint len) { - if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { - (*ftab->sha1Update)((SHA1_CTX*)pContext, (unsigned char*)(in+ofs), len); - } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { - (*ftab->md5Update)((MD5_CTX*)pContext, (unsigned char*)(in+ofs), len); - } else { // SHA-2 family - (*ftab->sha2Update)((SHA2_CTX*)pContext, (unsigned char*)(in+ofs), len); + crypto_ctx_t *context; + jint rv = 0; + + context = (crypto_ctx_t *) pContext; + rv = (*ftab->ucryptoDigestUpdate)(context, (const unsigned char*)(in + ofs), + (size_t) len); + + if (rv) { + freeContext(context); + if (DEBUG) printError("ucryptoDigestUpdate", mech, rv); } - return 0; + + return -rv; // use negative value to indicate error } -// Do digest and free the context immediately jint JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest (jint mech, jlong pContext, int notUsed, unsigned char* out, jint ofs, jint digestLen) { + crypto_ctx_t *context; + jint rv = 0; + size_t digest_len = digestLen; - if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { - (*ftab->sha1Final)((unsigned char*)(out + ofs), (SHA1_CTX *)pContext); - free((SHA1_CTX *)pContext); - } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { - (*ftab->md5Final)((unsigned char*)(out + ofs), (MD5_CTX *)pContext); - free((MD5_CTX *)pContext); - } else { // SHA-2 family - (*ftab->sha2Final)((unsigned char*)(out + ofs), (SHA2_CTX *)pContext); - free((SHA2_CTX *)pContext); + context = (crypto_ctx_t *) pContext; + rv = (*ftab->ucryptoDigestFinal)(context, (unsigned char*)(out + ofs), + &digest_len); + if (rv) { + freeContext(context); + if (DEBUG) printError("ucryptoDigestFinal", mech, rv); } - return 0; -} -jlong JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone - (jint mech, jlong pContext) { - void *copy = NULL; - size_t len = 0; - - if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { - len = sizeof(SHA1_CTX); - } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { - len = sizeof(MD5_CTX); - } else { // SHA-2 family - len = sizeof(SHA2_CTX); - } - copy = (void*) malloc(len); - if (copy != NULL) { - bcopy((void *)pContext, copy, len); - } - return (jlong) copy; + return -rv; // use negative value to indicate error } void JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeFree (jint mech, jlong pContext) { - if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_SHA1) { - free((SHA1_CTX*) pContext); - } else if (mech == com_oracle_security_ucrypto_NativeDigest_MECH_MD5) { - free((MD5_CTX*) pContext); - } else { // SHA-2 family - free((SHA2_CTX*) pContext); - } + crypto_ctx_t *context; + + context = (crypto_ctx_t *) pContext; + freeContext(context); } // AES @@ -395,7 +380,7 @@ jlong JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeInit rv = CipherInit(context, encrypt, (ucrypto_mech_t) mech, bufKey, keyLen, bufIv, ivLen, tagLen, bufAad, aadLen); if (rv) { - free(context); + freeContext(context); return 0L; } } @@ -417,8 +402,7 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeUpdate context = (crypto_ctx_t *) pContext; rv = CipherUpdate(context, encrypt, (unsigned char*)bufIn, inOfs, inLen, (unsigned char*)bufOut, outOfs, &outLen); if (rv) { - free(context); - context = 0; + freeContext(context); return -rv; // use negative value to indicate error! } @@ -443,7 +427,7 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeFinal outLen = 0; } rv = CipherFinal(context, encrypt, bufOut, outOfs, &outLen); - free(context); + freeContext(context); if (rv) { return -rv; // use negative value to indicate error! } @@ -451,8 +435,6 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeCipher_nativeFinal return outLen; } - - /* * Class: com_oracle_security_ucrypto_NativeDigest * Method: nativeInit @@ -475,13 +457,15 @@ JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeInit JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdate (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jIn, jint jOfs, jint jLen) { unsigned char *bufIn; + jint rv = 0; + bufIn = (unsigned char *) getBytes(env, jIn, jOfs, jLen); if (!(*env)->ExceptionCheck(env)) { - JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen); + rv = JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen); free(bufIn); } - return 0; + return rv; } /* @@ -492,6 +476,7 @@ JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeUpdat JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeDigest (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jOut, jint jOutOfs, jint digestLen) { unsigned char *bufOut; + jint rv = 0; bufOut = (unsigned char *) malloc(digestLen); if (bufOut == NULL) { @@ -499,21 +484,12 @@ JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeDiges return 0; } - JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen); - - (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut); + rv = JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen); + if (rv == 0) { + (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut); + } free(bufOut); - return 0; -} - -/* - * Class: com_oracle_security_ucrypto_NativeDigest - * Method: nativeClone - * Signature: (IJ)J - */ -JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigest_nativeClone - (JNIEnv *env, jclass jcls, jint mech, jlong pContext) { - return JavaCritical_com_oracle_security_ucrypto_NativeDigest_nativeClone(mech, pContext); + return rv; } /* @@ -582,7 +558,7 @@ JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeInit cleanup: if ((result == 0L) && (context != NULL)) { - free(context); + freeContext(context); } if (bufKey != NULL) { (*env)->ReleaseByteArrayElements(env, jKey, (jbyte *)bufKey, 0); @@ -626,7 +602,7 @@ JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeUpdat rv = CipherUpdate(context, encrypt, bufIn, 0, inLen, bufOut, 0, &outLen); if (rv) { - free(context); + freeContext(context); free(bufIn); free(bufOut); return -rv; @@ -683,6 +659,7 @@ JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeCipher_nativeFinal return rc; } + /* * Class: com_oracle_security_ucrypto_NativeKey * Method: nativeFree @@ -984,9 +961,9 @@ jlong JavaCritical_com_oracle_security_ucrypto_NativeKey_00024RSAPublic_nativeIn } if (DEBUG) { - printf("RSAPublicKey Init: keyValue=%ld, keyLen=2\n", pKey); - printBytes("RSA PublicKey mod: ", (unsigned char*) mod, modLen); - printBytes("RSA PublicKey pubExp: ", (unsigned char*) pub, pubLen); + printf("RSAPublicKey.nativeInit: keyValue=%ld, keyLen=2\n", pKey); + printBytes("\tmod: ", (unsigned char*) mod, modLen); + printBytes("\tpubExp: ", (unsigned char*) pub, pubLen); } pKey[0].oa_type = SUN_CKA_MODULUS; @@ -1062,7 +1039,7 @@ SignatureInit(crypto_ctx_t *context, jint mechVal, jboolean sign, if (DEBUG) { printf("SignatureInit: context=%ld, mech=%d, sign=%d, keyValue=%ld, keyLength=%d\n", context, mech, sign, pKey, keyLength); - printf("SignatureInit, ret => 0x%x\n", rv); + printError("SignatureInit", mech, rv); } return rv; } @@ -1083,7 +1060,7 @@ jlong JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeInit pKey = (uchar_t *) jKey; rv = SignatureInit(context, mech, sign, pKey, (size_t)keyLength); if (rv) { - free(context); + freeContext(context); return 0L; } } @@ -1105,7 +1082,7 @@ JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeRSASignature_nati pKey = (uchar_t *) jKey; rv = SignatureInit(context, mech, sign, pKey, (size_t)keyLength); if (rv) { - free(context); + freeContext(context); throwUCExceptionUsingRV(env, rv); return 0L; } @@ -1125,7 +1102,7 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__J context = (crypto_ctx_t *) pCtxt; if (DEBUG) { - printf("Signature update: context=%ld, sign=%d, jIn=%ld, jInOfs=%d, jInLen=%d\n", + printf("NativeRSASignature.nativeUpdate: context=%ld, sign=%d, jIn=%ld, jInOfs=%d, jInLen=%d\n", context, sign, jIn, jInOfs, jInLen); } if (sign) { @@ -1133,9 +1110,9 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeUpdate__J } else { rv = (*ftab->ucryptoVerifyUpdate)(context, (uchar_t *) (jIn + jInOfs), (size_t) jInLen); } - if (DEBUG) printf("Signature update, ret => 0x%x\n", rv); if (rv) { - free(context); + freeContext(context); + if (DEBUG) printError("NativeRSASignature.nativeUpdate", -1, rv); return -rv; // use negative value to indicate error! } @@ -1194,9 +1171,9 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal context = (crypto_ctx_t *) pCtxt; if (DEBUG) { - printf("Signature final: context=%ld, sign=%d, bufSig=%ld, sigOfs=%d, sigLen=%d\n", + printf("NativeRSASignature.nativeFinal: context=%ld, sign=%d, bufSig=%ld, sigOfs=%d, sigLen=%d\n", context, sign, bufSig, sigOfs, jSigLen); - printBytes("Before Final: SigBytes ", (unsigned char*) (bufSig + sigOfs), jSigLen); + printBytes("Before: SigBytes ", (unsigned char*) (bufSig + sigOfs), jSigLen); } if (sign) { rv = (*ftab->ucryptoSignFinal)(context, (uchar_t *) (bufSig + sigOfs), &sigLength); @@ -1204,18 +1181,17 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSASignature_nativeFinal rv = (*ftab->ucryptoVerifyFinal)(context, (uchar_t *) (bufSig + sigOfs), &sigLength); } - if (DEBUG) { - printf("Signature nativeFinal, ret => 0x%x\n", rv); - if (sigLength != jSigLen) { - printf("SIG actual output len=%d\n", sigLength); - } - if (sign) { - printBytes("After nativeFinal: ", (unsigned char*) (bufSig + sigOfs), jSigLen); - } - } - - free(context); + freeContext(context); if (rv) { + if (DEBUG) { + printError("NativeRSASignature.nativeFinal", -1, rv); + if (sigLength != jSigLen) { + printf("NativeRSASignature.nativeFinal out sig len=%d\n", sigLength); + } + if (sign) { + printBytes("After: SigBytes ", (unsigned char*) (bufSig + sigOfs), jSigLen); + } + } return -rv; } else return 0; } @@ -1273,10 +1249,10 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic pKey = (uchar_t *) keyValue; if (DEBUG) { - printf("Cipher nativeAtomic: mech=%d, encrypt=%d, pKey=%ld, keyLength=%d\n", + printf("NativeRSACipher.nativeAtomic: mech=%d, encrypt=%d, pKey=%ld, keyLength=%d\n", mech, encrypt, pKey, keyLength); - printBytes("Before nativeAtomic: in: ", (unsigned char*) bufIn, jInLen); - printBytes("Before nativeAtomic: out: ", (unsigned char*) (bufOut + jOutOfs), jOutLen); + printBytes("Before: in = ", (unsigned char*) bufIn, jInLen); + printBytes("Before: out = ", (unsigned char*) (bufOut + jOutOfs), jOutLen); } if (encrypt) { @@ -1289,11 +1265,11 @@ jint JavaCritical_com_oracle_security_ucrypto_NativeRSACipher_nativeAtomic (uchar_t *)(bufOut + jOutOfs), &outLength); } if (DEBUG) { - printf("Cipher nativeAtomic, ret => 0x%x\n", rv); + printError("NativeRSACipher.nativeAtomic", mech, rv); if (outLength != jOutLen) { - printf("CIP actual output len=%d\n", outLength); + printf("NativeRSACipher.nativeAtomic out len=%d\n", outLength); } - printBytes("After nativeAtomic: ", (unsigned char*) (bufOut + jOutOfs), outLength); + printBytes("After: ", (unsigned char*) (bufOut + jOutOfs), outLength); } if (rv) { diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.h b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.h index 9ad3891d0d0..a3ea195387e 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.h +++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCrypto.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,18 +29,18 @@ extern "C" { #endif -#undef com_oracle_security_ucrypto_NativeDigest_MECH_MD5 -#define com_oracle_security_ucrypto_NativeDigest_MECH_MD5 1L -#undef com_oracle_security_ucrypto_NativeDigest_MECH_SHA1 -#define com_oracle_security_ucrypto_NativeDigest_MECH_SHA1 2L -#undef com_oracle_security_ucrypto_NativeDigest_MECH_SHA256 -#define com_oracle_security_ucrypto_NativeDigest_MECH_SHA256 3L -#undef com_oracle_security_ucrypto_NativeDigest_MECH_SHA224 -#define com_oracle_security_ucrypto_NativeDigest_MECH_SHA224 4L -#undef com_oracle_security_ucrypto_NativeDigest_MECH_SHA384 -#define com_oracle_security_ucrypto_NativeDigest_MECH_SHA384 5L -#undef com_oracle_security_ucrypto_NativeDigest_MECH_SHA512 -#define com_oracle_security_ucrypto_NativeDigest_MECH_SHA512 6L +#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5 +#define com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5 1L +#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1 +#define com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1 2L +#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA256 +#define com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA256 3L +#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA224 +#define com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA224 4L +#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA384 +#define com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA384 5L +#undef com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA512 +#define com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA512 6L #define DEBUG 0 diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCryptoMD.c b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCryptoMD.c new file mode 100644 index 00000000000..df60ce3613a --- /dev/null +++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeCryptoMD.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 2016, 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. + */ + +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include <jni.h> +#include "jni_util.h" +#include <libsoftcrypto.h> +#include "nativeCrypto.h" +#include "nativeFunc.h" + + +extern void throwOutOfMemoryError(JNIEnv *env, const char *msg); +extern jbyte* getBytes(JNIEnv *env, jbyteArray bytes, int offset, int len); + +/////////////////////////////////////////////////////// +// SPECIAL ENTRIES FOR JVM JNI-BYPASSING OPTIMIZATION +//////////////////////////////////////////////////////// +jlong JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeInit(jint mech) { + void *pContext = NULL; + + switch (mech) { + case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1: + pContext = malloc(sizeof(SHA1_CTX)); + if (pContext != NULL) { + (*ftab->sha1Init)((SHA1_CTX *)pContext); + } + break; + case com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5: + pContext = malloc(sizeof(MD5_CTX)); + if (pContext != NULL) { + (*ftab->md5Init)((MD5_CTX *)pContext); + } + break; + case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA256: + pContext = malloc(sizeof(SHA2_CTX)); + if (pContext != NULL) { + (*ftab->sha2Init)(SHA256, (SHA2_CTX *)pContext); + } + break; + case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA384: + pContext = malloc(sizeof(SHA2_CTX)); + if (pContext != NULL) { + (*ftab->sha2Init)(SHA384, (SHA2_CTX *)pContext); + } + break; + case com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA512: + pContext = malloc(sizeof(SHA2_CTX)); + if (pContext != NULL) { + (*ftab->sha2Init)(SHA512, (SHA2_CTX *)pContext); + } + break; + default: + if (DEBUG) printf("ERROR: Unsupported mech %i\n", mech); + } + return (jlong) pContext; +} + +jint JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate + (jint mech, jlong pContext, int notUsed, unsigned char* in, jint ofs, jint len) { + if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) { + (*ftab->sha1Update)((SHA1_CTX*)pContext, (unsigned char*)(in+ofs), len); + } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) { + (*ftab->md5Update)((MD5_CTX*)pContext, (unsigned char*)(in+ofs), len); + } else { // SHA-2 family + (*ftab->sha2Update)((SHA2_CTX*)pContext, (unsigned char*)(in+ofs), len); + } + return 0; +} + +// Do digest and free the context immediately +jint JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest + (jint mech, jlong pContext, int notUsed, unsigned char* out, jint ofs, jint digestLen) { + + if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) { + (*ftab->sha1Final)((unsigned char*)(out + ofs), (SHA1_CTX *)pContext); + free((SHA1_CTX *)pContext); + } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) { + (*ftab->md5Final)((unsigned char*)(out + ofs), (MD5_CTX *)pContext); + free((MD5_CTX *)pContext); + } else { // SHA-2 family + (*ftab->sha2Final)((unsigned char*)(out + ofs), (SHA2_CTX *)pContext); + free((SHA2_CTX *)pContext); + } + return 0; +} + +jlong JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeClone + (jint mech, jlong pContext) { + void *copy = NULL; + size_t len = 0; + + if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) { + len = sizeof(SHA1_CTX); + } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) { + len = sizeof(MD5_CTX); + } else { // SHA-2 family + len = sizeof(SHA2_CTX); + } + copy = malloc(len); + if (copy != NULL) { + bcopy((void *)pContext, copy, len); + } + return (jlong) copy; +} + +void JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeFree + (jint mech, jlong pContext) { + if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_SHA1) { + free((SHA1_CTX*) pContext); + } else if (mech == com_oracle_security_ucrypto_NativeDigestMD_MECH_MD5) { + free((MD5_CTX*) pContext); + } else { // SHA-2 family + free((SHA2_CTX*) pContext); + } +} + + +/* + * Class: com_oracle_security_ucrypto_NativeDigestMD + * Method: nativeInit + * Signature: (I)J + */ +JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeInit + (JNIEnv *env, jclass jcls, jint mech) { + jlong result = JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeInit(mech); + if (result == NULL) { + throwOutOfMemoryError(env, NULL); + } + return result; +} + +/* + * Class: com_oracle_security_ucrypto_NativeDigestMD + * Method: nativeUpdate + * Signature: (IJ[BII)I + */ +JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate + (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jIn, jint jOfs, jint jLen) { + unsigned char *bufIn; + + bufIn = (unsigned char *) getBytes(env, jIn, jOfs, jLen); + if (!(*env)->ExceptionCheck(env)) { + JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeUpdate(mech, pContext, jLen, bufIn, 0, jLen); + free(bufIn); + } + return 0; +} + +/* + * Class: com_oracle_security_ucrypto_NativeDigestMD + * Method: nativeDigest + * Signature: (IJ[BII)I + */ +JNIEXPORT jint JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest + (JNIEnv *env, jclass jcls, jint mech, jlong pContext, jbyteArray jOut, jint jOutOfs, jint digestLen) { + unsigned char *bufOut; + + bufOut = (unsigned char *) malloc(digestLen); + if (bufOut == NULL) { + throwOutOfMemoryError(env, NULL); + return 0; + } + + JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeDigest(mech, pContext, digestLen, bufOut, 0, digestLen); + + (*env)->SetByteArrayRegion(env, jOut, jOutOfs, digestLen, (jbyte *) bufOut); + free(bufOut); + return 0; +} + +/* + * Class: com_oracle_security_ucrypto_NativeDigestMD + * Method: nativeClone + * Signature: (IJ)J + */ +JNIEXPORT jlong JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeClone + (JNIEnv *env, jclass jcls, jint mech, jlong pContext) { + return JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeClone(mech, pContext); +} + +/* + * Class: com_oracle_security_ucrypto_NativeDigestMD + * Method: nativeFree + * Signature: (IJ)V + */ +JNIEXPORT void JNICALL Java_com_oracle_security_ucrypto_NativeDigestMD_nativeFree + (JNIEnv *env, jclass jcls, jint mech, jlong pContext) { + JavaCritical_com_oracle_security_ucrypto_NativeDigestMD_nativeFree(mech, pContext); +} + diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.c b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.c index c1ee9027e92..2756977d09c 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.c +++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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,21 +42,33 @@ static const char SHA2_UPDATE[] = "SHA2Update"; static const char SHA2_FINAL[] = "SHA2Final"; static const char UCRYPTO_VERSION[] = "ucrypto_version"; static const char UCRYPTO_GET_MECHLIST[] = "ucrypto_get_mechlist"; + static const char UCRYPTO_ENCRYPT_INIT[] = "ucrypto_encrypt_init"; static const char UCRYPTO_ENCRYPT_UPDATE[] = "ucrypto_encrypt_update"; static const char UCRYPTO_ENCRYPT_FINAL[] = "ucrypto_encrypt_final"; static const char UCRYPTO_ENCRYPT[] = "ucrypto_encrypt"; + static const char UCRYPTO_DECRYPT_INIT[] = "ucrypto_decrypt_init"; static const char UCRYPTO_DECRYPT_UPDATE[] = "ucrypto_decrypt_update"; static const char UCRYPTO_DECRYPT_FINAL[] = "ucrypto_decrypt_final"; static const char UCRYPTO_DECRYPT[] = "ucrypto_decrypt"; + static const char UCRYPTO_SIGN_INIT[] = "ucrypto_sign_init"; static const char UCRYPTO_SIGN_UPDATE[] = "ucrypto_sign_update"; static const char UCRYPTO_SIGN_FINAL[] = "ucrypto_sign_final"; + static const char UCRYPTO_VERIFY_INIT[] = "ucrypto_verify_init"; static const char UCRYPTO_VERIFY_UPDATE[] = "ucrypto_verify_update"; static const char UCRYPTO_VERIFY_FINAL[] = "ucrypto_verify_final"; +static const char UCRYPTO_DIGEST_INIT[] = "ucrypto_digest_init"; +static const char UCRYPTO_DIGEST_UPDATE[] = "ucrypto_digest_update"; +static const char UCRYPTO_DIGEST_FINAL[] = "ucrypto_digest_final"; + +static const char UCRYPTO_FREE_CONTEXT[] = "ucrypto_free_context"; + +static const char UCRYPTO_STRERROR[] = "ucrypto_strerror"; + /** * Initialize native T4 crypto function pointers */ @@ -73,28 +85,6 @@ jboolean* loadNative() { return NULL; } - lib = dlopen("libmd.so", RTLD_NOW); - if (lib != NULL) { - ftab->md5Init = (MD5INIT_FN_PTR) dlsym(lib, MD5_INIT); - ftab->md5Update = (MD5UPDATE_FN_PTR) dlsym(lib, MD5_UPDATE); - ftab->md5Final = (MD5FINAL_FN_PTR) dlsym(lib, MD5_FINAL); - ftab->sha1Init = (SHA1INIT_FN_PTR) dlsym(lib, SHA1_INIT); - ftab->sha1Update = (SHA1UPDATE_FN_PTR) dlsym(lib, SHA1_UPDATE); - ftab->sha1Final = (SHA1FINAL_FN_PTR) dlsym(lib, SHA1_FINAL); - ftab->sha2Init = (SHA2INIT_FN_PTR) dlsym(lib, SHA2_INIT); - ftab->sha2Update = (SHA2UPDATE_FN_PTR) dlsym(lib, SHA2_UPDATE); - ftab->sha2Final = (SHA2FINAL_FN_PTR) dlsym(lib, SHA2_FINAL); - if (ftab->md5Init != NULL && ftab->md5Update != NULL && - ftab->md5Final != NULL && ftab->sha1Init != NULL && - ftab->sha1Update != NULL && ftab->sha1Final != NULL && - ftab->sha2Init != NULL && ftab->sha2Update != NULL && - ftab->sha2Final != NULL) { - buf[0] = JNI_TRUE; - } else { - dlclose(lib); - } - } - lib = dlopen("libsoftcrypto.so", RTLD_NOW); if (lib != NULL) { // These APIs aren't available for v0 lib on Solaris 10 @@ -102,7 +92,6 @@ jboolean* loadNative() { dlsym(lib, UCRYPTO_VERSION); ftab->ucryptoGetMechList = (UCRYPTO_GET_MECHLIST_FN_PTR) dlsym(lib, UCRYPTO_GET_MECHLIST); - //?? ftab->ucryptoSignInit = (UCRYPTO_SIGN_INIT_FN_PTR) dlsym(lib, UCRYPTO_SIGN_INIT); ftab->ucryptoSignUpdate = (UCRYPTO_SIGN_UPDATE_FN_PTR) @@ -116,6 +105,21 @@ jboolean* loadNative() { ftab->ucryptoVerifyFinal = (UCRYPTO_VERIFY_FINAL_FN_PTR) dlsym(lib, UCRYPTO_VERIFY_FINAL); + // These APS are added starting S12 + ftab->ucryptoDigestInit = (UCRYPTO_DIGEST_INIT_FN_PTR) + dlsym(lib, UCRYPTO_DIGEST_INIT); + ftab->ucryptoDigestUpdate = (UCRYPTO_DIGEST_UPDATE_FN_PTR) + dlsym(lib, UCRYPTO_DIGEST_UPDATE); + ftab->ucryptoDigestFinal = (UCRYPTO_DIGEST_FINAL_FN_PTR) + dlsym(lib, UCRYPTO_DIGEST_FINAL); + + ftab->ucryptoFreeContext = (UCRYPTO_FREE_CONTEXT_FN_PTR) + dlsym(lib, UCRYPTO_FREE_CONTEXT); + + ftab->ucryptoStrerror = (UCRYPTO_STRERROR_FN_PTR) + dlsym(lib, UCRYPTO_STRERROR); + + // These should be avilable for all libsoftcrypto libs ftab->ucryptoEncryptInit = (UCRYPTO_ENCRYPT_INIT_FN_PTR) dlsym(lib, UCRYPTO_ENCRYPT_INIT); @@ -147,6 +151,34 @@ jboolean* loadNative() { } else { dlclose(lib); } + + // proceed with libmd when libucrypto does not support digest operations + if (ftab->ucryptoDigestInit == NULL || + ftab->ucryptoDigestUpdate == NULL || + ftab->ucryptoDigestFinal == NULL) { + + lib = dlopen("libmd.so", RTLD_NOW); + if (lib != NULL) { + ftab->md5Init = (MD5INIT_FN_PTR) dlsym(lib, MD5_INIT); + ftab->md5Update = (MD5UPDATE_FN_PTR) dlsym(lib, MD5_UPDATE); + ftab->md5Final = (MD5FINAL_FN_PTR) dlsym(lib, MD5_FINAL); + ftab->sha1Init = (SHA1INIT_FN_PTR) dlsym(lib, SHA1_INIT); + ftab->sha1Update = (SHA1UPDATE_FN_PTR) dlsym(lib, SHA1_UPDATE); + ftab->sha1Final = (SHA1FINAL_FN_PTR) dlsym(lib, SHA1_FINAL); + ftab->sha2Init = (SHA2INIT_FN_PTR) dlsym(lib, SHA2_INIT); + ftab->sha2Update = (SHA2UPDATE_FN_PTR) dlsym(lib, SHA2_UPDATE); + ftab->sha2Final = (SHA2FINAL_FN_PTR) dlsym(lib, SHA2_FINAL); + if (ftab->md5Init != NULL && ftab->md5Update != NULL && + ftab->md5Final != NULL && ftab->sha1Init != NULL && + ftab->sha1Update != NULL && ftab->sha1Final != NULL && + ftab->sha2Init != NULL && ftab->sha2Update != NULL && + ftab->sha2Final != NULL) { + buf[0] = JNI_TRUE; + } else { + dlclose(lib); + } + } + } } return buf; diff --git a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.h b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.h index d45272f9bab..5f3a9ba87e3 100644 --- a/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.h +++ b/jdk/src/jdk.crypto.ucrypto/solaris/native/libj2ucrypto/nativeFunc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,15 +69,12 @@ typedef int (*UCRYPTO_ENCRYPT_INIT_FN_PTR) (crypto_ctx_t *context, ucrypto_mech_t mech_type, uchar_t *key_str, size_t key_len, void *iv, size_t iv_len); - typedef int (*UCRYPTO_ENCRYPT_UPDATE_FN_PTR) (crypto_ctx_t *context, uchar_t *in, size_t in_len, uchar_t *out, size_t *out_len); - typedef int (*UCRYPTO_ENCRYPT_FINAL_FN_PTR) (crypto_ctx_t *context, uchar_t *out, size_t *out_len); - typedef int (*UCRYPTO_ENCRYPT_FN_PTR) (ucrypto_mech_t mech_type, uchar_t *key_str, size_t key_len, void *iv, size_t iv_len, uchar_t *in, @@ -87,15 +84,12 @@ typedef int (*UCRYPTO_DECRYPT_INIT_FN_PTR) (crypto_ctx_t *context, ucrypto_mech_t mech_type, uchar_t *key_str, size_t key_len, void *iv, size_t iv_len); - typedef int (*UCRYPTO_DECRYPT_UPDATE_FN_PTR) (crypto_ctx_t *context, uchar_t *in, size_t in_len, uchar_t *out, size_t *out_len); - typedef int (*UCRYPTO_DECRYPT_FINAL_FN_PTR) (crypto_ctx_t *context, uchar_t *out, size_t *out_len); - typedef int (*UCRYPTO_DECRYPT_FN_PTR) (ucrypto_mech_t mech_type, uchar_t *key_str, size_t key_len, void *iv, size_t iv_len, uchar_t *in, @@ -105,10 +99,8 @@ typedef int (*UCRYPTO_SIGN_INIT_FN_PTR) (crypto_ctx_t *context, ucrypto_mech_t mech_type, uchar_t *key_str, size_t key_len, void *iv, size_t iv_len); - typedef int (*UCRYPTO_SIGN_UPDATE_FN_PTR) (crypto_ctx_t *context, uchar_t *data_str, size_t data_len); - typedef int (*UCRYPTO_SIGN_FINAL_FN_PTR) (crypto_ctx_t *context, uchar_t *sig_str, size_t *sig_len); @@ -116,13 +108,24 @@ typedef int (*UCRYPTO_VERIFY_INIT_FN_PTR) (crypto_ctx_t *context, ucrypto_mech_t mech_type, uchar_t *key_str, size_t key_len, void *iv, size_t iv_len); - typedef int (*UCRYPTO_VERIFY_UPDATE_FN_PTR) (crypto_ctx_t *context, uchar_t *data_str, size_t data_len); - typedef int (*UCRYPTO_VERIFY_FINAL_FN_PTR) (crypto_ctx_t *context, uchar_t *sig_str, size_t *sig_len); +typedef int (*UCRYPTO_DIGEST_INIT_FN_PTR) + (crypto_ctx_t *context, ucrypto_mech_t mech_type, + void *param, size_t param_len); +typedef int (*UCRYPTO_DIGEST_UPDATE_FN_PTR) + (crypto_ctx_t *context, const uchar_t *data, size_t data_len); +typedef int (*UCRYPTO_DIGEST_FINAL_FN_PTR) + (crypto_ctx_t *context, uchar_t *digest, size_t *digest_len); + +typedef void (*UCRYPTO_FREE_CONTEXT_FN_PTR) + (crypto_ctx_t *context); + +typedef char* (*UCRYPTO_STRERROR_FN_PTR)(int rv); + /* dynamically resolved functions from libmd, and libsoftcrypto @@ -153,6 +156,11 @@ typedef struct T4CRYPTO_FUNCTION_TABLE { UCRYPTO_VERIFY_INIT_FN_PTR ucryptoVerifyInit; UCRYPTO_VERIFY_UPDATE_FN_PTR ucryptoVerifyUpdate; UCRYPTO_VERIFY_FINAL_FN_PTR ucryptoVerifyFinal; + UCRYPTO_DIGEST_INIT_FN_PTR ucryptoDigestInit; + UCRYPTO_DIGEST_UPDATE_FN_PTR ucryptoDigestUpdate; + UCRYPTO_DIGEST_FINAL_FN_PTR ucryptoDigestFinal; + UCRYPTO_FREE_CONTEXT_FN_PTR ucryptoFreeContext; + UCRYPTO_STRERROR_FN_PTR ucryptoStrerror; } T4CRYPTO_FUNCTION_TABLE; typedef T4CRYPTO_FUNCTION_TABLE *T4CRYPTO_FUNCTION_TABLE_PTR; diff --git a/jdk/src/jdk.jcmd/share/classes/jdk/internal/vm/agent/spi/ToolProvider.java b/jdk/src/jdk.jcmd/share/classes/jdk/internal/vm/agent/spi/ToolProvider.java deleted file mode 100644 index 55be308348a..00000000000 --- a/jdk/src/jdk.jcmd/share/classes/jdk/internal/vm/agent/spi/ToolProvider.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2016, 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.agent.spi; - -/** - * Service interface for jdk.hotspot.agent to provide the tools that - * jstack, jmap, jinfo will invoke, if present. - */ -public interface ToolProvider { - /** - * Returns the name of the tool provider - */ - String getName(); - - /** - * Invoke the tool provider with the given arguments - */ - void run(String... arguments); -} diff --git a/jdk/src/jdk.jcmd/share/classes/module-info.java b/jdk/src/jdk.jcmd/share/classes/module-info.java index 4b8dbce1304..c78803b774c 100644 --- a/jdk/src/jdk.jcmd/share/classes/module-info.java +++ b/jdk/src/jdk.jcmd/share/classes/module-info.java @@ -26,9 +26,4 @@ module jdk.jcmd { requires jdk.attach; requires jdk.jvmstat; - - exports jdk.internal.vm.agent.spi to jdk.hotspot.agent; - - uses jdk.internal.vm.agent.spi.ToolProvider; } - diff --git a/jdk/src/jdk.jcmd/share/classes/sun/tools/common/ProcessArgumentMatcher.java b/jdk/src/jdk.jcmd/share/classes/sun/tools/common/ProcessArgumentMatcher.java new file mode 100644 index 00000000000..e08b11d6cb5 --- /dev/null +++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/common/ProcessArgumentMatcher.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2016, 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.tools.common; + +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import com.sun.tools.attach.VirtualMachine; +import com.sun.tools.attach.VirtualMachineDescriptor; + +import sun.jvmstat.monitor.MonitorException; +import sun.jvmstat.monitor.MonitoredHost; +import sun.jvmstat.monitor.MonitoredVm; +import sun.jvmstat.monitor.MonitoredVmUtil; +import sun.jvmstat.monitor.VmIdentifier; + +/** + * Class for finding process matching a process argument, + * excluding tool it self and returning a list containing + * the process identifiers. + */ +public class ProcessArgumentMatcher { + private String excludeCls; + private String matchClass = null; + private String singlePid = null; + private boolean matchAll = false; + + public ProcessArgumentMatcher(String pidArg, Class<?> excludeClass) { + excludeCls = excludeClass.getName(); + if (pidArg == null || pidArg.isEmpty()) { + throw new IllegalArgumentException("Pid string is invalid"); + } + if (pidArg.charAt(0) == '-') { + throw new IllegalArgumentException("Unrecognized " + pidArg); + } + try { + long pid = Long.parseLong(pidArg); + if (pid == 0) { + matchAll = true; + } else { + singlePid = String.valueOf(pid); + } + } catch (NumberFormatException nfe) { + matchClass = pidArg; + } + } + + private boolean check(VirtualMachineDescriptor vmd) { + String mainClass = null; + try { + VmIdentifier vmId = new VmIdentifier(vmd.id()); + MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId); + MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, -1); + mainClass = MonitoredVmUtil.mainClass(monitoredVm, true); + monitoredHost.detach(monitoredVm); + } catch (NullPointerException npe) { + // There is a potential race, where a running java app is being + // queried, unfortunately the java app has shutdown after this + // method is started but before getMonitoredVM is called. + // If this is the case, then the /tmp/hsperfdata_xxx/pid file + // will have disappeared and we will get a NullPointerException. + // Handle this gracefully.... + return false; + } catch (MonitorException | URISyntaxException e) { + if (e.getMessage() != null) { + System.err.println(e.getMessage()); + } else { + Throwable cause = e.getCause(); + if ((cause != null) && (cause.getMessage() != null)) { + System.err.println(cause.getMessage()); + } else { + e.printStackTrace(); + } + } + return false; + } + + if (mainClass.equals(excludeCls)) { + return false; + } + + if (matchAll || mainClass.indexOf(matchClass) != -1) { + return true; + } + + return false; + } + + public Collection<String> getPids() { + Collection<String> pids = new ArrayList<>(); + if (singlePid != null) { + pids.add(singlePid); + return pids; + } + List<VirtualMachineDescriptor> vmds = VirtualMachine.list(); + for (VirtualMachineDescriptor vmd : vmds) { + if (check(vmd)) { + pids.add(vmd.id()); + } + } + return pids; + } +} diff --git a/jdk/src/jdk.jcmd/share/classes/sun/tools/jcmd/Arguments.java b/jdk/src/jdk.jcmd/share/classes/sun/tools/jcmd/Arguments.java index fbd4ca9aae4..80708f5aa37 100644 --- a/jdk/src/jdk.jcmd/share/classes/sun/tools/jcmd/Arguments.java +++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/jcmd/Arguments.java @@ -33,16 +33,14 @@ class Arguments { private boolean listProcesses = false; private boolean listCounters = false; private boolean showUsage = false; - private int pid = -1; private String command = null; - private String processSubstring; + private String processString = null; public boolean isListProcesses() { return listProcesses; } public boolean isListCounters() { return listCounters; } public boolean isShowUsage() { return showUsage; } - public int getPid() { return pid; } public String getCommand() { return command; } - public String getProcessSubstring() { return processSubstring; } + public String getProcessString() { return processString; } public Arguments(String[] args) { if (args.length == 0 || args[0].equals("-l")) { @@ -55,15 +53,7 @@ class Arguments { return; } - try { - pid = Integer.parseInt(args[0]); - } catch (NumberFormatException ex) { - // use as a partial class-name instead - if (args[0].charAt(0) != '-') { - // unless it starts with a '-' - processSubstring = args[0]; - } - } + processString = args[0]; StringBuilder sb = new StringBuilder(); for (int i = 1; i < args.length; i++) { diff --git a/jdk/src/jdk.jcmd/share/classes/sun/tools/jcmd/JCmd.java b/jdk/src/jdk.jcmd/share/classes/sun/tools/jcmd/JCmd.java index 0ff46323ec6..ab77547a077 100644 --- a/jdk/src/jdk.jcmd/share/classes/sun/tools/jcmd/JCmd.java +++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/jcmd/JCmd.java @@ -29,22 +29,22 @@ import java.io.InputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.List; -import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.net.URISyntaxException; import com.sun.tools.attach.AttachOperationFailedException; import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.VirtualMachineDescriptor; -import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; import sun.tools.attach.HotSpotVirtualMachine; +import sun.tools.common.ProcessArgumentMatcher; import sun.tools.jstat.JStatLogger; import sun.jvmstat.monitor.Monitor; import sun.jvmstat.monitor.MonitoredHost; import sun.jvmstat.monitor.MonitoredVm; -import sun.jvmstat.monitor.MonitoredVmUtil; import sun.jvmstat.monitor.MonitorException; import sun.jvmstat.monitor.VmIdentifier; @@ -73,52 +73,18 @@ public class JCmd { System.exit(0); } - List<String> pids = new ArrayList<String>(); - if (arg.getPid() == 0) { - // find all VMs - List<VirtualMachineDescriptor> vmds = VirtualMachine.list(); - for (VirtualMachineDescriptor vmd : vmds) { - if (!isJCmdProcess(vmd)) { - pids.add(vmd.id()); - } - } - } else if (arg.getProcessSubstring() != null) { - // use the partial class-name match - List<VirtualMachineDescriptor> vmds = VirtualMachine.list(); - for (VirtualMachineDescriptor vmd : vmds) { - if (isJCmdProcess(vmd)) { - continue; - } - try { - String mainClass = getMainClass(vmd); - if (mainClass != null - && mainClass.indexOf(arg.getProcessSubstring()) != -1) { - pids.add(vmd.id()); - } - } catch (MonitorException|URISyntaxException e) { - if (e.getMessage() != null) { - System.err.println(e.getMessage()); - } else { - Throwable cause = e.getCause(); - if ((cause != null) && (cause.getMessage() != null)) { - System.err.println(cause.getMessage()); - } else { - e.printStackTrace(); - } - } - } - } - if (pids.isEmpty()) { - System.err.println("Could not find any processes matching : '" - + arg.getProcessSubstring() + "'"); - System.exit(1); - } - } else if (arg.getPid() == -1) { + Collection<String> pids = Collections.emptyList(); + try { + ProcessArgumentMatcher ap = new ProcessArgumentMatcher(arg.getProcessString(), JCmd.class); + pids = ap.getPids(); + } catch (IllegalArgumentException iae) { System.err.println("Invalid pid specified"); System.exit(1); - } else { - // Use the found pid - pids.add(arg.getPid() + ""); + } + if (pids.isEmpty()) { + System.err.println("Could not find any processes matching : '" + + arg.getProcessString() + "'"); + System.exit(1); } boolean success = true; @@ -199,36 +165,6 @@ public class JCmd { } } - private static boolean isJCmdProcess(VirtualMachineDescriptor vmd) { - try { - String mainClass = getMainClass(vmd); - return mainClass != null && mainClass.equals(JCmd.class.getName()); - } catch (URISyntaxException|MonitorException ex) { - return false; - } - } - - private static String getMainClass(VirtualMachineDescriptor vmd) - throws URISyntaxException, MonitorException { - try { - String mainClass = null; - VmIdentifier vmId = new VmIdentifier(vmd.id()); - MonitoredHost monitoredHost = MonitoredHost.getMonitoredHost(vmId); - MonitoredVm monitoredVm = monitoredHost.getMonitoredVm(vmId, -1); - mainClass = MonitoredVmUtil.mainClass(monitoredVm, true); - monitoredHost.detach(monitoredVm); - return mainClass; - } catch(NullPointerException e) { - // There is a potential race, where a running java app is being - // queried, unfortunately the java app has shutdown after this - // method is started but before getMonitoredVM is called. - // If this is the case, then the /tmp/hsperfdata_xxx/pid file - // will have disappeared and we will get a NullPointerException. - // Handle this gracefully.... - return null; - } - } - /** * Class to compare two Monitor objects by name in ascending order. * (from jstat) diff --git a/jdk/src/jdk.jcmd/share/classes/sun/tools/jinfo/JInfo.java b/jdk/src/jdk.jcmd/share/classes/sun/tools/jinfo/JInfo.java index f19b6d159f0..ca774122a17 100644 --- a/jdk/src/jdk.jcmd/share/classes/sun/tools/jinfo/JInfo.java +++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/jinfo/JInfo.java @@ -25,15 +25,14 @@ package sun.tools.jinfo; -import java.util.Arrays; import java.io.IOException; import java.io.InputStream; +import java.util.Collection; import com.sun.tools.attach.VirtualMachine; import sun.tools.attach.HotSpotVirtualMachine; -import jdk.internal.vm.agent.spi.ToolProvider; -import jdk.internal.vm.agent.spi.ToolProviderFinder; +import sun.tools.common.ProcessArgumentMatcher; /* * This class is the main class for the JInfo utility. It parses its arguments @@ -41,155 +40,94 @@ import jdk.internal.vm.agent.spi.ToolProviderFinder; * or an SA tool. */ final public class JInfo { - private static final String SA_JINFO_TOOL_NAME = "jinfo"; - private boolean useSA = false; - private String[] args = null; - - private JInfo(String[] args) throws IllegalArgumentException { - if (args.length == 0) { - throw new IllegalArgumentException(); - } - - int argCopyIndex = 0; - // First determine if we should launch SA or not - if (args[0].equals("-F")) { - // delete the -F - argCopyIndex = 1; - useSA = true; - } else if (args[0].equals("-flags") - || args[0].equals("-sysprops")) - { - if (args.length == 2) { - if (!isPid(args[1])) { - // If args[1] doesn't parse to a number then - // it must be the SA debug server - // (otherwise it is the pid) - useSA = true; - } - } else if (args.length == 3) { - // arguments include an executable and a core file - useSA = true; - } else { - throw new IllegalArgumentException(); - } - } else if (!args[0].startsWith("-")) { - if (args.length == 2) { - // the only arguments are an executable and a core file - useSA = true; - } else if (args.length == 1) { - if (!isPid(args[0])) { - // The only argument is not a PID; it must be SA debug - // server - useSA = true; - } - } else { - throw new IllegalArgumentException(); - } - } else if (args[0].equals("-h") || args[0].equals("-help")) { - if (args.length > 1) { - throw new IllegalArgumentException(); - } - } else if (args[0].equals("-flag")) { - if (args.length == 3) { - if (!isPid(args[2])) { - throw new IllegalArgumentException(); - } - } else { - throw new IllegalArgumentException(); - } - } else { - throw new IllegalArgumentException(); - } - - this.args = Arrays.copyOfRange(args, argCopyIndex, args.length); - } - - @SuppressWarnings("fallthrough") - private void execute() throws Exception { - if (args[0].equals("-h") - || args[0].equals("-help")) { - usage(0); - } - - if (useSA) { - // SA only supports -flags or -sysprops - if (args[0].startsWith("-")) { - if (!(args[0].equals("-flags") || args[0].equals("-sysprops"))) { - usage(1); - } - } - - // invoke SA which does it's own argument parsing - runTool(); - - } else { - // Now we can parse arguments for the non-SA case - String pid = null; - - switch(args[0]) { - case "-flag": - if (args.length != 3) { - usage(1); - } - String option = args[1]; - pid = args[2]; - flag(pid, option); - break; - case "-flags": - if (args.length != 2) { - usage(1); - } - pid = args[1]; - flags(pid); - break; - case "-sysprops": - if (args.length != 2) { - usage(1); - } - pid = args[1]; - sysprops(pid); - break; - case "-help": - case "-h": - usage(0); - // Fall through - default: - if (args.length == 1) { - // no flags specified, we do -sysprops and -flags - pid = args[0]; - sysprops(pid); - System.out.println(); - flags(pid); - System.out.println(); - commandLine(pid); - } else { - usage(1); - } - } - } - } public static void main(String[] args) throws Exception { - JInfo jinfo = null; - try { - jinfo = new JInfo(args); - jinfo.execute(); - } catch (IllegalArgumentException e) { + if (args.length == 0) { + usage(1); // no arguments + } + checkForUnsupportedOptions(args); + + boolean doFlag = false; + boolean doFlags = false; + boolean doSysprops = false; + + // Parse the options (arguments starting with "-" ) + int optionCount = 0; + while (optionCount < args.length) { + String arg = args[optionCount]; + if (!arg.startsWith("-")) { + break; + } + + optionCount++; + + if (arg.equals("-help") || arg.equals("-h")) { + usage(0); + } + + if (arg.equals("-flag")) { + doFlag = true; + continue; + } + + if (arg.equals("-flags")) { + doFlags = true; + continue; + } + + if (arg.equals("-sysprops")) { + doSysprops = true; + continue; + } + } + + // Next we check the parameter count. -flag allows extra parameters + int paramCount = args.length - optionCount; + if ((doFlag && paramCount != 2) || ((!doFlag && paramCount != 1))) { usage(1); } - } - private static boolean isPid(String arg) { - return arg.matches("[0-9]+"); - } - - // Invoke SA tool with the given arguments - private void runTool() throws Exception { - ToolProvider tool = ToolProviderFinder.find(SA_JINFO_TOOL_NAME); - if (tool == null) { - usage(1); + if (!doFlag && !doFlags && !doSysprops) { + // Print flags and sysporps if no options given + ProcessArgumentMatcher ap = new ProcessArgumentMatcher(args[optionCount], JInfo.class); + Collection<String> pids = ap.getPids(); + for (String pid : pids) { + if (pids.size() > 1) { + System.out.println("Pid:" + pid); + } + sysprops(pid); + System.out.println(); + flags(pid); + System.out.println(); + commandLine(pid); + } + } + + if (doFlag) { + ProcessArgumentMatcher ap = new ProcessArgumentMatcher(args[optionCount+1], JInfo.class); + Collection<String> pids = ap.getPids(); + for (String pid : pids) { + if (pids.size() > 1) { + System.out.println("Pid:" + pid); + } + flag(pid, args[optionCount]); + } + } + else if (doFlags || doSysprops) { + ProcessArgumentMatcher ap = new ProcessArgumentMatcher(args[optionCount], JInfo.class); + Collection<String> pids = ap.getPids(); + for (String pid : pids) { + if (pids.size() > 1) { + System.out.println("Pid:" + pid); + } + if (doFlags) { + flags(pid); + } + else if (doSysprops) { + sysprops(pid); + } + } } - tool.run(args); } private static void flag(String pid, String option) throws IOException { @@ -274,46 +212,49 @@ final public class JInfo { vm.detach(); } + private static void checkForUnsupportedOptions(String[] args) { + // Check arguments for -F, and non-numeric value + // and warn the user that SA is not supported anymore + int maxCount = 1; + int paramCount = 0; - // print usage message - private static void usage(int exit) { - boolean usageSA = ToolProviderFinder.find(SA_JINFO_TOOL_NAME) != null; - - System.err.println("Usage:"); - if (usageSA) { - System.err.println(" jinfo [option] <pid>"); - System.err.println(" (to connect to a running process)"); - System.err.println(" jinfo -F [option] <pid>"); - System.err.println(" (to connect to a hung process)"); - System.err.println(" jinfo [option] <executable> <core>"); - System.err.println(" (to connect to a core file)"); - System.err.println(" jinfo [option] [server_id@]<remote server IP or hostname>"); - System.err.println(" (to connect to remote debug server)"); - System.err.println(""); - System.err.println("where <option> is one of:"); - System.err.println(" for running processes:"); - System.err.println(" -flag <name> to print the value of the named VM flag"); - System.err.println(" -flag [+|-]<name> to enable or disable the named VM flag"); - System.err.println(" -flag <name>=<value> to set the named VM flag to the given value"); - System.err.println(" for running or hung processes and core files:"); - System.err.println(" -flags to print VM flags"); - System.err.println(" -sysprops to print Java system properties"); - System.err.println(" <no option> to print both VM flags and system properties"); - System.err.println(" -h | -help to print this help message"); - } else { - System.err.println(" jinfo <option> <pid>"); - System.err.println(" (to connect to a running process)"); - System.err.println(""); - System.err.println("where <option> is one of:"); - System.err.println(" -flag <name> to print the value of the named VM flag"); - System.err.println(" -flag [+|-]<name> to enable or disable the named VM flag"); - System.err.println(" -flag <name>=<value> to set the named VM flag to the given value"); - System.err.println(" -flags to print VM flags"); - System.err.println(" -sysprops to print Java system properties"); - System.err.println(" <no option> to print both VM flags and system properties"); - System.err.println(" -h | -help to print this help message"); + for (String s : args) { + if (s.equals("-F")) { + SAOptionError("-F option used"); + } + if (s.equals("-flag")) { + maxCount = 2; + } + if (! s.startsWith("-")) { + paramCount += 1; + } } + if (paramCount > maxCount) { + SAOptionError("More than " + maxCount + " non-option argument"); + } + } + + private static void SAOptionError(String msg) { + System.err.println("Error: " + msg); + System.err.println("Cannot connect to core dump or remote debug server. Use jhsdb jinfo instead"); + System.exit(1); + } + + // print usage message + private static void usage(int exit) { + System.err.println("Usage:"); + System.err.println(" jinfo <option> <pid>"); + System.err.println(" (to connect to a running process)"); + System.err.println(""); + System.err.println("where <option> is one of:"); + System.err.println(" -flag <name> to print the value of the named VM flag"); + System.err.println(" -flag [+|-]<name> to enable or disable the named VM flag"); + System.err.println(" -flag <name>=<value> to set the named VM flag to the given value"); + System.err.println(" -flags to print VM flags"); + System.err.println(" -sysprops to print Java system properties"); + System.err.println(" <no option> to print both VM flags and system properties"); + System.err.println(" -h | -help to print this help message"); System.exit(exit); } } diff --git a/jdk/src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java b/jdk/src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java index cb7651e476b..810a44eee6f 100644 --- a/jdk/src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java +++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/jmap/JMap.java @@ -28,12 +28,13 @@ package sun.tools.jmap; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.Collection; import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.AttachNotSupportedException; import sun.tools.attach.HotSpotVirtualMachine; -import jdk.internal.vm.agent.spi.ToolProvider; -import jdk.internal.vm.agent.spi.ToolProviderFinder; +import sun.tools.common.ProcessArgumentMatcher; /* * This class is the main class for the JMap utility. It parses its arguments @@ -44,34 +45,18 @@ import jdk.internal.vm.agent.spi.ToolProviderFinder; */ public class JMap { - // Options handled by the attach mechanism - private static String HISTO_OPTION = "-histo"; - private static String LIVE_HISTO_OPTION = "-histo:live"; - private static String DUMP_OPTION_PREFIX = "-dump:"; - - // These options imply the use of a SA tool - private static String SA_TOOL_OPTIONS = - "-heap|-heap:format=b|-clstats|-finalizerinfo"; - - // The -F (force) option is currently not passed through to SA - private static String FORCE_SA_OPTION = "-F"; - - // Default option (if nothing provided) - private static String DEFAULT_OPTION = "-pmap"; - public static void main(String[] args) throws Exception { if (args.length == 0) { usage(1); // no arguments } - // used to indicate if we should use SA - boolean useSA = false; + checkForUnsupportedOptions(args); - // the chosen option (-heap, -dump:*, ... ) + // the chosen option String option = null; // First iterate over the options (arguments starting with -). There should be - // one (but maybe two if -F is also used). + // one. int optionCount = 0; while (optionCount < args.length) { String arg = args[optionCount]; @@ -80,8 +65,6 @@ public class JMap { } if (arg.equals("-help") || arg.equals("-h")) { usage(0); - } else if (arg.equals(FORCE_SA_OPTION)) { - useSA = true; } else { if (option != null) { usage(1); // option already specified @@ -93,123 +76,102 @@ public class JMap { // if no option provided then use default. if (option == null) { - option = DEFAULT_OPTION; - } - if (option.matches(SA_TOOL_OPTIONS)) { - useSA = true; + usage(0); } - // Next we check the parameter count. For the SA tools there are - // one or two parameters. For the built-in -dump option there is - // only one parameter (the process-id) + // Next we check the parameter count. int paramCount = args.length - optionCount; - if (paramCount == 0 || paramCount > 2) { + if (paramCount != 1) { usage(1); } - if (optionCount == 0 || paramCount != 1) { - useSA = true; - } else { - // the parameter for the -dump option is a process-id. - // If it doesn't parse to a number then it must be SA - // debug server - if (!args[optionCount].matches("[0-9]+")) { - useSA = true; + String pidArg = args[1]; + // Here we handle the built-in options + // As more options are added we should create an abstract tool class and + // have a table to map the options + ProcessArgumentMatcher ap = new ProcessArgumentMatcher(pidArg, JMap.class); + Collection<String> pids = ap.getPids(); + for (String pid : pids) { + if (pids.size() > 1) { + System.out.println("Pid:" + pid); } - } - - - // at this point we know if we are executing an SA tool or a built-in - // option. - - if (useSA) { - // parameters (<pid> or <exe> <core>) - String params[] = new String[paramCount]; - for (int i=optionCount; i<args.length; i++ ){ - params[i-optionCount] = args[i]; - } - runTool(option, params); - - } else { - String pid = args[1]; - // Here we handle the built-in options - // As more options are added we should create an abstract tool class and - // have a table to map the options - if (option.equals(HISTO_OPTION)) { - histo(pid, false); - } else if (option.equals(LIVE_HISTO_OPTION)) { - histo(pid, true); - } else if (option.startsWith(DUMP_OPTION_PREFIX)) { - dump(pid, option); + if (option.equals("-histo")) { + histo(pid, ""); + } else if (option.startsWith("-histo:")) { + histo(pid, option.substring("-histo:".length())); + } else if (option.startsWith("-dump:")) { + dump(pid, option.substring("-dump:".length())); + } else if (option.equals("-finalizerinfo")) { + executeCommandForPid(pid, "jcmd", "GC.finalizer_info"); + } else if (option.equals("-clstats")) { + executeCommandForPid(pid, "jcmd", "GC.class_stats"); } else { - usage(1); + usage(1); } } } - // Invoke SA tool with the given arguments - private static void runTool(String option, String args[]) throws Exception { - String[][] tools = { - { "-pmap", "pmap" }, - { "-heap", "heapSummary" }, - { "-heap:format=b", "heapDumper" }, - { "-histo", "objectHistogram" }, - { "-clstats", "classLoaderStats" }, - { "-finalizerinfo", "finalizerInfo" }, - }; + private static void executeCommandForPid(String pid, String command, Object ... args) + throws AttachNotSupportedException, IOException, + UnsupportedEncodingException { + VirtualMachine vm = VirtualMachine.attach(pid); - String name = null; - - // -dump option needs to be handled in a special way - if (option.startsWith(DUMP_OPTION_PREFIX)) { - // first check that the option can be parsed - String fn = parseDumpOptions(option); - if (fn == null) { - usage(1); - } - - // tool for heap dumping - name = "heapDumper"; - - // HeapDumper -f <file> - args = prepend(fn, args); - args = prepend("-f", args); - } else { - int i=0; - while (i < tools.length) { - if (option.equals(tools[i][0])) { - name = tools[i][1]; - break; - } - i++; - } - } - if (name == null) { - usage(1); // no mapping to tool + // Cast to HotSpotVirtualMachine as this is an + // implementation specific method. + HotSpotVirtualMachine hvm = (HotSpotVirtualMachine) vm; + try (InputStream in = hvm.executeCommand(command, args)) { + // read to EOF and just print output + byte b[] = new byte[256]; + int n; + do { + n = in.read(b); + if (n > 0) { + String s = new String(b, 0, n, "UTF-8"); + System.out.print(s); + } + } while (n > 0); } + vm.detach(); + } - // Tool not available on this platform. - ToolProvider tool = ToolProviderFinder.find(name); - if (tool == null) { + private static void histo(String pid, String options) + throws AttachNotSupportedException, IOException, + UnsupportedEncodingException { + String liveopt = "-all"; + if (options.equals("") || options.equals("all")) { + // pass + } + else if (options.equals("live")) { + liveopt = "-live"; + } + else { usage(1); } - // invoke the main method with the arguments - tool.run(args); + // inspectHeap is not the same as jcmd GC.class_histogram + executeCommandForPid(pid, "inspectheap", liveopt); } - private static final String LIVE_OBJECTS_OPTION = "-live"; - private static final String ALL_OBJECTS_OPTION = "-all"; - private static void histo(String pid, boolean live) throws IOException { - VirtualMachine vm = attach(pid); - InputStream in = ((HotSpotVirtualMachine)vm). - heapHisto(live ? LIVE_OBJECTS_OPTION : ALL_OBJECTS_OPTION); - drain(vm, in); - } + private static void dump(String pid, String options) + throws AttachNotSupportedException, IOException, + UnsupportedEncodingException { + + String subopts[] = options.split(","); + String filename = null; + String liveopt = "-all"; + + for (int i = 0; i < subopts.length; i++) { + String subopt = subopts[i]; + if (subopt.equals("live")) { + liveopt = "-live"; + } else if (subopt.startsWith("file=")) { + // file=<file> - check that <file> is specified + if (subopt.length() > 5) { + filename = subopt.substring(5); + } + } + } - private static void dump(String pid, String options) throws IOException { - // parse the options to get the dump filename - String filename = parseDumpOptions(options); if (filename == null) { usage(1); // invalid options or no filename } @@ -219,156 +181,73 @@ public class JMap { // working directory rather than the directory where jmap // is executed. filename = new File(filename).getCanonicalPath(); - - // dump live objects only or not - boolean live = isDumpLiveObjects(options); - - VirtualMachine vm = attach(pid); - System.out.println("Dumping heap to " + filename + " ..."); - InputStream in = ((HotSpotVirtualMachine)vm). - dumpHeap((Object)filename, - (live ? LIVE_OBJECTS_OPTION : ALL_OBJECTS_OPTION)); - drain(vm, in); + // dumpHeap is not the same as jcmd GC.heap_dump + executeCommandForPid(pid, "dumpheap", filename, liveopt); } - // Parse the options to the -dump option. Valid options are format=b and - // file=<file>. Returns <file> if provided. Returns null if <file> not - // provided, or invalid option. - private static String parseDumpOptions(String arg) { - assert arg.startsWith(DUMP_OPTION_PREFIX); + private static void checkForUnsupportedOptions(String[] args) { + // Check arguments for -F, -m, and non-numeric value + // and warn the user that SA is not supported anymore - String filename = null; + int paramCount = 0; - // options are separated by comma (,) - String options[] = arg.substring(DUMP_OPTION_PREFIX.length()).split(","); + for (String s : args) { + if (s.equals("-F")) { + SAOptionError("-F option used"); + } - for (int i=0; i<options.length; i++) { - String option = options[i]; + if (s.equals("-heap")) { + SAOptionError("-heap option used"); + } - if (option.equals("format=b")) { - // ignore format (not needed at this time) - } else if (option.equals("live")) { - // a valid suboption - } else { + /* Reimplemented using jcmd, output format is different + from original one - // file=<file> - check that <file> is specified - if (option.startsWith("file=")) { - filename = option.substring(5); - if (filename.length() == 0) { - return null; - } - } else { - return null; // option not recognized - } + if (s.equals("-clstats")) { + warnSA("-clstats option used"); + } + + if (s.equals("-finalizerinfo")) { + warnSA("-finalizerinfo option used"); + } + */ + + if (! s.startsWith("-")) { + paramCount += 1; } } - return filename; - } - private static boolean isDumpLiveObjects(String arg) { - // options are separated by comma (,) - String options[] = arg.substring(DUMP_OPTION_PREFIX.length()).split(","); - for (String suboption : options) { - if (suboption.equals("live")) { - return true; - } - } - return false; - } - - // Attach to <pid>, existing if we fail to attach - private static VirtualMachine attach(String pid) { - try { - return VirtualMachine.attach(pid); - } catch (Exception x) { - String msg = x.getMessage(); - if (msg != null) { - System.err.println(pid + ": " + msg); - } else { - x.printStackTrace(); - } - if ((x instanceof AttachNotSupportedException) && haveSA()) { - System.err.println("The -F option can be used when the " + - "target process is not responding"); - } - System.exit(1); - return null; // keep compiler happy + if (paramCount > 1) { + SAOptionError("More than one non-option argument"); } } - // Read the stream from the target VM until EOF, then detach - private static void drain(VirtualMachine vm, InputStream in) throws IOException { - // read to EOF and just print output - byte b[] = new byte[256]; - int n; - do { - n = in.read(b); - if (n > 0) { - String s = new String(b, 0, n, "UTF-8"); - System.out.print(s); - } - } while (n > 0); - in.close(); - vm.detach(); - } - - // return a new string array with arg as the first element - private static String[] prepend(String arg, String args[]) { - String[] newargs = new String[args.length+1]; - newargs[0] = arg; - System.arraycopy(args, 0, newargs, 1, args.length); - return newargs; - } - - // returns true if SA is available - private static boolean haveSA() { - return ToolProviderFinder.find("heapSummary") != null; + private static void SAOptionError(String msg) { + System.err.println("Error: " + msg); + System.err.println("Cannot connect to core dump or remote debug server. Use jhsdb jmap instead"); + System.exit(1); } // print usage message private static void usage(int exit) { System.err.println("Usage:"); - if (haveSA()) { - System.err.println(" jmap [option] <pid>"); - System.err.println(" (to connect to running process)"); - System.err.println(" jmap [option] <executable <core>"); - System.err.println(" (to connect to a core file)"); - System.err.println(" jmap [option] [server_id@]<remote server IP or hostname>"); - System.err.println(" (to connect to remote debug server)"); - System.err.println(""); - System.err.println("where <option> is one of:"); - System.err.println(" <none> to print same info as Solaris pmap"); - System.err.println(" -heap to print java heap summary"); - System.err.println(" -histo[:live] to print histogram of java object heap; if the \"live\""); - System.err.println(" suboption is specified, only count live objects"); - System.err.println(" -clstats to print class loader statistics"); - System.err.println(" -finalizerinfo to print information on objects awaiting finalization"); - System.err.println(" -dump:<dump-options> to dump java heap in hprof binary format"); - System.err.println(" dump-options:"); - System.err.println(" live dump only live objects; if not specified,"); - System.err.println(" all objects in the heap are dumped."); - System.err.println(" format=b binary format"); - System.err.println(" file=<file> dump heap to <file>"); - System.err.println(" Example: jmap -dump:live,format=b,file=heap.bin <pid>"); - System.err.println(" -F force. Use with -dump:<dump-options> <pid> or -histo"); - System.err.println(" to force a heap dump or histogram when <pid> does not"); - System.err.println(" respond. The \"live\" suboption is not supported"); - System.err.println(" in this mode."); - System.err.println(" -h | -help to print this help message"); - System.err.println(" -J<flag> to pass <flag> directly to the runtime system"); - } else { - System.err.println(" jmap -histo <pid>"); - System.err.println(" (to connect to running process and print histogram of java object heap"); - System.err.println(" jmap -dump:<dump-options> <pid>"); - System.err.println(" (to connect to running process and dump java heap)"); - System.err.println(""); - System.err.println(" dump-options:"); - System.err.println(" format=b binary default"); - System.err.println(" file=<file> dump heap to <file>"); - System.err.println(""); - System.err.println(" Example: jmap -dump:format=b,file=heap.bin <pid>"); - } - + System.err.println(" jmap -clstats <pid>"); + System.err.println(" to connect to running process and print class loader statistics"); + System.err.println(" jmap -finalizerinfo <pid>"); + System.err.println(" to connect to running process and print information on objects awaiting finalization"); + System.err.println(" jmap -histo[:live] <pid>"); + System.err.println(" to connect to running process and print histogram of java object heap"); + System.err.println(" if the \"live\" suboption is specified, only count live objects"); + System.err.println(" jmap -dump:<dump-options> <pid>"); + System.err.println(" to connect to running process and dump java heap"); + System.err.println(""); + System.err.println(" dump-options:"); + System.err.println(" live dump only live objects; if not specified,"); + System.err.println(" all objects in the heap are dumped."); + System.err.println(" format=b binary format"); + System.err.println(" file=<file> dump heap to <file>"); + System.err.println(""); + System.err.println(" Example: jmap -dump:live,format=b,file=heap.bin <pid>"); System.exit(exit); } } diff --git a/jdk/src/jdk.jcmd/share/classes/sun/tools/jstack/JStack.java b/jdk/src/jdk.jcmd/share/classes/sun/tools/jstack/JStack.java index 355328474fd..7d629e3854e 100644 --- a/jdk/src/jdk.jcmd/share/classes/sun/tools/jstack/JStack.java +++ b/jdk/src/jdk.jcmd/share/classes/sun/tools/jstack/JStack.java @@ -26,12 +26,11 @@ package sun.tools.jstack; import java.io.InputStream; +import java.util.Collection; import com.sun.tools.attach.VirtualMachine; -import com.sun.tools.attach.AttachNotSupportedException; import sun.tools.attach.HotSpotVirtualMachine; -import jdk.internal.vm.agent.spi.ToolProvider; -import jdk.internal.vm.agent.spi.ToolProviderFinder; +import sun.tools.common.ProcessArgumentMatcher; /* * This class is the main class for the JStack utility. It parses its arguments @@ -39,15 +38,14 @@ import jdk.internal.vm.agent.spi.ToolProviderFinder; * obtained the thread dump from a target process using the VM attach mechanism */ public class JStack { - private static final String SA_JSTACK_TOOL_NAME = "jstack"; public static void main(String[] args) throws Exception { if (args.length == 0) { usage(1); // no arguments } - boolean useSA = false; - boolean mixed = false; + checkForUnsupportedOptions(args); + boolean locks = false; // Parse the options (arguments starting with "-" ) @@ -60,87 +58,40 @@ public class JStack { if (arg.equals("-help") || arg.equals("-h")) { usage(0); } - else if (arg.equals("-F")) { - useSA = true; - } else { - if (arg.equals("-m")) { - mixed = true; + if (arg.equals("-l")) { + locks = true; } else { - if (arg.equals("-l")) { - locks = true; - } else { - usage(1); - } + usage(1); } } optionCount++; } - // mixed stack implies SA tool - if (mixed) { - useSA = true; - } - - // Next we check the parameter count. If there are two parameters - // we assume core file and executable so we use SA. + // Next we check the parameter count. int paramCount = args.length - optionCount; - if (paramCount == 0 || paramCount > 2) { + if (paramCount != 1) { usage(1); } - if (paramCount == 2) { - useSA = true; - } else { - // If we can't parse it as a pid then it must be debug server - if (!args[optionCount].matches("[0-9]+")) { - useSA = true; - } - } - // now execute using the SA JStack tool or the built-in thread dumper - if (useSA) { - // parameters (<pid> or <exe> <core> - String params[] = new String[paramCount]; - for (int i=optionCount; i<args.length; i++ ){ - params[i-optionCount] = args[i]; - } - runJStackTool(mixed, locks, params); + // pass -l to thread dump operation to get extra lock info + String pidArg = args[optionCount]; + String params[]; + if (locks) { + params = new String[] { "-l" }; } else { - // pass -l to thread dump operation to get extra lock info - String pid = args[optionCount]; - String params[]; - if (locks) { - params = new String[] { "-l" }; - } else { - params = new String[0]; + params = new String[0]; + } + ProcessArgumentMatcher ap = new ProcessArgumentMatcher(pidArg, JStack.class); + Collection<String> pids = ap.getPids(); + for (String pid : pids) { + if (pids.size() > 1) { + System.out.println("Pid:" + pid); } runThreadDump(pid, params); } } - // SA JStack tool - private static boolean isAgentToolPresent() { - return ToolProviderFinder.find(SA_JSTACK_TOOL_NAME) != null; - } - - private static void runJStackTool(boolean mixed, boolean locks, String args[]) throws Exception { - ToolProvider tool = ToolProviderFinder.find(SA_JSTACK_TOOL_NAME); - if (tool == null) { - usage(1); // SA not available - } - - // JStack tool also takes -m and -l arguments - if (mixed) { - args = prepend("-m", args); - } - if (locks) { - args = prepend("-l", args); - } - - tool.run(args); - } - - // Attach to pid and perform a thread dump private static void runThreadDump(String pid, String args[]) throws Exception { VirtualMachine vm = null; @@ -153,10 +104,6 @@ public class JStack { } else { x.printStackTrace(); } - if ((x instanceof AttachNotSupportedException) && isAgentToolPresent()) { - System.err.println("The -F option can be used when the target " + - "process is not responding"); - } System.exit(1); } @@ -178,12 +125,35 @@ public class JStack { vm.detach(); } - // return a new string array with arg as the first element - private static String[] prepend(String arg, String args[]) { - String[] newargs = new String[args.length+1]; - newargs[0] = arg; - System.arraycopy(args, 0, newargs, 1, args.length); - return newargs; + private static void checkForUnsupportedOptions(String[] args) { + // Check arguments for -F, -m, and non-numeric value + // and warn the user that SA is not supported anymore + + int paramCount = 0; + + for (String s : args) { + if (s.equals("-F")) { + SAOptionError("-F option used"); + } + + if (s.equals("-m")) { + SAOptionError("-m option used"); + } + + if (! s.startsWith("-")) { + paramCount += 1; + } + } + + if (paramCount > 1) { + SAOptionError("More than one non-option argument"); + } + } + + private static void SAOptionError(String msg) { + System.err.println("Error: " + msg); + System.err.println("Cannot connect to core dump or remote debug server. Use jhsdb jstack instead"); + System.exit(1); } // print usage message @@ -191,25 +161,8 @@ public class JStack { System.err.println("Usage:"); System.err.println(" jstack [-l] <pid>"); System.err.println(" (to connect to running process)"); - - if (isAgentToolPresent()) { - System.err.println(" jstack -F [-m] [-l] <pid>"); - System.err.println(" (to connect to a hung process)"); - System.err.println(" jstack [-m] [-l] <executable> <core>"); - System.err.println(" (to connect to a core file)"); - System.err.println(" jstack [-m] [-l] [server_id@]<remote server IP or hostname>"); - System.err.println(" (to connect to a remote debug server)"); - } - System.err.println(""); System.err.println("Options:"); - - if (isAgentToolPresent()) { - System.err.println(" -F to force a thread dump. Use when jstack <pid> does not respond" + - " (process is hung)"); - System.err.println(" -m to print both java and native frames (mixed mode)"); - } - System.err.println(" -l long listing. Prints additional information about locks"); System.err.println(" -h or -help to print this help message"); System.exit(exit); diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Commands.java b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Commands.java index bbae8bc44c8..5e6438d887a 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Commands.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/Commands.java @@ -1534,7 +1534,6 @@ class Commands { PathSearchingVirtualMachine vm = (PathSearchingVirtualMachine)Env.vm(); MessageOutput.println("base directory:", vm.baseDirectory()); MessageOutput.println("classpath:", vm.classPath().toString()); - MessageOutput.println("bootclasspath:", vm.bootClassPath().toString()); } else { MessageOutput.println("The VM does not use paths"); } diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/EventHandler.java b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/EventHandler.java index fe6dd070f0d..cd416ccf24e 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/EventHandler.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/EventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, 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 @@ -133,6 +133,10 @@ public class EventHandler implements Runnable { if (!vmDied) { vmDisconnectEvent(event); } + /* + * Inform jdb command line processor that jdb is being shutdown. JDK-8154144. + */ + ((TTY)notifier).setShuttingDown(true); Env.shutdown(shutdownMessageKey); return false; } else { diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java index 0bd403af2b9..ee716a55dcb 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTY.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2016, 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,6 +56,16 @@ public class TTY implements EventNotifier { */ private static final String progname = "jdb"; + private volatile boolean shuttingDown = false; + + public void setShuttingDown(boolean s) { + shuttingDown = s; + } + + public boolean isShuttingDown() { + return shuttingDown; + } + @Override public void vmStartEvent(VMStartEvent se) { Thread.yield(); // fetch output @@ -750,7 +760,13 @@ public class TTY implements EventNotifier { while (true) { String ln = in.readLine(); if (ln == null) { - MessageOutput.println("Input stream closed."); + /* + * Jdb is being shutdown because debuggee exited, ignore any 'null' + * returned by readLine() during shutdown. JDK-8154144. + */ + if (!isShuttingDown()) { + MessageOutput.println("Input stream closed."); + } ln = "quit"; } diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources.java b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources.java index c412743c4b6..39e703d88b8 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources.java @@ -74,7 +74,6 @@ public class TTYResources extends java.util.ListResourceBundle { {"Array element is not a method", "Array element is not a method"}, {"Array index must be a integer type", "Array index must be a integer type"}, {"base directory:", "base directory: {0}"}, - {"bootclasspath:", "bootclasspath: {0}"}, {"Breakpoint hit:", "Breakpoint hit: "}, {"breakpoint", "breakpoint {0}"}, {"Breakpoints set:", "Breakpoints set:"}, diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_ja.java b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_ja.java index 1cb6d231d50..b3562226398 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_ja.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_ja.java @@ -74,7 +74,6 @@ public class TTYResources_ja extends java.util.ListResourceBundle { {"Array element is not a method", "\u914D\u5217\u8981\u7D20\u306F\u30E1\u30BD\u30C3\u30C9\u3067\u306F\u3042\u308A\u307E\u305B\u3093"}, {"Array index must be a integer type", "\u914D\u5217\u306E\u6DFB\u3048\u5B57\u306F\u6574\u6570\u578B\u3067\u3042\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059"}, {"base directory:", "\u30D9\u30FC\u30B9\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA: {0}"}, - {"bootclasspath:", "\u30D6\u30FC\u30C8\u30FB\u30AF\u30E9\u30B9\u30D1\u30B9: {0}"}, {"Breakpoint hit:", "\u30D2\u30C3\u30C8\u3057\u305F\u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8: "}, {"breakpoint", "\u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8{0}"}, {"Breakpoints set:", "\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u30D6\u30EC\u30FC\u30AF\u30DD\u30A4\u30F3\u30C8:"}, diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_zh_CN.java b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_zh_CN.java index 50790cb9d72..79dc9268da0 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_zh_CN.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/example/debug/tty/TTYResources_zh_CN.java @@ -74,7 +74,6 @@ public class TTYResources_zh_CN extends java.util.ListResourceBundle { {"Array element is not a method", "\u6570\u7EC4\u5143\u7D20\u4E0D\u662F\u65B9\u6CD5"}, {"Array index must be a integer type", "\u6570\u7EC4\u7D22\u5F15\u5FC5\u987B\u4E3A\u6574\u6570\u7C7B\u578B"}, {"base directory:", "\u57FA\u76EE\u5F55: {0}"}, - {"bootclasspath:", "\u5F15\u5BFC\u7C7B\u8DEF\u5F84: {0}"}, {"Breakpoint hit:", "\u65AD\u70B9\u547D\u4E2D: "}, {"breakpoint", "\u65AD\u70B9{0}"}, {"Breakpoints set:", "\u65AD\u70B9\u96C6:"}, diff --git a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java index 47e743483e3..28c3dfbfa3c 100644 --- a/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java +++ b/jdk/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineImpl.java @@ -1439,7 +1439,7 @@ class VirtualMachineImpl extends MirrorImpl } public List<String> bootClassPath() { - return Arrays.asList(getClasspath().bootclasspaths); + return Collections.emptyList(); } public String baseDirectory() { diff --git a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/VirtualMachineImpl.c b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/VirtualMachineImpl.c index 2718ad1e3a4..8e1639c5e2e 100644 --- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/VirtualMachineImpl.c +++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/VirtualMachineImpl.c @@ -126,7 +126,7 @@ classesForSignature(PacketInputStream *in, PacketOutputStream *out) int writtenCount = 0; int i; - for (i=0; i<classCount; i++) { + for (i = 0; i < classCount; i++) { jclass clazz = theClasses[i]; jint status = classStatus(clazz); char *candidate_signature = NULL; @@ -141,7 +141,13 @@ classesForSignature(PacketInputStream *in, PacketOutputStream *out) error = classSignature(clazz, &candidate_signature, NULL); if (error != JVMTI_ERROR_NONE) { - break; + // Clazz become invalid since the time we get the class list + // Skip this entry + if (error == JVMTI_ERROR_INVALID_CLASS) { + continue; + } + + break; } if (strcmp(candidate_signature, signature) == 0) { diff --git a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c index cd1cd2f7dc0..3baf486c233 100644 --- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c +++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.c @@ -277,12 +277,14 @@ invoker_enableInvokeRequests(jthread thread) JDI_ASSERT(thread); + debugMonitorEnter(invokerLock); request = threadControl_getInvokeRequest(thread); if (request == NULL) { EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request"); } request->available = JNI_TRUE; + debugMonitorExit(invokerLock); } jvmtiError @@ -738,30 +740,21 @@ invoker_completeInvokeRequest(jthread thread) } } -jboolean -invoker_isPending(jthread thread) -{ - InvokeRequest *request; - - JDI_ASSERT(thread); - request = threadControl_getInvokeRequest(thread); - if (request == NULL) { - EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request"); - } - return request->pending; -} - jboolean invoker_isEnabled(jthread thread) { InvokeRequest *request; + jboolean isEnabled; JDI_ASSERT(thread); + debugMonitorEnter(invokerLock); request = threadControl_getInvokeRequest(thread); if (request == NULL) { EXIT_ERROR(AGENT_ERROR_INVALID_THREAD, "getting thread invoke request"); } - return request->available; + isEnabled = request->available; + debugMonitorExit(invokerLock); + return isEnabled; } void diff --git a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.h b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.h index 29ecdb5d59c..e004ce6ef8e 100644 --- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.h +++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/invoker.h @@ -67,7 +67,6 @@ jvmtiError invoker_requestInvoke(jbyte invokeType, jbyte options, jint id, jboolean invoker_doInvoke(jthread thread); void invoker_completeInvokeRequest(jthread thread); -jboolean invoker_isPending(jthread thread); jboolean invoker_isEnabled(jthread thread); void invoker_detach(InvokeRequest *request); diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/Jlink.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/Jlink.java index 92d7eb64fcf..e899d378963 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/Jlink.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/Jlink.java @@ -34,11 +34,9 @@ import java.util.Objects; import java.util.Set; import jdk.tools.jlink.internal.JlinkTask; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.PluginContext; import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.ExecutableImage; import jdk.tools.jlink.builder.ImageBuilder; -import jdk.tools.jlink.internal.PluginContextImpl; import jdk.tools.jlink.internal.PluginRepository; /** @@ -71,7 +69,6 @@ public final class Jlink { private final List<Plugin> plugins; private final ImageBuilder imageBuilder; private final String lastSorterPluginName; - private final PluginContext pluginContext; /** * Empty plugins configuration. @@ -86,7 +83,7 @@ public final class Jlink { * @param plugins List of plugins. */ public PluginsConfiguration(List<Plugin> plugins) { - this(plugins, null, null, null); + this(plugins, null, null); } /** @@ -101,28 +98,10 @@ public final class Jlink { */ public PluginsConfiguration(List<Plugin> plugins, ImageBuilder imageBuilder, String lastSorterPluginName) { - this(plugins, imageBuilder, lastSorterPluginName, null); - } - - /** - * Plugins configuration with a last sorter and an ImageBuilder. No - * sorting can occur after the last sorter plugin. The ImageBuilder is - * in charge to layout the image content on disk. - * - * @param plugins List of transformer plugins. - * @param imageBuilder Image builder. - * @param lastSorterPluginName Name of last sorter plugin, no sorting - * @param ctx the plugin context - * can occur after it. - */ - public PluginsConfiguration(List<Plugin> plugins, - ImageBuilder imageBuilder, String lastSorterPluginName, - PluginContext ctx) { this.plugins = plugins == null ? Collections.emptyList() : plugins; this.imageBuilder = imageBuilder; this.lastSorterPluginName = lastSorterPluginName; - this.pluginContext = ctx != null? ctx : new PluginContextImpl(); } /** @@ -146,13 +125,6 @@ public final class Jlink { return lastSorterPluginName; } - /** - * @return the pluginContext - */ - public PluginContext getPluginContext() { - return pluginContext; - } - @Override public String toString() { StringBuilder builder = new StringBuilder(); diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java index a3943145c06..2c0620a99db 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java @@ -1,3 +1,4 @@ + /* * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -24,8 +25,6 @@ */ package jdk.tools.jlink.builder; -import jdk.tools.jlink.plugin.ExecutableImage; -import jdk.tools.jlink.plugin.PluginException; import java.io.BufferedOutputStream; import java.io.BufferedWriter; import java.io.ByteArrayInputStream; @@ -47,8 +46,10 @@ import java.nio.file.StandardOpenOption; import java.nio.file.attribute.PosixFileAttributeView; import java.nio.file.attribute.PosixFilePermission; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Properties; @@ -56,23 +57,40 @@ import java.util.Set; import jdk.tools.jlink.internal.BasicImageWriter; import jdk.tools.jlink.internal.plugins.FileCopierPlugin; import jdk.tools.jlink.internal.plugins.FileCopierPlugin.SymImageFile; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.Module; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ExecutableImage; +import jdk.tools.jlink.plugin.ModulePool; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.PluginException; /** * * Default Image Builder. This builder creates the default runtime image layout. */ -public class DefaultImageBuilder implements ImageBuilder { +public final class DefaultImageBuilder implements ImageBuilder { /** * The default java executable Image. */ - static class DefaultExecutableImage extends ExecutableImage { + static final class DefaultExecutableImage implements ExecutableImage { + + private final Path home; + private final List<String> args; + private final Set<String> modules; public DefaultExecutableImage(Path home, Set<String> modules) { - super(home, modules, createArgs(home)); + this(home, modules, createArgs(home)); + } + + private DefaultExecutableImage(Path home, Set<String> modules, + List<String> args) { + Objects.requireNonNull(home); + Objects.requireNonNull(args); + if (!Files.exists(home)) { + throw new IllegalArgumentException("Invalid image home"); + } + this.home = home; + this.modules = Collections.unmodifiableSet(modules); + this.args = Collections.unmodifiableList(args); } private static List<String> createArgs(Path home) { @@ -83,6 +101,21 @@ public class DefaultImageBuilder implements ImageBuilder { return javaArgs; } + @Override + public Path getHome() { + return home; + } + + @Override + public Set<String> getModules() { + return modules; + } + + @Override + public List<String> getExecutionArgs() { + return args; + } + @Override public void storeLaunchArgs(List<String> args) { try { @@ -111,17 +144,19 @@ public class DefaultImageBuilder implements ImageBuilder { Files.createDirectories(mdir); } - private void storeFiles(Set<String> modules, Properties release) throws IOException { + private void storeFiles(Set<String> modules, Map<String, String> release) throws IOException { if (release != null) { - addModules(release, modules); + Properties props = new Properties(); + props.putAll(release); + addModules(props, modules); File r = new File(root.toFile(), "release"); try (FileOutputStream fo = new FileOutputStream(r)) { - release.store(fo, null); + props.store(fo, null); } } } - private void addModules(Properties release, Set<String> modules) throws IOException { + private void addModules(Properties props, Set<String> modules) throws IOException { StringBuilder builder = new StringBuilder(); int i = 0; for (String m : modules) { @@ -131,28 +166,32 @@ public class DefaultImageBuilder implements ImageBuilder { } i++; } - release.setProperty("MODULES", builder.toString()); + props.setProperty("MODULES", builder.toString()); } @Override - public void storeFiles(Pool files, Properties release) { + public void storeFiles(ModulePool files) { try { - for (ModuleData f : files.getContent()) { - if (!f.getType().equals(Pool.ModuleDataType.CLASS_OR_RESOURCE)) { - accept(f); + files.entries().forEach(f -> { + if (!f.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) { + try { + accept(f); + } catch (IOException ioExp) { + throw new UncheckedIOException(ioExp); + } } - } - for (Module m : files.getModules()) { + }); + files.modules().forEach(m -> { // Only add modules that contain packages if (!m.getAllPackages().isEmpty()) { // Skip the fake module used by FileCopierPlugin when copying files. if (m.getName().equals(FileCopierPlugin.FAKE_MODULE)) { - continue; + return; } modules.add(m.getName()); } - } - storeFiles(modules, release); + }); + storeFiles(modules, files.getReleaseProperties()); if (Files.getFileStore(root).supportsFileAttributeView(PosixFileAttributeView.class)) { // launchers in the bin directory need execute permission @@ -168,8 +207,8 @@ public class DefaultImageBuilder implements ImageBuilder { Path lib = root.resolve("lib"); if (Files.isDirectory(lib)) { Files.find(lib, 2, (path, attrs) -> { - return path.getFileName().toString().equals("jspawnhelper") || - path.getFileName().toString().equals("jexec"); + return path.getFileName().toString().equals("jspawnhelper") + || path.getFileName().toString().equals("jexec"); }).forEach(this::setExecutable); } } @@ -180,27 +219,23 @@ public class DefaultImageBuilder implements ImageBuilder { } } - @Override - public void storeFiles(Pool files) { - storeFiles(files, new Properties()); - } - /** * Generates launcher scripts. + * * @param imageContent The image content. * @param modules The set of modules that the runtime image contains. * @throws IOException */ - protected void prepareApplicationFiles(Pool imageContent, Set<String> modules) throws IOException { + protected void prepareApplicationFiles(ModulePool imageContent, Set<String> modules) throws IOException { // generate launch scripts for the modules with a main class for (String module : modules) { String path = "/" + module + "/module-info.class"; - ModuleData res = imageContent.get(path); - if (res == null) { + Optional<ModuleEntry> res = imageContent.findEntry(path); + if (!res.isPresent()) { throw new IOException("module-info.class not found for " + module + " module"); } Optional<String> mainClass; - ByteArrayInputStream stream = new ByteArrayInputStream(res.getBytes()); + ByteArrayInputStream stream = new ByteArrayInputStream(res.get().getBytes()); mainClass = ModuleDescriptor.read(stream).mainClass(); if (mainClass.isPresent()) { Path cmd = root.resolve("bin").resolve(module); @@ -263,9 +298,9 @@ public class DefaultImageBuilder implements ImageBuilder { } } - private void accept(ModuleData file) throws IOException { + private void accept(ModuleEntry file) throws IOException { String fullPath = file.getPath(); - String module = "/" + file.getModule()+ "/"; + String module = "/" + file.getModule() + "/"; String filename = fullPath.substring(module.length()); // Remove radical native|config|... filename = filename.substring(filename.indexOf('/') + 1); @@ -404,8 +439,7 @@ public class DefaultImageBuilder implements ImageBuilder { public static ExecutableImage getExecutableImage(Path root) { if (Files.exists(root.resolve("bin").resolve(getJavaProcessName()))) { - return new DefaultImageBuilder.DefaultExecutableImage(root, - retrieveModules(root)); + return new DefaultExecutableImage(root, retrieveModules(root)); } return null; } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java index dc0bf71c535..10cea85d363 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/ImageBuilder.java @@ -29,7 +29,7 @@ import java.util.Properties; import jdk.tools.jlink.plugin.ExecutableImage; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModulePool; /** * Implement this interface to develop your own image layout. First the jimage @@ -45,7 +45,7 @@ public interface ImageBuilder { * @param release the release properties * @throws PluginException */ - public default void storeFiles(Pool content, Properties release) { + public default void storeFiles(ModulePool content, Properties release) { storeFiles(content); } @@ -55,7 +55,7 @@ public interface ImageBuilder { * @param content Pool of module content. * @throws PluginException */ - public default void storeFiles(Pool content) { + public default void storeFiles(ModulePool content) { throw new UnsupportedOperationException("storeFiles"); } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java index e0347e52a21..f765be2919b 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImageFileCreator.java @@ -44,12 +44,11 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.tools.jlink.internal.Archive.Entry; import jdk.tools.jlink.internal.Archive.Entry.EntryType; -import jdk.tools.jlink.internal.PoolImpl.CompressedModuleData; +import jdk.tools.jlink.internal.ModulePoolImpl.CompressedModuleData; import jdk.tools.jlink.plugin.ExecutableImage; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.plugin.ModulePool; +import jdk.tools.jlink.plugin.ModuleEntry; /** * An image (native endian.) @@ -145,7 +144,7 @@ public final class ImageFileCreator { })); ByteOrder order = ByteOrder.nativeOrder(); BasicImageWriter writer = new BasicImageWriter(order); - PoolImpl pool = createPools(archives, entriesForModule, order, writer); + ModulePoolImpl pool = createPools(archives, entriesForModule, order, writer); try (OutputStream fos = Files.newOutputStream(jimageFile); BufferedOutputStream bos = new BufferedOutputStream(fos); DataOutputStream out = new DataOutputStream(bos)) { @@ -163,9 +162,9 @@ public final class ImageFileCreator { ByteOrder byteOrder) throws IOException { BasicImageWriter writer = new BasicImageWriter(byteOrder); - PoolImpl allContent = createPools(archives, + ModulePoolImpl allContent = createPools(archives, entriesForModule, byteOrder, writer); - PoolImpl result = generateJImage(allContent, + ModulePoolImpl result = generateJImage(allContent, writer, plugins, plugins.getJImageFileOutputStream()); //Handle files. @@ -176,12 +175,12 @@ public final class ImageFileCreator { } } - private static PoolImpl generateJImage(PoolImpl allContent, + private static ModulePoolImpl generateJImage(ModulePoolImpl allContent, BasicImageWriter writer, ImagePluginStack pluginSupport, DataOutputStream out ) throws IOException { - PoolImpl resultResources; + ModulePoolImpl resultResources; try { resultResources = pluginSupport.visitResources(allContent); } catch (PluginException pe) { @@ -190,14 +189,14 @@ public final class ImageFileCreator { throw new IOException(ex); } Set<String> duplicates = new HashSet<>(); - long offset = 0; + long[] offset = new long[1]; - List<ModuleData> content = new ArrayList<>(); + List<ModuleEntry> content = new ArrayList<>(); List<String> paths = new ArrayList<>(); // the order of traversing the resources and the order of // the module content being written must be the same - for (ModuleData res : resultResources.getContent()) { - if (res.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) { + resultResources.entries().forEach(res -> { + if (res.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) { String path = res.getPath(); content.add(res); long uncompressedSize = res.getLength(); @@ -216,24 +215,24 @@ public final class ImageFileCreator { // TODO Need to hang bytes on resource and write // from resource not zip. // Skipping resource throws off writing from zip. - offset += onFileSize; - continue; + offset[0] += onFileSize; + return; } duplicates.add(path); - writer.addLocation(path, offset, compressedSize, uncompressedSize); + writer.addLocation(path, offset[0], compressedSize, uncompressedSize); paths.add(path); - offset += onFileSize; + offset[0] += onFileSize; } - } + }); - ImageResourcesTree tree = new ImageResourcesTree(offset, writer, paths); + ImageResourcesTree tree = new ImageResourcesTree(offset[0], writer, paths); // write header and indices byte[] bytes = writer.getBytes(); out.write(bytes, 0, bytes.length); // write module content - for (ModuleData res : content) { + for (ModuleEntry res : content) { byte[] buf = res.getBytes(); out.write(buf, 0, buf.length); } @@ -245,26 +244,26 @@ public final class ImageFileCreator { return resultResources; } - private static Pool.ModuleDataType mapImageFileType(EntryType type) { + private static ModuleEntry.Type mapImageFileType(EntryType type) { switch(type) { case CONFIG: { - return Pool.ModuleDataType.CONFIG; + return ModuleEntry.Type.CONFIG; } case NATIVE_CMD: { - return Pool.ModuleDataType.NATIVE_CMD; + return ModuleEntry.Type.NATIVE_CMD; } case NATIVE_LIB: { - return Pool.ModuleDataType.NATIVE_LIB; + return ModuleEntry.Type.NATIVE_LIB; } } return null; } - private static PoolImpl createPools(Set<Archive> archives, + private static ModulePoolImpl createPools(Set<Archive> archives, Map<String, List<Entry>> entriesForModule, ByteOrder byteOrder, BasicImageWriter writer) throws IOException { - PoolImpl resources = new PoolImpl(byteOrder, new StringTable() { + ModulePoolImpl resources = new ModulePoolImpl(byteOrder, new StringTable() { @Override public int addString(String str) { @@ -291,7 +290,7 @@ public final class ImageFileCreator { path = "/" + mn + "/" + path; } try { - resources.add(Pool.newResource(path, bytes)); + resources.add(ModuleEntry.create(path, bytes)); } catch (Exception ex) { throw new IOException(ex); } @@ -300,7 +299,7 @@ public final class ImageFileCreator { try { // Entry.path() contains the kind of file native, conf, bin, ... // Keep it to avoid naming conflict (eg: native/jvm.cfg and config/jvm.cfg - resources.add(Pool.newImageFile(mn, + resources.add(ModuleEntry.create(mn, "/" + mn + "/" + entry.path(), mapImageFileType(entry.type()), entry.stream(), entry.size())); } catch (Exception ex) { diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java index 7bd631a8c72..08ff3cb7e64 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java @@ -28,22 +28,17 @@ import java.io.DataOutputStream; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Objects; -import java.util.Properties; import jdk.tools.jlink.plugin.ExecutableImage; import jdk.tools.jlink.builder.ImageBuilder; import jdk.tools.jlink.Jlink; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.PluginContext; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Plugin.CATEGORY; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.Plugin.Category; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.PostProcessorPlugin; import jdk.tools.jlink.plugin.TransformerPlugin; @@ -52,17 +47,18 @@ import jdk.tools.jlink.plugin.TransformerPlugin; */ public final class ImagePluginConfiguration { - private static final List<Plugin.CATEGORY> CATEGORIES_ORDER = new ArrayList<>(); + private static final List<Plugin.Category> CATEGORIES_ORDER = new ArrayList<>(); static { - CATEGORIES_ORDER.add(Plugin.CATEGORY.FILTER); - CATEGORIES_ORDER.add(Plugin.CATEGORY.TRANSFORMER); - CATEGORIES_ORDER.add(Plugin.CATEGORY.MODULEINFO_TRANSFORMER); - CATEGORIES_ORDER.add(Plugin.CATEGORY.SORTER); - CATEGORIES_ORDER.add(Plugin.CATEGORY.COMPRESSOR); - CATEGORIES_ORDER.add(Plugin.CATEGORY.VERIFIER); - CATEGORIES_ORDER.add(Plugin.CATEGORY.PROCESSOR); - CATEGORIES_ORDER.add(Plugin.CATEGORY.PACKAGER); + CATEGORIES_ORDER.add(Plugin.Category.FILTER); + CATEGORIES_ORDER.add(Plugin.Category.TRANSFORMER); + CATEGORIES_ORDER.add(Plugin.Category.MODULEINFO_TRANSFORMER); + CATEGORIES_ORDER.add(Plugin.Category.SORTER); + CATEGORIES_ORDER.add(Plugin.Category.COMPRESSOR); + CATEGORIES_ORDER.add(Plugin.Category.METAINFO_ADDER); + CATEGORIES_ORDER.add(Plugin.Category.VERIFIER); + CATEGORIES_ORDER.add(Plugin.Category.PROCESSOR); + CATEGORIES_ORDER.add(Plugin.Category.PACKAGER); } private ImagePluginConfiguration() { @@ -76,8 +72,8 @@ public final class ImagePluginConfiguration { if (pluginsConfiguration == null) { return new ImagePluginStack(); } - Map<Plugin.CATEGORY, List<Plugin>> plugins = new LinkedHashMap<>(); - for (Plugin.CATEGORY cat : CATEGORIES_ORDER) { + Map<Plugin.Category, List<Plugin>> plugins = new LinkedHashMap<>(); + for (Plugin.Category cat : CATEGORIES_ORDER) { plugins.put(cat, new ArrayList<>()); } @@ -89,7 +85,7 @@ public final class ImagePluginConfiguration { + " added more than once to stack "); } seen.add(plug.getName()); - CATEGORY category = Utils.getCategory(plug); + Category category = Utils.getCategory(plug); if (category == null) { throw new PluginException("Invalid category for " + plug.getName()); @@ -100,10 +96,10 @@ public final class ImagePluginConfiguration { List<TransformerPlugin> transformerPlugins = new ArrayList<>(); List<PostProcessorPlugin> postProcessingPlugins = new ArrayList<>(); - for (Entry<Plugin.CATEGORY, List<Plugin>> entry : plugins.entrySet()) { + for (Entry<Plugin.Category, List<Plugin>> entry : plugins.entrySet()) { // Sort according to plugin constraints List<Plugin> orderedPlugins = PluginOrderingGraph.sort(entry.getValue()); - CATEGORY category = entry.getKey(); + Category category = entry.getKey(); for (Plugin p : orderedPlugins) { if (Utils.isPostProcessor(category)) { @SuppressWarnings("unchecked") @@ -143,14 +139,13 @@ public final class ImagePluginConfiguration { } @Override - public void storeFiles(Pool files) { + public void storeFiles(ModulePool files) { throw new PluginException("No directory setup to store files"); } }; } - PluginContext ctxt = pluginsConfiguration.getPluginContext(); return new ImagePluginStack(builder, transformerPlugins, - lastSorter, postProcessingPlugins, ctxt); + lastSorter, postProcessingPlugins); } } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java index 6a5db82ccdf..24b8aeb632d 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginStack.java @@ -37,20 +37,21 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; -import java.util.Properties; +import java.util.Optional; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.internal.jimage.decompressor.Decompressor; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.PluginContext; import jdk.tools.jlink.plugin.ExecutableImage; import jdk.tools.jlink.builder.ImageBuilder; import jdk.tools.jlink.plugin.TransformerPlugin; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModulePool; +import jdk.tools.jlink.plugin.LinkModule; +import jdk.tools.jlink.plugin.ModuleEntry; import jdk.tools.jlink.plugin.PostProcessorPlugin; /** @@ -64,9 +65,9 @@ public final class ImagePluginStack { ExecutableImage retrieve(ImagePluginStack stack) throws IOException; } - public static final class OrderedResourcePool extends PoolImpl { + public static final class OrderedResourcePool extends ModulePoolImpl { - private final List<ModuleData> orderedList = new ArrayList<>(); + private final List<ModuleEntry> orderedList = new ArrayList<>(); public OrderedResourcePool(ByteOrder order, StringTable table) { super(order, table); @@ -78,22 +79,22 @@ public final class ImagePluginStack { * @param resource The Resource to add. */ @Override - public void add(ModuleData resource) { + public void add(ModuleEntry resource) { super.add(resource); orderedList.add(resource); } - List<ModuleData> getOrderedList() { + List<ModuleEntry> getOrderedList() { return Collections.unmodifiableList(orderedList); } } - private final static class CheckOrderResourcePool extends PoolImpl { + private final static class CheckOrderResourcePool extends ModulePoolImpl { - private final List<ModuleData> orderedList; + private final List<ModuleEntry> orderedList; private int currentIndex; - public CheckOrderResourcePool(ByteOrder order, List<ModuleData> orderedList, StringTable table) { + public CheckOrderResourcePool(ByteOrder order, List<ModuleEntry> orderedList, StringTable table) { super(order, table); this.orderedList = orderedList; } @@ -104,8 +105,8 @@ public final class ImagePluginStack { * @param resource The Resource to add. */ @Override - public void add(ModuleData resource) { - ModuleData ordered = orderedList.get(currentIndex); + public void add(ModuleEntry resource) { + ModuleEntry ordered = orderedList.get(currentIndex); if (!resource.equals(ordered)) { throw new PluginException("Resource " + resource.getPath() + " not in the right order"); } @@ -166,26 +167,16 @@ public final class ImagePluginStack { private final List<ResourcePrevisitor> resourcePrevisitors = new ArrayList<>(); private final ImageBuilder imageBuilder; - private final Properties release; public ImagePluginStack() { this(null, Collections.emptyList(), null, - Collections.emptyList(), null); + Collections.emptyList()); } public ImagePluginStack(ImageBuilder imageBuilder, List<TransformerPlugin> contentPlugins, Plugin lastSorter, List<PostProcessorPlugin> postprocessingPlugins) { - this(imageBuilder, contentPlugins, lastSorter, - postprocessingPlugins, null); - } - - public ImagePluginStack(ImageBuilder imageBuilder, - List<TransformerPlugin> contentPlugins, - Plugin lastSorter, - List<PostProcessorPlugin> postprocessingPlugins, - PluginContext ctxt) { Objects.requireNonNull(contentPlugins); this.lastSorter = lastSorter; for (TransformerPlugin p : contentPlugins) { @@ -200,7 +191,6 @@ public final class ImagePluginStack { this.postProcessingPlugins.add(p); } this.imageBuilder = imageBuilder; - this.release = ctxt != null? ctxt.getReleaseProperties() : new Properties(); } public void operate(ImageProvider provider) throws Exception { @@ -231,12 +221,12 @@ public final class ImagePluginStack { * @return The result of the visit. * @throws IOException */ - public PoolImpl visitResources(PoolImpl resources) + public ModulePoolImpl visitResources(ModulePoolImpl resources) throws Exception { Objects.requireNonNull(resources); resources.setReadOnly(); if (resources.isEmpty()) { - return new PoolImpl(resources.getByteOrder(), + return new ModulePoolImpl(resources.getByteOrder(), resources.getStringTable()); } PreVisitStrings previsit = new PreVisitStrings(); @@ -250,11 +240,11 @@ public final class ImagePluginStack { resources.getStringTable().addString(s); } - PoolImpl current = resources; - List<Pool.ModuleData> frozenOrder = null; + ModulePoolImpl current = resources; + List<ModuleEntry> frozenOrder = null; for (TransformerPlugin p : contentPlugins) { current.setReadOnly(); - PoolImpl output = null; + ModulePoolImpl output = null; if (p == lastSorter) { if (frozenOrder != null) { throw new Exception("Order of resources is already frozen. Plugin " @@ -268,7 +258,7 @@ public final class ImagePluginStack { output = new CheckOrderResourcePool(current.getByteOrder(), frozenOrder, resources.getStringTable()); } else { - output = new PoolImpl(current.getByteOrder(), + output = new ModulePoolImpl(current.getByteOrder(), resources.getStringTable()); } } @@ -287,15 +277,15 @@ public final class ImagePluginStack { } /** - * This pool wrap the original pool and automatically uncompress moduledata + * This pool wrap the original pool and automatically uncompress ModuleEntry * if needed. */ - private class LastPool extends Pool { - private class LastModule implements Module { + private class LastPool implements ModulePool { + private class LastModule implements LinkModule { - private final Module module; + final LinkModule module; - LastModule(Module module) { + LastModule(LinkModule module) { this.module = module; } @@ -305,9 +295,9 @@ public final class ImagePluginStack { } @Override - public ModuleData get(String path) { - ModuleData d = module.get(path); - return getUncompressed(d); + public Optional<ModuleEntry> findEntry(String path) { + Optional<ModuleEntry> d = module.findEntry(path); + return d.isPresent()? Optional.of(getUncompressed(d.get())) : Optional.empty(); } @Override @@ -316,7 +306,7 @@ public final class ImagePluginStack { } @Override - public void add(ModuleData data) { + public void add(ModuleEntry data) { throw new PluginException("pool is readonly"); } @@ -331,19 +321,24 @@ public final class ImagePluginStack { } @Override - public Collection<ModuleData> getContent() { - List<ModuleData> lst = new ArrayList<>(); - for(ModuleData md : module.getContent()) { + public Stream<ModuleEntry> entries() { + List<ModuleEntry> lst = new ArrayList<>(); + module.entries().forEach(md -> { lst.add(getUncompressed(md)); - } - return lst; + }); + return lst.stream(); + } + + @Override + public int getEntryCount() { + return module.getEntryCount(); } } - private final PoolImpl pool; + private final ModulePoolImpl pool; Decompressor decompressor = new Decompressor(); - Collection<ModuleData> content; + Collection<ModuleEntry> content; - LastPool(PoolImpl pool) { + LastPool(ModulePoolImpl pool) { this.pool = pool; } @@ -353,23 +348,14 @@ public final class ImagePluginStack { } @Override - public void add(ModuleData resource) { + public void add(ModuleEntry resource) { throw new PluginException("pool is readonly"); } - /** - * Retrieves the module of the provided name. - * - * @param name The module name - * @return the module or null if the module doesn't exist. - */ @Override - public Module getModule(String name) { - Module module = pool.getModule(name); - if (module != null) { - module = new LastModule(module); - } - return module; + public Optional<LinkModule> findModule(String name) { + Optional<LinkModule> module = pool.findModule(name); + return module.isPresent()? Optional.of(new LastModule(module.get())) : Optional.empty(); } /** @@ -378,45 +364,55 @@ public final class ImagePluginStack { * @return The collection of modules. */ @Override - public Collection<Module> getModules() { - List<Module> modules = new ArrayList<>(); - for (Module m : pool.getModules()) { + public Stream<? extends LinkModule> modules() { + List<LinkModule> modules = new ArrayList<>(); + pool.modules().forEach(m -> { modules.add(new LastModule(m)); - } - return modules; + }); + return modules.stream(); + } + + @Override + public int getModuleCount() { + return pool.getModuleCount(); } /** * Get all resources contained in this pool instance. * - * @return The collection of resources; + * @return The stream of resources; */ @Override - public Collection<ModuleData> getContent() { + public Stream<? extends ModuleEntry> entries() { if (content == null) { content = new ArrayList<>(); - for (ModuleData md : pool.getContent()) { + pool.entries().forEach(md -> { content.add(getUncompressed(md)); - } + }); } - return content; + return content.stream(); + } + + @Override + public int getEntryCount() { + return pool.getEntryCount(); } /** * Get the resource for the passed path. * * @param path A resource path - * @return A Resource instance or null if the resource is not found + * @return A Resource instance if the resource is found */ @Override - public ModuleData get(String path) { + public Optional<ModuleEntry> findEntry(String path) { Objects.requireNonNull(path); - Pool.ModuleData res = pool.get(path); - return getUncompressed(res); + Optional<ModuleEntry> res = pool.findEntry(path); + return res.isPresent()? Optional.of(getUncompressed(res.get())) : Optional.empty(); } @Override - public boolean contains(ModuleData res) { + public boolean contains(ModuleEntry res) { return pool.contains(res); } @@ -426,8 +422,8 @@ public final class ImagePluginStack { } @Override - public void visit(Visitor visitor, Pool output) { - pool.visit(visitor, output); + public void transformAndCopy(Function<ModuleEntry, ModuleEntry> visitor, ModulePool output) { + pool.transformAndCopy(visitor, output); } @Override @@ -435,14 +431,19 @@ public final class ImagePluginStack { return pool.getByteOrder(); } - private ModuleData getUncompressed(ModuleData res) { + @Override + public Map<String, String> getReleaseProperties() { + return Collections.unmodifiableMap(pool.getReleaseProperties()); + } + + private ModuleEntry getUncompressed(ModuleEntry res) { if (res != null) { - if (res instanceof PoolImpl.CompressedModuleData) { + if (res instanceof ModulePoolImpl.CompressedModuleData) { try { byte[] bytes = decompressor.decompressResource(getByteOrder(), (int offset) -> pool.getStringTable().getString(offset), res.getBytes()); - res = Pool.newResource(res.getPath(), + res = ModuleEntry.create(res.getPath(), new ByteArrayInputStream(bytes), bytes.length); } catch (IOException ex) { @@ -462,20 +463,24 @@ public final class ImagePluginStack { * @param writer * @throws java.lang.Exception */ - public void storeFiles(PoolImpl original, PoolImpl transformed, + public void storeFiles(ModulePoolImpl original, ModulePoolImpl transformed, BasicImageWriter writer) throws Exception { Objects.requireNonNull(original); - try { - // fill release information available from transformed "java.base" module! - ModuleDescriptor desc = transformed.getModule("java.base").getDescriptor(); - desc.osName().ifPresent(s -> release.put("OS_NAME", s)); - desc.osVersion().ifPresent(s -> release.put("OS_VERSION", s)); - desc.osArch().ifPresent(s -> release.put("OS_ARCH", s)); - } catch (Exception ignored) { - } + Objects.requireNonNull(transformed); + Optional<LinkModule> javaBase = transformed.findModule("java.base"); + javaBase.ifPresent(mod -> { + try { + Map<String, String> release = transformed.getReleaseProperties(); + // fill release information available from transformed "java.base" module! + ModuleDescriptor desc = mod.getDescriptor(); + desc.osName().ifPresent(s -> release.put("OS_NAME", s)); + desc.osVersion().ifPresent(s -> release.put("OS_VERSION", s)); + desc.osArch().ifPresent(s -> release.put("OS_ARCH", s)); + } catch (Exception ignored) {} + }); - imageBuilder.storeFiles(new LastPool(transformed), release); + imageBuilder.storeFiles(new LastPool(transformed)); } public ExecutableImage getExecutableImage() throws IOException { diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModuleEntryImpl.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModuleEntryImpl.java new file mode 100644 index 00000000000..30c07a3b2d7 --- /dev/null +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModuleEntryImpl.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2016, 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.tools.jlink.internal; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UncheckedIOException; +import java.util.Objects; +import jdk.tools.jlink.plugin.ModuleEntry; + +/** + * A LinkModuleEntry is the elementary unit of data inside an image. It is + * generally a file. e.g.: a java class file, a resource file, a shared library, + * ... + * <br> + * A LinkModuleEntry is identified by a path of the form: + * <ul> + * <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file + * name}</li> + * <li>For other files (shared lib, launchers, config, ...):/{module name}/ + * {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li> + * </ul> + */ +public class ModuleEntryImpl implements ModuleEntry { + + private final Type type; + private final String path; + private final String module; + private final long length; + private final InputStream stream; + private byte[] buffer; + + /** + * Create a new LinkModuleEntry. + * + * @param module The module name. + * @param path The data path identifier. + * @param type The data type. + * @param stream The data content stream. + * @param length The stream length. + */ + public ModuleEntryImpl(String module, String path, Type type, InputStream stream, long length) { + Objects.requireNonNull(module); + Objects.requireNonNull(path); + Objects.requireNonNull(type); + Objects.requireNonNull(stream); + this.path = path; + this.type = type; + this.module = module; + this.stream = stream; + this.length = length; + } + + /** + * The LinkModuleEntry module name. + * + * @return The module name. + */ + @Override + public final String getModule() { + return module; + } + + /** + * The LinkModuleEntry path. + * + * @return The module path. + */ + @Override + public final String getPath() { + return path; + } + + /** + * The LinkModuleEntry's type. + * + * @return The data type. + */ + @Override + public final Type getType() { + return type; + } + + /** + * The LinkModuleEntry content as an array of byte. + * + * @return An Array of bytes. + */ + @Override + public byte[] getBytes() { + if (buffer == null) { + try (InputStream is = stream) { + buffer = is.readAllBytes(); + } catch (IOException ex) { + throw new UncheckedIOException(ex); + } + } + return buffer; + } + + /** + * The LinkModuleEntry content length. + * + * @return The length. + */ + @Override + public long getLength() { + return length; + } + + /** + * The LinkModuleEntry stream. + * + * @return The module data stream. + */ + @Override + public InputStream stream() { + return stream; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + Objects.hashCode(this.path); + return hash; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof ModuleEntryImpl)) { + return false; + } + ModuleEntryImpl f = (ModuleEntryImpl) other; + return f.path.equals(path); + } + + @Override + public String toString() { + return getPath(); + } +} \ No newline at end of file diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModulePoolImpl.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModulePoolImpl.java new file mode 100644 index 00000000000..a572fa48637 --- /dev/null +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ModulePoolImpl.java @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2015, 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.tools.jlink.internal; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.lang.module.ModuleDescriptor; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Stream; +import jdk.internal.jimage.decompressor.CompressedResourceHeader; +import jdk.tools.jlink.plugin.ModulePool; +import jdk.tools.jlink.plugin.LinkModule; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.PluginException; +import jdk.tools.jlink.internal.plugins.FileCopierPlugin; + +/** + * Pool of module data. + */ +public class ModulePoolImpl implements ModulePool { + + private class ModuleImpl implements LinkModule { + + final Map<String, ModuleEntry> moduleContent = new LinkedHashMap<>(); + private ModuleDescriptor descriptor; + final String name; + + private ModuleImpl(String name) { + this.name = name; + } + + @Override + public String getName() { + return name; + } + + @Override + public Optional<ModuleEntry> findEntry(String path) { + if (!path.startsWith("/")) { + path = "/" + path; + } + if (!path.startsWith("/" + name)) { + path = "/" + name + path; + } + return Optional.ofNullable(moduleContent.get(path)); + } + + @Override + public ModuleDescriptor getDescriptor() { + if (descriptor == null) { + String p = "/" + name + "/module-info.class"; + Optional<ModuleEntry> content = findEntry(p); + if (!content.isPresent()) { + throw new PluginException("No module-info for " + name + + " module"); + } + ByteBuffer bb = ByteBuffer.wrap(content.get().getBytes()); + descriptor = ModuleDescriptor.read(bb); + } + return descriptor; + } + + @Override + public void add(ModuleEntry data) { + if (isReadOnly()) { + throw new PluginException("LinkConfiguration is readonly"); + } + Objects.requireNonNull(data); + if (!data.getModule().equals(name)) { + throw new PluginException("Can't add resource " + data.getPath() + + " to module " + name); + } + ModulePoolImpl.this.add(data); + } + + @Override + public Set<String> getAllPackages() { + Set<String> pkgs = new HashSet<>(); + moduleContent.values().stream().filter(m -> m.getType(). + equals(ModuleEntry.Type.CLASS_OR_RESOURCE)).forEach(res -> { + // Module metadata only contains packages with .class files + if (ImageFileCreator.isClassPackage(res.getPath())) { + String[] split = ImageFileCreator.splitPath(res.getPath()); + String pkg = split[1]; + if (pkg != null && !pkg.isEmpty()) { + pkgs.add(pkg); + } + } + }); + return pkgs; + } + + @Override + public String toString() { + return getName(); + } + + @Override + public Stream<? extends ModuleEntry> entries() { + return moduleContent.values().stream(); + } + + @Override + public int getEntryCount() { + return moduleContent.values().size(); + } + } + + private final Map<String, ModuleEntry> resources = new LinkedHashMap<>(); + private final Map<String, ModuleImpl> modules = new LinkedHashMap<>(); + private final ModuleImpl fileCopierModule = new ModuleImpl(FileCopierPlugin.FAKE_MODULE); + private Map<String, String> releaseProps = new HashMap<>(); + + private final ByteOrder order; + + private boolean isReadOnly; + private final StringTable table; + + public ModulePoolImpl() { + this(ByteOrder.nativeOrder()); + } + + public ModulePoolImpl(ByteOrder order) { + this(order, new StringTable() { + + @Override + public int addString(String str) { + return -1; + } + + @Override + public String getString(int id) { + return null; + } + }); + } + + public ModulePoolImpl(ByteOrder order, StringTable table) { + this.order = order; + this.table = table; + } + + /** + * Add a ModuleEntry. + * + * @param data The ModuleEntry to add. + */ + @Override + public void add(ModuleEntry data) { + if (isReadOnly()) { + throw new PluginException("LinkConfiguration is readonly"); + } + Objects.requireNonNull(data); + if (resources.get(data.getPath()) != null) { + throw new PluginException("Resource " + data.getPath() + + " already present"); + } + String modulename = data.getModule(); + ModuleImpl m = modules.get(modulename); + // ## TODO: FileCopierPlugin should not add content to a module + // FAKE_MODULE is not really a module to be added in the image + if (FileCopierPlugin.FAKE_MODULE.equals(modulename)) { + m = fileCopierModule; + } + if (m == null) { + m = new ModuleImpl(modulename); + modules.put(modulename, m); + } + resources.put(data.getPath(), data); + m.moduleContent.put(data.getPath(), data); + } + + /** + * Retrieves the module for the provided name. + * + * @param name The module name + * @return the module of matching name, if found + */ + @Override + public Optional<LinkModule> findModule(String name) { + Objects.requireNonNull(name); + return Optional.ofNullable(modules.get(name)); + } + + /** + * The stream of modules contained in this LinkConfiguration. + * + * @return The stream of modules. + */ + @Override + public Stream<? extends LinkModule> modules() { + return modules.values().stream(); + } + + /** + * Return the number of LinkModule count in this LinkConfiguration. + * + * @return the module count. + */ + @Override + public int getModuleCount() { + return modules.size(); + } + + /** + * Get all ModuleEntry contained in this LinkConfiguration instance. + * + * @return The stream of LinkModuleEntries. + */ + @Override + public Stream<? extends ModuleEntry> entries() { + return resources.values().stream(); + } + + /** + * Return the number of ModuleEntry count in this LinkConfiguration. + * + * @return the entry count. + */ + @Override + public int getEntryCount() { + return resources.values().size(); + } + + /** + * Get the ModuleEntry for the passed path. + * + * @param path A data path + * @return A ModuleEntry instance or null if the data is not found + */ + @Override + public Optional<ModuleEntry> findEntry(String path) { + Objects.requireNonNull(path); + return Optional.ofNullable(resources.get(path)); + } + + /** + * Check if the LinkConfiguration contains the given ModuleEntry. + * + * @param data The module data to check existence for. + * @return The module data or null if not found. + */ + @Override + public boolean contains(ModuleEntry data) { + Objects.requireNonNull(data); + return findEntry(data.getPath()).isPresent(); + } + + /** + * Check if the LinkConfiguration contains some content at all. + * + * @return True, no content, false otherwise. + */ + @Override + public boolean isEmpty() { + return resources.isEmpty(); + } + + /** + * Visit each ModuleEntry in this LinkConfiguration to transform it and + * copy the transformed ModuleEntry to the output LinkConfiguration. + * + * @param transform The function called for each ModuleEntry found in + * the LinkConfiguration. The transform function should return a + * ModuleEntry instance which will be added to the output or it should + * return null if the passed ModuleEntry is to be ignored for the + * output. + * + * @param output The LinkConfiguration to be filled with Visitor returned + * ModuleEntry. + */ + @Override + public void transformAndCopy(Function<ModuleEntry, ModuleEntry> transform, + ModulePool output) { + entries().forEach(resource -> { + ModuleEntry res = transform.apply(resource); + if (res != null) { + output.add(res); + } + }); + } + + /** + * The ByteOrder currently in use when generating the jimage file. + * + * @return The ByteOrder. + */ + @Override + public ByteOrder getByteOrder() { + return order; + } + + @Override + public Map<String, String> getReleaseProperties() { + return isReadOnly()? Collections.unmodifiableMap(releaseProps) : releaseProps; + } + + public StringTable getStringTable() { + return table; + } + + /** + * Make this Resources instance read-only. No resource can be added. + */ + public void setReadOnly() { + isReadOnly = true; + } + + /** + * Read only state. + * + * @return true if readonly false otherwise. + */ + @Override + public boolean isReadOnly() { + return isReadOnly; + } + + /** + * A resource that has been compressed. + */ + public static final class CompressedModuleData extends ModuleEntryImpl { + + final long uncompressed_size; + + private CompressedModuleData(String module, String path, + InputStream stream, long size, + long uncompressed_size) { + super(module, path, ModuleEntry.Type.CLASS_OR_RESOURCE, stream, size); + this.uncompressed_size = uncompressed_size; + } + + public long getUncompressedSize() { + return uncompressed_size; + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof CompressedModuleData)) { + return false; + } + CompressedModuleData f = (CompressedModuleData) other; + return f.getPath().equals(getPath()); + } + + @Override + public int hashCode() { + return super.hashCode(); + } + } + + public static CompressedModuleData newCompressedResource(ModuleEntry original, + ByteBuffer compressed, + String plugin, String pluginConfig, StringTable strings, + ByteOrder order) { + Objects.requireNonNull(original); + Objects.requireNonNull(compressed); + Objects.requireNonNull(plugin); + + boolean isTerminal = !(original instanceof CompressedModuleData); + long uncompressed_size = original.getLength(); + if (original instanceof CompressedModuleData) { + CompressedModuleData comp = (CompressedModuleData) original; + uncompressed_size = comp.getUncompressedSize(); + } + int nameOffset = strings.addString(plugin); + int configOffset = -1; + if (pluginConfig != null) { + configOffset = strings.addString(plugin); + } + CompressedResourceHeader rh + = new CompressedResourceHeader(compressed.limit(), original.getLength(), + nameOffset, configOffset, isTerminal); + // Merge header with content; + byte[] h = rh.getBytes(order); + ByteBuffer bb = ByteBuffer.allocate(compressed.limit() + h.length); + bb.order(order); + bb.put(h); + bb.put(compressed); + byte[] contentWithHeader = bb.array(); + + CompressedModuleData compressedResource + = new CompressedModuleData(original.getModule(), original.getPath(), + new ByteArrayInputStream(contentWithHeader), + contentWithHeader.length, uncompressed_size); + return compressedResource; + } + +} diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PoolImpl.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PoolImpl.java deleted file mode 100644 index 2b1dd827bae..00000000000 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PoolImpl.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (c) 2015, 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.tools.jlink.internal; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Objects; -import jdk.internal.jimage.decompressor.CompressedResourceHeader; -import jdk.tools.jlink.plugin.Pool; - -/** - * Pool of module data. - */ -public class PoolImpl extends Pool { - - /** - * A resource that has been compressed. - */ - public static final class CompressedModuleData extends ModuleData { - - private final long uncompressed_size; - - private CompressedModuleData(String module, String path, - InputStream stream, long size, - long uncompressed_size) { - super(module, path, ModuleDataType.CLASS_OR_RESOURCE, stream, size); - this.uncompressed_size = uncompressed_size; - } - - public long getUncompressedSize() { - return uncompressed_size; - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof CompressedModuleData)) { - return false; - } - CompressedModuleData f = (CompressedModuleData) other; - return f.getPath().equals(getPath()); - } - - @Override - public int hashCode() { - return super.hashCode(); - } - } - - private boolean isReadOnly; - private final StringTable table; - - public PoolImpl() { - this(ByteOrder.nativeOrder(), new StringTable() { - - @Override - public int addString(String str) { - return -1; - } - @Override - public String getString(int id) { - return null; - } - }); - } - - public PoolImpl(ByteOrder order) { - this(order, new StringTable() { - - @Override - public int addString(String str) { - return -1; - } - @Override - public String getString(int id) { - return null; - } - }); - } - - public PoolImpl(ByteOrder order, StringTable table) { - super(order); - this.table = table; - } - - public StringTable getStringTable() { - return table; - } - - /** - * Make this Resources instance read-only. No resource can be added. - */ - public void setReadOnly() { - isReadOnly = true; - } - - /** - * Read only state. - * - * @return true if readonly false otherwise. - */ - @Override - public boolean isReadOnly() { - return isReadOnly; - } - - public static CompressedModuleData newCompressedResource(ModuleData original, - ByteBuffer compressed, - String plugin, String pluginConfig, StringTable strings, - ByteOrder order) { - Objects.requireNonNull(original); - Objects.requireNonNull(compressed); - Objects.requireNonNull(plugin); - - boolean isTerminal = !(original instanceof CompressedModuleData); - long uncompressed_size = original.getLength(); - if (original instanceof CompressedModuleData) { - CompressedModuleData comp = (CompressedModuleData) original; - uncompressed_size = comp.getUncompressedSize(); - } - int nameOffset = strings.addString(plugin); - int configOffset = -1; - if (pluginConfig != null) { - configOffset = strings.addString(plugin); - } - CompressedResourceHeader rh - = new CompressedResourceHeader(compressed.limit(), original.getLength(), - nameOffset, configOffset, isTerminal); - // Merge header with content; - byte[] h = rh.getBytes(order); - ByteBuffer bb = ByteBuffer.allocate(compressed.limit() + h.length); - bb.order(order); - bb.put(h); - bb.put(compressed); - byte[] contentWithHeader = bb.array(); - - CompressedModuleData compressedResource - = new CompressedModuleData(original.getModule(), original.getPath(), - new ByteArrayInputStream(contentWithHeader), - contentWithHeader.length, uncompressed_size); - return compressedResource; - } - -} diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePrevisitor.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePrevisitor.java index d9c5bab9a61..c8b8bc79ed6 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePrevisitor.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePrevisitor.java @@ -24,7 +24,7 @@ */ package jdk.tools.jlink.internal; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModulePool; /** * Plugin wishing to pre-visit the resources must implement this interface. @@ -44,5 +44,5 @@ public interface ResourcePrevisitor { * usage. * @throws PluginException */ - public void previsit(Pool resources, StringTable strings); + public void previsit(ModulePool resources, StringTable strings); } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java index 31064ab79d6..b255312bbf4 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java @@ -52,7 +52,7 @@ import jdk.internal.module.ConfigurableModuleFinder.Phase; import jdk.tools.jlink.Jlink; import jdk.tools.jlink.Jlink.PluginsConfiguration; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.Plugin.CATEGORY; +import jdk.tools.jlink.plugin.Plugin.Category; import jdk.tools.jlink.builder.DefaultImageBuilder; import jdk.tools.jlink.builder.ImageBuilder; import jdk.tools.jlink.plugin.PluginException; @@ -346,7 +346,6 @@ public final class TaskHelper { } } - PluginContextImpl pluginContext = new PluginContextImpl(); List<Plugin> pluginsList = new ArrayList<>(); for (Entry<Plugin, List<Map<String, String>>> entry : pluginToMaps.entrySet()) { Plugin plugin = entry.getKey(); @@ -356,7 +355,7 @@ public final class TaskHelper { // we call configure once for each occurrence. It is upto the plugin // to 'merge' and/or 'override' arguments. for (Map<String, String> map : argsMaps) { - plugin.configure(Collections.unmodifiableMap(map), pluginContext); + plugin.configure(Collections.unmodifiableMap(map)); } if (!Utils.isDisabled(plugin)) { @@ -371,7 +370,7 @@ public final class TaskHelper { } return new Jlink.PluginsConfiguration(pluginsList, - builder, lastSorter, pluginContext); + builder, lastSorter); } } @@ -594,7 +593,7 @@ public final class TaskHelper { + ": " + plugin.getClass().getName()); log.println(bundleHelper.getMessage("main.plugin.module") + ": " + plugin.getClass().getModule().getName()); - CATEGORY category = Utils.getCategory(plugin); + Category category = Utils.getCategory(plugin); log.println(bundleHelper.getMessage("main.plugin.category") + ": " + category.getName()); log.println(bundleHelper.getMessage("main.plugin.state") diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java index a8a9a45a5f4..0e29969a034 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Utils.java @@ -30,7 +30,6 @@ import java.util.Comparator; import java.util.List; import java.util.function.Function; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.Plugin.PluginType; public class Utils { @@ -50,25 +49,26 @@ public class Utils { return arguments; }; - public static boolean isPostProcessor(Plugin.CATEGORY category) { - return category.equals(Plugin.CATEGORY.VERIFIER) - || category.equals(Plugin.CATEGORY.PROCESSOR) - || category.equals(Plugin.CATEGORY.PACKAGER); + public static boolean isPostProcessor(Plugin.Category category) { + return category.equals(Plugin.Category.VERIFIER) + || category.equals(Plugin.Category.PROCESSOR) + || category.equals(Plugin.Category.PACKAGER); } - public static boolean isPreProcessor(Plugin.CATEGORY category) { - return category.equals(Plugin.CATEGORY.COMPRESSOR) - || category.equals(Plugin.CATEGORY.FILTER) - || category.equals(Plugin.CATEGORY.MODULEINFO_TRANSFORMER) - || category.equals(Plugin.CATEGORY.SORTER) - || category.equals(Plugin.CATEGORY.TRANSFORMER); + public static boolean isPreProcessor(Plugin.Category category) { + return category.equals(Plugin.Category.COMPRESSOR) + || category.equals(Plugin.Category.FILTER) + || category.equals(Plugin.Category.MODULEINFO_TRANSFORMER) + || category.equals(Plugin.Category.SORTER) + || category.equals(Plugin.Category.TRANSFORMER) + || category.equals(Plugin.Category.METAINFO_ADDER); } public static boolean isPostProcessor(Plugin prov) { if (prov.getType() != null) { - for (PluginType pt : prov.getType()) { - if (pt instanceof Plugin.CATEGORY) { - return isPostProcessor((Plugin.CATEGORY) pt); + for (Plugin.Category pt : prov.getType()) { + if (pt instanceof Plugin.Category) { + return isPostProcessor(pt); } } } @@ -77,20 +77,20 @@ public class Utils { public static boolean isPreProcessor(Plugin prov) { if (prov.getType() != null) { - for (PluginType pt : prov.getType()) { - if (pt instanceof Plugin.CATEGORY) { - return isPreProcessor((Plugin.CATEGORY) pt); + for (Plugin.Category pt : prov.getType()) { + if (pt instanceof Plugin.Category) { + return isPreProcessor(pt); } } } return false; } - public static Plugin.CATEGORY getCategory(Plugin provider) { + public static Plugin.Category getCategory(Plugin provider) { if (provider.getType() != null) { - for (Plugin.PluginType t : provider.getType()) { - if (t instanceof Plugin.CATEGORY) { - return (Plugin.CATEGORY) t; + for (Plugin.Category t : provider.getType()) { + if (t instanceof Plugin.Category) { + return t; } } } @@ -140,15 +140,15 @@ public class Utils { } public static boolean isFunctional(Plugin prov) { - return prov.getState().contains(Plugin.STATE.FUNCTIONAL); + return prov.getState().contains(Plugin.State.FUNCTIONAL); } public static boolean isAutoEnabled(Plugin prov) { - return prov.getState().contains(Plugin.STATE.AUTO_ENABLED); + return prov.getState().contains(Plugin.State.AUTO_ENABLED); } public static boolean isDisabled(Plugin prov) { - return prov.getState().contains(Plugin.STATE.DISABLED); + return prov.getState().contains(Plugin.State.DISABLED); } // is this a builtin (jdk.jlink) plugin? diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java index e448acd0b1d..874b338c93f 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java @@ -30,7 +30,7 @@ import jdk.tools.jlink.Jlink; import jdk.tools.jlink.builder.ImageBuilder; import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.builder.*; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModulePool; import java.io.ByteArrayOutputStream; import java.io.File; diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java index aa068f1136e..43eb6f27dec 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/DefaultCompressPlugin.java @@ -26,16 +26,13 @@ package jdk.tools.jlink.internal.plugins; import java.io.IOException; import java.io.UncheckedIOException; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Map; import java.util.Set; -import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.internal.PoolImpl; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.internal.ModulePoolImpl; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; import jdk.tools.jlink.internal.ImagePluginStack; import jdk.tools.jlink.internal.ResourcePrevisitor; @@ -62,10 +59,10 @@ public final class DefaultCompressPlugin implements TransformerPlugin, ResourceP } @Override - public void visit(Pool in, Pool out) { + public void visit(ModulePool in, ModulePool out) { if (ss != null && zip != null) { - Pool output = new ImagePluginStack.OrderedResourcePool(in.getByteOrder(), - ((PoolImpl) in).getStringTable()); + ModulePool output = new ImagePluginStack.OrderedResourcePool(in.getByteOrder(), + ((ModulePoolImpl) in).getStringTable()); ss.visit(in, output); zip.visit(output, out); } else if (ss != null) { @@ -76,16 +73,16 @@ public final class DefaultCompressPlugin implements TransformerPlugin, ResourceP } @Override - public void previsit(Pool resources, StringTable strings) { + public void previsit(ModulePool resources, StringTable strings) { if (ss != null) { ss.previsit(resources, strings); } } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.COMPRESSOR); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.COMPRESSOR); return Collections.unmodifiableSet(set); } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java index 0271670e4c1..628d8f6346e 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeFilesPlugin.java @@ -32,8 +32,8 @@ import java.util.Map; import java.util.Set; import java.util.function.Predicate; import jdk.tools.jlink.plugin.TransformerPlugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.plugin.ModulePool; +import jdk.tools.jlink.plugin.ModuleEntry; import jdk.tools.jlink.internal.Utils; /** @@ -51,9 +51,9 @@ public final class ExcludeFilesPlugin implements TransformerPlugin { } @Override - public void visit(Pool in, Pool out) { - in.visit((file) -> { - if (!file.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) { + public void visit(ModulePool in, ModulePool out) { + in.transformAndCopy((file) -> { + if (!file.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) { file = predicate.test(file.getPath()) ? file : null; } return file; @@ -61,9 +61,9 @@ public final class ExcludeFilesPlugin implements TransformerPlugin { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.FILTER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.FILTER); return Collections.unmodifiableSet(set); } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java index 6d4737a4661..626087b76be 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludePlugin.java @@ -32,7 +32,8 @@ import java.util.Set; import java.util.function.Predicate; import jdk.tools.jlink.plugin.PluginException; import jdk.tools.jlink.plugin.TransformerPlugin; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.internal.Utils; /** @@ -50,9 +51,9 @@ public final class ExcludePlugin implements TransformerPlugin { } @Override - public void visit(Pool in, Pool out) { - in.visit((resource) -> { - if (resource.getType().equals(Pool.ModuleDataType.CLASS_OR_RESOURCE)) { + public void visit(ModulePool in, ModulePool out) { + in.transformAndCopy((resource) -> { + if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) { resource = predicate.test(resource.getPath()) ? resource : null; } return resource; @@ -75,9 +76,9 @@ public final class ExcludePlugin implements TransformerPlugin { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.FILTER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.FILTER); return Collections.unmodifiableSet(set); } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java index 4d502904c37..753d63e5cfc 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java @@ -40,9 +40,10 @@ import java.util.TreeSet; import java.util.function.Predicate; import java.util.stream.Collectors; import jdk.tools.jlink.plugin.TransformerPlugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.internal.Utils; +import jdk.tools.jlink.plugin.ModuleEntry; import jdk.tools.jlink.plugin.PluginException; /** @@ -102,24 +103,24 @@ public final class ExcludeVMPlugin implements TransformerPlugin { * e.g.: /java.base/native/amd64/server/libjvm.so * /java.base/native/server/libjvm.dylib */ - private List<Pool.ModuleData> getVMs(Pool in) { + private List<ModuleEntry> getVMs(ModulePool in) { String jvmlib = jvmlib(); - List<Pool.ModuleData> ret = in.getModule("java.base").getContent().stream().filter((t) -> { + List<ModuleEntry> ret = in.findModule("java.base").get().entries().filter((t) -> { return t.getPath().endsWith("/" + jvmlib); }).collect(Collectors.toList()); return ret; } @Override - public void visit(Pool in, Pool out) { + public void visit(ModulePool in, ModulePool out) { String jvmlib = jvmlib(); TreeSet<Jvm> existing = new TreeSet<>(new JvmComparator()); TreeSet<Jvm> removed = new TreeSet<>(new JvmComparator()); if (!keepAll) { // First retrieve all available VM names and removed VM - List<Pool.ModuleData> jvms = getVMs(in); + List<ModuleEntry> jvms = getVMs(in); for (Jvm jvm : Jvm.values()) { - for (Pool.ModuleData md : jvms) { + for (ModuleEntry md : jvms) { if (md.getPath().endsWith("/" + jvm.getName() + "/" + jvmlib)) { existing.add(jvm); if (isRemoved(md)) { @@ -137,9 +138,9 @@ public final class ExcludeVMPlugin implements TransformerPlugin { } // Rewrite the jvm.cfg file. - in.visit((file) -> { + in.transformAndCopy((file) -> { if (!keepAll) { - if (file.getType().equals(ModuleDataType.NATIVE_LIB)) { + if (file.getType().equals(ModuleEntry.Type.NATIVE_LIB)) { if (file.getPath().endsWith(JVM_CFG)) { try { file = handleJvmCfgFile(file, existing, removed); @@ -155,14 +156,14 @@ public final class ExcludeVMPlugin implements TransformerPlugin { } - private boolean isRemoved(Pool.ModuleData file) { + private boolean isRemoved(ModuleEntry file) { return !predicate.test(file.getPath()); } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.FILTER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.FILTER); return Collections.unmodifiableSet(set); } @@ -217,7 +218,7 @@ public final class ExcludeVMPlugin implements TransformerPlugin { } } - private Pool.ModuleData handleJvmCfgFile(Pool.ModuleData orig, + private ModuleEntry handleJvmCfgFile(ModuleEntry orig, TreeSet<Jvm> existing, TreeSet<Jvm> removed) throws IOException { if (keepAll) { @@ -253,7 +254,7 @@ public final class ExcludeVMPlugin implements TransformerPlugin { byte[] content = builder.toString().getBytes(StandardCharsets.UTF_8); - return Pool.newImageFile(orig.getModule(), + return ModuleEntry.create(orig.getModule(), orig.getPath(), orig.getType(), new ByteArrayInputStream(content), content.length); diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java index 7a51d6cbcdf..497d97e50a6 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/FileCopierPlugin.java @@ -41,10 +41,10 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; +import jdk.tools.jlink.internal.ModuleEntryImpl; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; import jdk.tools.jlink.internal.Utils; @@ -68,12 +68,12 @@ public class FileCopierPlugin implements TransformerPlugin { /** * Symbolic link to another path. */ - public static abstract class SymImageFile extends Pool.ModuleData { + public static abstract class SymImageFile extends ModuleEntryImpl { private final String targetPath; public SymImageFile(String targetPath, String module, String path, - Pool.ModuleDataType type, InputStream stream, long size) { + ModuleEntry.Type type, InputStream stream, long size) { super(module, path, type, stream, size); this.targetPath = targetPath; } @@ -86,7 +86,7 @@ public class FileCopierPlugin implements TransformerPlugin { private static final class SymImageFileImpl extends SymImageFile { public SymImageFileImpl(String targetPath, Path file, String module, - String path, ModuleDataType type) { + String path, ModuleEntry.Type type) { super(targetPath, module, path, type, newStream(file), length(file)); } } @@ -110,11 +110,11 @@ public class FileCopierPlugin implements TransformerPlugin { private static final class DirectoryCopy implements FileVisitor<Path> { private final Path source; - private final Pool pool; + private final ModulePool pool; private final String targetDir; private final List<SymImageFile> symlinks = new ArrayList<>(); - DirectoryCopy(Path source, Pool pool, String targetDir) { + DirectoryCopy(Path source, ModulePool pool, String targetDir) { this.source = source; this.pool = pool; this.targetDir = targetDir; @@ -148,7 +148,7 @@ public class FileCopierPlugin implements TransformerPlugin { } SymImageFileImpl impl = new SymImageFileImpl(symTarget.toString(), file, path, Objects.requireNonNull(file.getFileName()).toString(), - Pool.ModuleDataType.OTHER); + ModuleEntry.Type.OTHER); symlinks.add(impl); } else { addFile(pool, file, path); @@ -172,14 +172,14 @@ public class FileCopierPlugin implements TransformerPlugin { } } - private static void addFile(Pool pool, Path file, String path) + private static void addFile(ModulePool pool, Path file, String path) throws IOException { Objects.requireNonNull(pool); Objects.requireNonNull(file); Objects.requireNonNull(path); - ModuleData impl = Pool.newImageFile(FAKE_MODULE, + ModuleEntry impl = ModuleEntry.create(FAKE_MODULE, "/" + FAKE_MODULE + "/other/" + path, - Pool.ModuleDataType.OTHER, newStream(file), length(file)); + ModuleEntry.Type.OTHER, newStream(file), length(file)); try { pool.add(impl); } catch (Exception ex) { @@ -188,9 +188,9 @@ public class FileCopierPlugin implements TransformerPlugin { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.TRANSFORMER); return Collections.unmodifiableSet(set); } @@ -239,8 +239,8 @@ public class FileCopierPlugin implements TransformerPlugin { } @Override - public void visit(Pool in, Pool out) { - in.visit((file) -> { + public void visit(ModulePool in, ModulePool out) { + in.transformAndCopy((file) -> { return file; }, out); diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java index d2b2995bdda..9e0805ec361 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/GenerateJLIClassesPlugin.java @@ -33,8 +33,9 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; +import jdk.tools.jlink.plugin.ModuleEntry; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; /** @@ -60,8 +61,8 @@ public final class GenerateJLIClassesPlugin implements TransformerPlugin { } @Override - public Set<PluginType> getType() { - return Collections.singleton(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + return Collections.singleton(Category.TRANSFORMER); } @Override @@ -75,8 +76,8 @@ public final class GenerateJLIClassesPlugin implements TransformerPlugin { } @Override - public Set<STATE> getState() { - return EnumSet.of(STATE.AUTO_ENABLED, STATE.FUNCTIONAL); + public Set<State> getState() { + return EnumSet.of(State.AUTO_ENABLED, State.FUNCTIONAL); } @Override @@ -151,8 +152,8 @@ public final class GenerateJLIClassesPlugin implements TransformerPlugin { } @Override - public void visit(Pool in, Pool out) { - for (Pool.ModuleData data : in.getContent()) { + public void visit(ModulePool in, ModulePool out) { + in.entries().forEach(data -> { if (("/java.base/" + BMH + ".class").equals(data.getPath())) { // Add BoundMethodHandle unchanged out.add(data); @@ -162,11 +163,11 @@ public final class GenerateJLIClassesPlugin implements TransformerPlugin { out.add(data); } } - } + }); } @SuppressWarnings("unchecked") - private void generateConcreteClass(String types, Pool.ModuleData data, Pool out) { + private void generateConcreteClass(String types, ModuleEntry data, ModulePool out) { try { // Generate class Map.Entry<String, byte[]> result = (Map.Entry<String, byte[]>) @@ -175,9 +176,9 @@ public final class GenerateJLIClassesPlugin implements TransformerPlugin { byte[] bytes = result.getValue(); // Add class to pool - Pool.ModuleData ndata = new Pool.ModuleData(data.getModule(), + ModuleEntry ndata = ModuleEntry.create(data.getModule(), "/java.base/" + className + ".class", - Pool.ModuleDataType.CLASS_OR_RESOURCE, + ModuleEntry.Type.CLASS_OR_RESOURCE, new ByteArrayInputStream(bytes), bytes.length); if (!out.contains(ndata)) { out.add(ndata); diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java index b8b7aa46cc1..3083c19d2ba 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/IncludeLocalesPlugin.java @@ -34,6 +34,7 @@ import java.util.IllformedLocaleException; import java.util.Locale; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.function.Predicate; import java.util.regex.Pattern; @@ -44,9 +45,10 @@ import jdk.internal.org.objectweb.asm.ClassReader; import jdk.tools.jlink.internal.ResourcePrevisitor; import jdk.tools.jlink.internal.StringTable; import jdk.tools.jlink.internal.Utils; +import jdk.tools.jlink.plugin.LinkModule; +import jdk.tools.jlink.plugin.ModuleEntry; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; /** @@ -112,19 +114,19 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr } @Override - public void visit(Pool in, Pool out) { - in.visit((resource) -> { + public void visit(ModulePool in, ModulePool out) { + in.transformAndCopy((resource) -> { if (resource.getModule().equals(MODULENAME)) { String path = resource.getPath(); resource = predicate.test(path) ? resource: null; if (resource != null && - resource.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) { + resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) { byte[] bytes = resource.getBytes(); ClassReader cr = new ClassReader(bytes); if (Arrays.stream(cr.getInterfaces()) .anyMatch(i -> i.contains(METAINFONAME)) && stripUnsupportedLocales(bytes, cr)) { - resource = new Pool.ModuleData(MODULENAME, path, + resource = ModuleEntry.create(MODULENAME, path, resource.getType(), new ByteArrayInputStream(bytes), bytes.length); } @@ -135,9 +137,9 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.FILTER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.FILTER); return Collections.unmodifiableSet(set); } @@ -172,12 +174,13 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr } @Override - public void previsit(Pool resources, StringTable strings) { + public void previsit(ModulePool resources, StringTable strings) { final Pattern p = Pattern.compile(".*((Data_)|(Names_))(?<tag>.*)\\.class"); - Pool.Module module = resources.getModule(MODULENAME); + Optional<LinkModule> optMod = resources.findModule(MODULENAME); // jdk.localedata module validation - if (module != null) { + if (optMod.isPresent()) { + LinkModule module = optMod.get(); Set<String> packages = module.getAllPackages(); if (!packages.containsAll(LOCALEDATA_PACKAGES)) { throw new PluginException(PluginsResourceBundle.getMessage(NAME + ".missingpackages") + @@ -186,7 +189,7 @@ public final class IncludeLocalesPlugin implements TransformerPlugin, ResourcePr .collect(Collectors.joining(",\n\t"))); } - available = Stream.concat(module.getContent().stream() + available = Stream.concat(module.entries() .map(md -> p.matcher(md.getPath())) .filter(m -> m.matches()) .map(m -> m.group("tag").replaceAll("_", "-")), diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OptimizationPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OptimizationPlugin.java index 4f8e5eade53..9632cdf9b95 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OptimizationPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OptimizationPlugin.java @@ -24,7 +24,6 @@ */ package jdk.tools.jlink.internal.plugins; -import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -287,9 +286,9 @@ public final class OptimizationPlugin extends AsmPlugin { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.TRANSFORMER); return Collections.unmodifiableSet(set); } } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java index 8fb124dd775..5060bf5c519 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/OrderResourcesPlugin.java @@ -36,9 +36,8 @@ import java.util.Map; import java.util.Set; import java.util.function.ToIntFunction; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; import jdk.tools.jlink.internal.Utils; @@ -62,15 +61,15 @@ public final class OrderResourcesPlugin implements TransformerPlugin { } static class SortWrapper { - private final ModuleData resource; + private final ModuleEntry resource; private final int ordinal; - SortWrapper(ModuleData resource, int ordinal) { + SortWrapper(ModuleEntry resource, int ordinal) { this.resource = resource; this.ordinal = ordinal; } - ModuleData getResource() { + ModuleEntry getResource() { return resource; } @@ -95,7 +94,7 @@ public final class OrderResourcesPlugin implements TransformerPlugin { return path; } - private int getOrdinal(ModuleData resource) { + private int getOrdinal(ModuleEntry resource) { String path = resource.getPath(); Integer value = orderedPaths.get(stripModule(path)); @@ -126,23 +125,23 @@ public final class OrderResourcesPlugin implements TransformerPlugin { } @Override - public void visit(Pool in, Pool out) { - in.getContent().stream() + public void visit(ModulePool in, ModulePool out) { + in.entries() .filter(resource -> resource.getType() - .equals(ModuleDataType.CLASS_OR_RESOURCE)) + .equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) .map((resource) -> new SortWrapper(resource, getOrdinal(resource))) .sorted(OrderResourcesPlugin::compare) .forEach((wrapper) -> out.add(wrapper.getResource())); - in.getContent().stream() + in.entries() .filter(other -> !other.getType() - .equals(ModuleDataType.CLASS_OR_RESOURCE)) + .equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) .forEach((other) -> out.add(other)); } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.SORTER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.SORTER); return Collections.unmodifiableSet(set); } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java index bbc7428a41e..579aace7e0a 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ReleaseInfoPlugin.java @@ -24,34 +24,33 @@ */ package jdk.tools.jlink.internal.plugins; -import java.lang.module.ModuleDescriptor; import java.io.FileInputStream; import java.io.IOException; import java.util.Collections; import java.util.EnumSet; -import java.util.List; +import java.util.HashMap; import java.util.Map; -import java.util.Set; import java.util.Properties; - +import java.util.Set; +import java.util.function.Function; import jdk.tools.jlink.internal.Utils; -import jdk.tools.jlink.plugin.ExecutableImage; -import jdk.tools.jlink.plugin.PluginContext; -import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.PostProcessorPlugin; +import jdk.tools.jlink.plugin.ModulePool; +import jdk.tools.jlink.plugin.Plugin.Category; +import jdk.tools.jlink.plugin.Plugin.State; +import jdk.tools.jlink.plugin.TransformerPlugin; /** * This plugin adds/deletes information for 'release' file. */ -public final class ReleaseInfoPlugin implements PostProcessorPlugin { +public final class ReleaseInfoPlugin implements TransformerPlugin { // option name public static final String NAME = "release-info"; public static final String KEYS = "keys"; + private final Map<String, String> release = new HashMap<>(); @Override - public Set<PluginType> getType() { - return Collections.singleton(CATEGORY.PROCESSOR); + public Set<Category> getType() { + return Collections.singleton(Category.METAINFO_ADDER); } @Override @@ -65,8 +64,8 @@ public final class ReleaseInfoPlugin implements PostProcessorPlugin { } @Override - public Set<STATE> getState() { - return EnumSet.of(STATE.FUNCTIONAL); + public Set<State> getState() { + return EnumSet.of(State.FUNCTIONAL); } @Override @@ -80,49 +79,49 @@ public final class ReleaseInfoPlugin implements PostProcessorPlugin { } @Override - public void configure(Map<String, String> config, PluginContext ctx) { - Properties release = ctx != null? ctx.getReleaseProperties() : null; - if (release != null) { - String operation = config.get(NAME); - switch (operation) { - case "add": { - // leave it to open-ended! source, java_version, java_full_version - // can be passed via this option like: - // - // --release-info add:build_type=fastdebug,source=openjdk,java_version=9 - // and put whatever value that was passed in command line. + public void configure(Map<String, String> config) { + String operation = config.get(NAME); + switch (operation) { + case "add": { + // leave it to open-ended! source, java_version, java_full_version + // can be passed via this option like: + // + // --release-info add:build_type=fastdebug,source=openjdk,java_version=9 + // and put whatever value that was passed in command line. - config.keySet().stream(). - filter(s -> !NAME.equals(s)). - forEach(s -> release.put(s, config.get(s))); - } - break; - - case "del": { - // --release-info del:keys=openjdk,java_version - String[] keys = Utils.listParser.apply(config.get(KEYS)); - for (String k : keys) { - release.remove(k); - } - } - break; - - default: { - // --release-info <file> - try (FileInputStream fis = new FileInputStream(operation)) { - release.load(fis); - } catch (IOException exp) { - throw new RuntimeException(exp); - } - } - break; + config.keySet().stream(). + filter(s -> !NAME.equals(s)). + forEach(s -> release.put(s, config.get(s))); } + break; + + case "del": { + // --release-info del:keys=openjdk,java_version + String[] keys = Utils.listParser.apply(config.get(KEYS)); + for (String k : keys) { + release.remove(k); + } + } + break; + + default: { + // --release-info <file> + Properties props = new Properties(); + try (FileInputStream fis = new FileInputStream(operation)) { + props.load(fis); + } catch (IOException exp) { + throw new RuntimeException(exp); + } + props.forEach((k, v) -> release.put(k.toString(), v.toString())); + } + break; } } @Override - public List<String> process(ExecutableImage image) { - // Nothing to do! Release info copied already during configure! - return Collections.emptyList(); + public void visit(ModulePool in, ModulePool out) { + in.transformAndCopy(Function.identity(), out); + out.getReleaseProperties().putAll(in.getReleaseProperties()); + out.getReleaseProperties().putAll(release); } } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java index a4aa8f9d5ca..b3a1e7cf3cf 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StringSharingPlugin.java @@ -56,11 +56,11 @@ import java.util.stream.Collectors; import jdk.internal.jimage.decompressor.CompressIndexes; import jdk.internal.jimage.decompressor.SignatureParser; import jdk.internal.jimage.decompressor.StringSharingDecompressor; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.plugin.TransformerPlugin; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.internal.ResourcePrevisitor; import jdk.tools.jlink.internal.StringTable; import jdk.tools.jlink.internal.Utils; @@ -228,7 +228,7 @@ public class StringSharingPlugin implements TransformerPlugin, ResourcePrevisito } } - public byte[] transform(ModuleData resource, Pool out, + public byte[] transform(ModuleEntry resource, ModulePool out, StringTable strings) throws IOException, Exception { byte[] content = resource.getBytes(); ClassFile cf; @@ -243,7 +243,7 @@ public class StringSharingPlugin implements TransformerPlugin, ResourcePrevisito } @SuppressWarnings("fallthrough") - private byte[] optimize(ModuleData resource, Pool resources, + private byte[] optimize(ModuleEntry resource, ModulePool resources, StringTable strings, Set<Integer> descriptorIndexes, byte[] content) throws Exception { DataInputStream stream = new DataInputStream(new ByteArrayInputStream(content)); @@ -348,27 +348,27 @@ public class StringSharingPlugin implements TransformerPlugin, ResourcePrevisito } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.COMPRESSOR); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.COMPRESSOR); return Collections.unmodifiableSet(set); } @Override - public void visit(Pool in, Pool result) { + public void visit(ModulePool in, ModulePool result) { CompactCPHelper visit = new CompactCPHelper(); - in.visit((resource) -> { - ModuleData res = resource; + in.transformAndCopy((resource) -> { + ModuleEntry res = resource; if (predicate.test(resource.getPath()) && resource.getPath().endsWith(".class")) { byte[] compressed = null; try { - compressed = visit.transform(resource, result, ((PoolImpl) in).getStringTable()); + compressed = visit.transform(resource, result, ((ModulePoolImpl) in).getStringTable()); } catch (Exception ex) { throw new PluginException(ex); } - res = PoolImpl.newCompressedResource(resource, + res = ModulePoolImpl.newCompressedResource(resource, ByteBuffer.wrap(compressed), getName(), null, - ((PoolImpl) in).getStringTable(), in.getByteOrder()); + ((ModulePoolImpl) in).getStringTable(), in.getByteOrder()); } return res; }, result); @@ -405,10 +405,10 @@ public class StringSharingPlugin implements TransformerPlugin, ResourcePrevisito } @Override - public void previsit(Pool resources, StringTable strings) { + public void previsit(ModulePool resources, StringTable strings) { CompactCPHelper preVisit = new CompactCPHelper(); - for (ModuleData resource : resources.getContent()) { - if (resource.getType().equals(Pool.ModuleDataType.CLASS_OR_RESOURCE) + resources.entries().forEach(resource -> { + if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE) && resource.getPath().endsWith(".class") && predicate.test(resource.getPath())) { try { preVisit.transform(resource, null, strings); @@ -416,6 +416,6 @@ public class StringSharingPlugin implements TransformerPlugin, ResourcePrevisito throw new PluginException(ex); } } - } + }); } } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java index ae927952226..4e7a036d838 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripDebugPlugin.java @@ -29,14 +29,12 @@ import java.io.IOException; import java.io.UncheckedIOException; import java.util.Collections; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.function.Predicate; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; /** @@ -61,9 +59,9 @@ public final class StripDebugPlugin implements TransformerPlugin { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.TRANSFORMER); return Collections.unmodifiableSet(set); } @@ -73,11 +71,11 @@ public final class StripDebugPlugin implements TransformerPlugin { } @Override - public void visit(Pool in, Pool out) { + public void visit(ModulePool in, ModulePool out) { //remove *.diz files as well as debug attributes. - in.visit((resource) -> { - ModuleData res = resource; - if (resource.getType().equals(ModuleDataType.CLASS_OR_RESOURCE)) { + in.transformAndCopy((resource) -> { + ModuleEntry res = resource; + if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) { String path = resource.getPath(); if (path.endsWith(".class")) { if (path.endsWith("module-info.class")) { @@ -87,7 +85,7 @@ public final class StripDebugPlugin implements TransformerPlugin { ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS); reader.accept(writer, ClassReader.SKIP_DEBUG); byte[] content = writer.toByteArray(); - res = Pool.newResource(path, new ByteArrayInputStream(content), content.length); + res = ModuleEntry.create(path, new ByteArrayInputStream(content), content.length); } } } else if (predicate.test(res.getPath())) { diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripNativeCommandsPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripNativeCommandsPlugin.java index dc64582be21..496a4e538d7 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripNativeCommandsPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/StripNativeCommandsPlugin.java @@ -26,9 +26,9 @@ package jdk.tools.jlink.internal.plugins; import java.util.Collections; import java.util.HashSet; -import java.util.Map; import java.util.Set; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; /** @@ -45,16 +45,16 @@ public final class StripNativeCommandsPlugin implements TransformerPlugin { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.FILTER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.FILTER); return Collections.unmodifiableSet(set); } @Override - public void visit(Pool in, Pool out) { - in.visit((file) -> { - return file.getType() == Pool.ModuleDataType.NATIVE_CMD ? null : file; + public void visit(ModulePool in, ModulePool out) { + in.transformAndCopy((file) -> { + return file.getType() == ModuleEntry.Type.NATIVE_CMD ? null : file; }, out); } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModuleDescriptorPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModuleDescriptorPlugin.java index f4cba7607ea..b60fecb5d16 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModuleDescriptorPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModuleDescriptorPlugin.java @@ -36,6 +36,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -50,9 +51,10 @@ import jdk.internal.org.objectweb.asm.Opcodes; import static jdk.internal.org.objectweb.asm.Opcodes.*; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; import jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin.Builder.*; +import jdk.tools.jlink.plugin.ModuleEntry; /** * Jlink plugin to reconstitute module descriptors for installed modules. @@ -81,8 +83,8 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin { } @Override - public Set<PluginType> getType() { - return Collections.singleton(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + return Collections.singleton(Category.TRANSFORMER); } @Override @@ -96,9 +98,9 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin { } @Override - public Set<STATE> getState() { - return enabled ? EnumSet.of(STATE.AUTO_ENABLED, STATE.FUNCTIONAL) - : EnumSet.of(STATE.DISABLED); + public Set<State> getState() { + return enabled ? EnumSet.of(State.AUTO_ENABLED, State.FUNCTIONAL) + : EnumSet.of(State.DISABLED); } @Override @@ -110,7 +112,7 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin { @Override - public void visit(Pool in, Pool out) { + public void visit(ModulePool in, ModulePool out) { if (!enabled) { throw new PluginException(NAME + " was set"); } @@ -119,13 +121,14 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin { // generate the byte code to create ModuleDescriptors // skip parsing module-info.class and skip name check - for (Pool.Module module : in.getModules()) { - Pool.ModuleData data = module.get("module-info.class"); - if (data == null) { + in.modules().forEach(module -> { + Optional<ModuleEntry> optData = module.findEntry("module-info.class"); + if (! optData.isPresent()) { // automatic module not supported yet throw new PluginException("module-info.class not found for " + module.getName() + " module"); } + ModuleEntry data = optData.get(); assert module.getName().equals(data.getModule()); try { ByteArrayInputStream bain = new ByteArrayInputStream(data.getBytes()); @@ -141,7 +144,7 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin { ModuleInfoRewriter minfoWriter = new ModuleInfoRewriter(bain, mbuilder.conceals()); // replace with the overridden version - data = new Pool.ModuleData(data.getModule(), + data = ModuleEntry.create(data.getModule(), data.getPath(), data.getType(), minfoWriter.stream(), @@ -151,19 +154,17 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin { } catch (IOException e) { throw new PluginException(e); } - - } + }); // Generate the new class ClassWriter cwriter = builder.build(); - for (Pool.ModuleData data : in.getContent()) { + in.entries().forEach(data -> { if (data.getPath().endsWith("module-info.class")) - continue; - + return; if (builder.isOverriddenClass(data.getPath())) { byte[] bytes = cwriter.toByteArray(); - Pool.ModuleData ndata = - new Pool.ModuleData(data.getModule(), + ModuleEntry ndata = + ModuleEntry.create(data.getModule(), data.getPath(), data.getType(), new ByteArrayInputStream(bytes), @@ -172,7 +173,7 @@ public final class SystemModuleDescriptorPlugin implements TransformerPlugin { } else { out.add(data); } - } + }); } /* diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java index df66e300f5c..d3dd7bff210 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ZipPlugin.java @@ -34,10 +34,9 @@ import java.util.Set; import java.util.function.Predicate; import java.util.zip.Deflater; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.internal.PoolImpl; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.internal.ModulePoolImpl; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; import jdk.tools.jlink.internal.Utils; @@ -68,9 +67,9 @@ public final class ZipPlugin implements TransformerPlugin { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.COMPRESSOR); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.COMPRESSOR); return Collections.unmodifiableSet(set); } @@ -124,16 +123,16 @@ public final class ZipPlugin implements TransformerPlugin { } @Override - public void visit(Pool in, Pool out) { - in.visit((resource) -> { - ModuleData res = resource; - if (resource.getType().equals(ModuleDataType.CLASS_OR_RESOURCE) + public void visit(ModulePool in, ModulePool out) { + in.transformAndCopy((resource) -> { + ModuleEntry res = resource; + if (resource.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE) && predicate.test(resource.getPath())) { byte[] compressed; compressed = compress(resource.getBytes()); - res = PoolImpl.newCompressedResource(resource, + res = ModulePoolImpl.newCompressedResource(resource, ByteBuffer.wrap(compressed), getName(), null, - ((PoolImpl) in).getStringTable(), in.getByteOrder()); + ((ModulePoolImpl) in).getStringTable(), in.getByteOrder()); } return res; }, out); diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPlugin.java index 9902959d059..52712172d5e 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPlugin.java @@ -26,9 +26,9 @@ package jdk.tools.jlink.internal.plugins.asm; import java.util.Objects; import jdk.tools.jlink.plugin.TransformerPlugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; +import jdk.tools.jlink.internal.ModulePoolImpl; /** * Extend this class to develop your own plugin in order to transform jimage @@ -41,17 +41,17 @@ public abstract class AsmPlugin implements TransformerPlugin { } @Override - public void visit(Pool allContent, Pool outResources) { + public void visit(ModulePool allContent, ModulePool outResources) { Objects.requireNonNull(allContent); Objects.requireNonNull(outResources); - PoolImpl resources = new PoolImpl(allContent.getByteOrder()); - for(ModuleData md : allContent.getContent()) { - if(md.getType().equals(Pool.ModuleDataType.CLASS_OR_RESOURCE)) { + ModulePoolImpl resources = new ModulePoolImpl(allContent.getByteOrder()); + allContent.entries().forEach(md -> { + if(md.getType().equals(ModuleEntry.Type.CLASS_OR_RESOURCE)) { resources.add(md); } else { outResources.add(md); } - } + }); AsmPools pools = new AsmPools(resources); visit(pools); pools.fillOutputResources(outResources); diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPool.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPool.java index 9184bb86257..aa5c1cb5ef5 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPool.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPool.java @@ -24,13 +24,12 @@ */ package jdk.tools.jlink.internal.plugins.asm; -import java.io.InputStream; -import java.nio.ByteBuffer; import java.util.Collection; import java.util.List; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; /** * A pool of ClassReader and other resource files. @@ -138,14 +137,14 @@ public interface AsmPool { * @return The ClassReader or null if the class is not found. * @throws jdk.tools.jlink.plugin.PluginException */ - public ClassReader getClassReader(Pool.ModuleData res); + public ClassReader getClassReader(ModuleEntry res); /** * Returns all the classes contained in the writable pool. * * @return The collection of classes. */ - public Collection<Pool.ModuleData> getClasses(); + public Collection<ModuleEntry> getClasses(); } /** @@ -185,14 +184,14 @@ public interface AsmPool { * @param res The java resource * @return The Resource or null if the resource is not found. */ - public ResourceFile getResourceFile(Pool.ModuleData res); + public ResourceFile getResourceFile(ModuleEntry res); /** * Returns all the resources contained in the writable pool. * * @return The array of resources. */ - public Collection<Pool.ModuleData> getResourceFiles(); + public Collection<ModuleEntry> getResourceFiles(); } /** @@ -206,7 +205,7 @@ public interface AsmPool { * @return The resource paths ordered in the way to use for storage in the jimage. * @throws jdk.tools.jlink.plugin.PluginException */ - public List<String> sort(Pool resources); + public List<String> sort(ModulePool resources); } /** @@ -237,7 +236,7 @@ public interface AsmPool { * * @return The classes. */ - public Collection<Pool.ModuleData> getClasses(); + public Collection<ModuleEntry> getClasses(); /** * Returns the resources contained in the pool. Resources are all the file @@ -245,7 +244,7 @@ public interface AsmPool { * * @return The array of resource files. */ - public Collection<Pool.ModuleData> getResourceFiles(); + public Collection<ModuleEntry> getResourceFiles(); /** * Retrieves a resource based on the binary name. This name doesn't contain @@ -266,7 +265,7 @@ public interface AsmPool { * @param res The resource * @return The resource file or null if it doesn't exist. */ - public ResourceFile getResourceFile(Pool.ModuleData res); + public ResourceFile getResourceFile(ModuleEntry res); /** * Retrieve a ClassReader from the pool. @@ -284,7 +283,7 @@ public interface AsmPool { * @return A reader or null if the class is unknown * @throws jdk.tools.jlink.plugin.PluginException */ - public ClassReader getClassReader(Pool.ModuleData res); + public ClassReader getClassReader(ModuleEntry res); /** * To visit the set of ClassReaders. @@ -310,6 +309,6 @@ public interface AsmPool { * @param output The pool used to fill the jimage. * @throws jdk.tools.jlink.plugin.PluginException */ - public void fillOutputResources(Pool output); + public void fillOutputResources(ModulePool output); } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPoolImpl.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPoolImpl.java index cb838d11efa..20c17c85b7b 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPoolImpl.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPoolImpl.java @@ -41,15 +41,14 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; -import java.util.Optional; import java.util.Set; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.tools.jlink.internal.ImageFileCreator; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; +import jdk.tools.jlink.plugin.ModuleEntry; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModulePool; /** * A pool of ClassReader and other resource files. This class allows to @@ -94,7 +93,7 @@ final class AsmPoolImpl implements AsmModulePool { } byte[] content = writer.toByteArray(); - ModuleData res = Pool.newResource(path, + ModuleEntry res = ModuleEntry.create(path, new ByteArrayInputStream(content), content.length); transformedClasses.put(className, res); } @@ -108,7 +107,7 @@ final class AsmPoolImpl implements AsmModulePool { public void forgetClass(String className) { Objects.requireNonNull(className); // do we have a resource? - ModuleData res = transformedClasses.get(className); + ModuleEntry res = transformedClasses.get(className); if (res == null) { res = inputClasses.get(className); if (res == null) { @@ -130,7 +129,7 @@ final class AsmPoolImpl implements AsmModulePool { @Override public ClassReader getClassReader(String binaryName) { Objects.requireNonNull(binaryName); - ModuleData res = transformedClasses.get(binaryName); + ModuleEntry res = transformedClasses.get(binaryName); ClassReader reader = null; if (res != null) { reader = getClassReader(res); @@ -144,16 +143,16 @@ final class AsmPoolImpl implements AsmModulePool { * @return The array of transformed classes. */ @Override - public Collection<ModuleData> getClasses() { - List<ModuleData> classes = new ArrayList<>(); - for (Entry<String, ModuleData> entry : transformedClasses.entrySet()) { + public Collection<ModuleEntry> getClasses() { + List<ModuleEntry> classes = new ArrayList<>(); + for (Entry<String, ModuleEntry> entry : transformedClasses.entrySet()) { classes.add(entry.getValue()); } return classes; } @Override - public ClassReader getClassReader(ModuleData res) { + public ClassReader getClassReader(ModuleEntry res) { return newClassReader(res.getBytes()); } } @@ -176,7 +175,7 @@ final class AsmPoolImpl implements AsmModulePool { public void addResourceFile(ResourceFile resFile) { Objects.requireNonNull(resFile); String path = toResourceNamePath(resFile.getPath()); - ModuleData res = Pool.newResource(path, resFile.getContent()); + ModuleEntry res = ModuleEntry.create(path, resFile.getContent()); transformedResources.put(resFile.getPath(), res); } @@ -191,7 +190,7 @@ final class AsmPoolImpl implements AsmModulePool { Objects.requireNonNull(resourceName); String path = toResourceNamePath(resourceName); // do we have a resource? - ModuleData res = transformedResources.get(resourceName); + ModuleEntry res = transformedResources.get(resourceName); if (res == null) { res = inputResources.get(resourceName); if (res == null) { @@ -212,7 +211,7 @@ final class AsmPoolImpl implements AsmModulePool { @Override public ResourceFile getResourceFile(String name) { Objects.requireNonNull(name); - ModuleData res = transformedResources.get(name); + ModuleEntry res = transformedResources.get(name); ResourceFile resFile = null; if (res != null) { resFile = getResourceFile(res); @@ -226,24 +225,24 @@ final class AsmPoolImpl implements AsmModulePool { * @return The array of transformed classes. */ @Override - public Collection<ModuleData> getResourceFiles() { - List<ModuleData> resources = new ArrayList<>(); - for (Entry<String, ModuleData> entry : transformedResources.entrySet()) { + public Collection<ModuleEntry> getResourceFiles() { + List<ModuleEntry> resources = new ArrayList<>(); + for (Entry<String, ModuleEntry> entry : transformedResources.entrySet()) { resources.add(entry.getValue()); } return resources; } @Override - public ResourceFile getResourceFile(ModuleData res) { + public ResourceFile getResourceFile(ModuleEntry res) { return new ResourceFile(toJavaBinaryResourceName(res.getPath()), res.getBytes()); } } - private final Pool jimageResources; - private final Map<String, ModuleData> inputClasses; - private final Map<String, ModuleData> inputResources; + private final ModulePool jimageResources; + private final Map<String, ModuleEntry> inputClasses; + private final Map<String, ModuleEntry> inputResources; private final Map<String, String> inputClassPackageMapping; private final Map<String, String> inputOtherPackageMapping; @@ -254,9 +253,9 @@ final class AsmPoolImpl implements AsmModulePool { private Sorter sorter; - private final Map<String, ModuleData> transformedClasses + private final Map<String, ModuleEntry> transformedClasses = new LinkedHashMap<>(); - private final Map<String, ModuleData> transformedResources + private final Map<String, ModuleEntry> transformedResources = new LinkedHashMap<>(); private final List<String> forgetResources = new ArrayList<>(); private final Map<String, String> newPackageMapping = new HashMap<>(); @@ -274,7 +273,7 @@ final class AsmPoolImpl implements AsmModulePool { * @param pools The resource pools. * @param descriptor The module descriptor. */ - AsmPoolImpl(Pool inputResources, String moduleName, + AsmPoolImpl(ModulePool inputResources, String moduleName, AsmPools pools, ModuleDescriptor descriptor) { Objects.requireNonNull(inputResources); @@ -285,11 +284,11 @@ final class AsmPoolImpl implements AsmModulePool { this.moduleName = moduleName; this.pools = pools; this.descriptor = descriptor; - Map<String, ModuleData> classes = new LinkedHashMap<>(); - Map<String, ModuleData> resources = new LinkedHashMap<>(); + Map<String, ModuleEntry> classes = new LinkedHashMap<>(); + Map<String, ModuleEntry> resources = new LinkedHashMap<>(); Map<String, String> packageClassToModule = new HashMap<>(); Map<String, String> packageOtherToModule = new HashMap<>(); - for (ModuleData res : inputResources.getContent()) { + inputResources.entries().forEach(res -> { if (res.getPath().endsWith(".class")) { classes.put(toJavaBinaryClassName(res.getPath()), res); } else { @@ -305,7 +304,7 @@ final class AsmPoolImpl implements AsmModulePool { packageOtherToModule.put(split[1], res.getModule()); } } - } + }); this.inputClasses = Collections.unmodifiableMap(classes); this.inputResources = Collections.unmodifiableMap(resources); @@ -356,7 +355,7 @@ final class AsmPoolImpl implements AsmModulePool { * @return The array of classes. */ @Override - public Collection<ModuleData> getClasses() { + public Collection<ModuleEntry> getClasses() { return inputClasses.values(); } @@ -367,7 +366,7 @@ final class AsmPoolImpl implements AsmModulePool { * @return The array of classes. */ @Override - public Collection<ModuleData> getResourceFiles() { + public Collection<ModuleEntry> getResourceFiles() { return inputResources.values(); } @@ -385,7 +384,7 @@ final class AsmPoolImpl implements AsmModulePool { @Override public ResourceFile getResourceFile(String binaryName) { Objects.requireNonNull(binaryName); - ModuleData res = inputResources.get(binaryName); + ModuleEntry res = inputResources.get(binaryName); ResourceFile resFile = null; if (res != null) { resFile = getResourceFile(res); @@ -402,7 +401,7 @@ final class AsmPoolImpl implements AsmModulePool { @Override public ClassReader getClassReader(String binaryName) { Objects.requireNonNull(binaryName); - ModuleData res = inputClasses.get(binaryName); + ModuleEntry res = inputClasses.get(binaryName); ClassReader reader = null; if (res != null) { reader = getClassReader(res); @@ -411,13 +410,13 @@ final class AsmPoolImpl implements AsmModulePool { } @Override - public ResourceFile getResourceFile(ModuleData res) { + public ResourceFile getResourceFile(ModuleEntry res) { return new ResourceFile(toJavaBinaryResourceName(res.getPath()), res.getBytes()); } @Override - public ClassReader getClassReader(ModuleData res) { + public ClassReader getClassReader(ModuleEntry res) { return newClassReader(res.getBytes()); } @@ -505,7 +504,7 @@ final class AsmPoolImpl implements AsmModulePool { @Override public void visitClassReaders(ClassReaderVisitor visitor) { Objects.requireNonNull(visitor); - for (ModuleData res : getClasses()) { + for (ModuleEntry res : getClasses()) { ClassReader reader = newClassReader(res.getBytes()); ClassWriter writer = visitor.visit(reader); if (writer != null) { @@ -523,7 +522,7 @@ final class AsmPoolImpl implements AsmModulePool { @Override public void visitResourceFiles(ResourceFileVisitor visitor) { Objects.requireNonNull(visitor); - for (ModuleData resource : getResourceFiles()) { + for (ModuleEntry resource : getResourceFiles()) { ResourceFile resFile = new ResourceFile(toJavaBinaryResourceName(resource.getPath()), resource.getBytes()); @@ -540,18 +539,18 @@ final class AsmPoolImpl implements AsmModulePool { * been set, it is used to sort the returned resources. * */ @Override - public void fillOutputResources(Pool outputResources) { + public void fillOutputResources(ModulePool outputResources) { List<String> added = new ArrayList<>(); // If the sorter is null, use the input order. // New resources are added at the end // First input classes that have not been removed - Pool output = new PoolImpl(outputResources.getByteOrder(), - ((PoolImpl)outputResources).getStringTable()); - for (ModuleData inResource : jimageResources.getContent()) { + ModulePool output = new ModulePoolImpl(outputResources.getByteOrder(), + ((ModulePoolImpl)outputResources).getStringTable()); + jimageResources.entries().forEach(inResource -> { if (!forgetResources.contains(inResource.getPath())) { - ModuleData resource = inResource; + ModuleEntry resource = inResource; // Do we have a transformed class with the same name? - ModuleData res = transformedResources. + ModuleEntry res = transformedResources. get(toJavaBinaryResourceName(inResource.getPath())); if (res != null) { resource = res; @@ -565,10 +564,10 @@ final class AsmPoolImpl implements AsmModulePool { output.add(resource); added.add(resource.getPath()); } - } + }); // Then new resources - for (Map.Entry<String, ModuleData> entry : transformedResources.entrySet()) { - ModuleData resource = entry.getValue(); + for (Map.Entry<String, ModuleEntry> entry : transformedResources.entrySet()) { + ModuleEntry resource = entry.getValue(); if (!forgetResources.contains(resource.getPath())) { if (!added.contains(resource.getPath())) { output.add(resource); @@ -576,8 +575,8 @@ final class AsmPoolImpl implements AsmModulePool { } } // And new classes - for (Map.Entry<String, ModuleData> entry : transformedClasses.entrySet()) { - ModuleData resource = entry.getValue(); + for (Map.Entry<String, ModuleEntry> entry : transformedClasses.entrySet()) { + ModuleEntry resource = entry.getValue(); if (!forgetResources.contains(resource.getPath())) { if (!added.contains(resource.getPath())) { output.add(resource); diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPools.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPools.java index bbb2d5403f8..53742ee5ad7 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPools.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/asm/AsmPools.java @@ -41,11 +41,11 @@ import java.util.Objects; import java.util.Set; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.plugins.asm.AsmPool.Sorter; +import jdk.tools.jlink.plugin.ModuleEntry; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModulePool; /** * A container for pools of ClassReader and other resource files. A pool of all @@ -97,10 +97,10 @@ public final class AsmPools { } @Override - public Collection<Pool.ModuleData> getClasses() { - List<Pool.ModuleData> all = new ArrayList<>(); + public Collection<ModuleEntry> getClasses() { + List<ModuleEntry> all = new ArrayList<>(); visitAllPools((AsmModulePool pool) -> { - for (Pool.ModuleData rf : pool.getTransformedClasses().getClasses()) { + for (ModuleEntry rf : pool.getTransformedClasses().getClasses()) { all.add(rf); } }); @@ -108,7 +108,7 @@ public final class AsmPools { } @Override - public ClassReader getClassReader(Pool.ModuleData res) { + public ClassReader getClassReader(ModuleEntry res) { return visitPools((AsmModulePool pool) -> { return pool.getTransformedClasses().getClassReader(res); }); @@ -140,10 +140,10 @@ public final class AsmPools { } @Override - public Collection<Pool.ModuleData> getResourceFiles() { - List<Pool.ModuleData> all = new ArrayList<>(); + public Collection<ModuleEntry> getResourceFiles() { + List<ModuleEntry> all = new ArrayList<>(); visitAllPools((AsmModulePool pool) -> { - for (Pool.ModuleData rf : pool.getTransformedResourceFiles().getResourceFiles()) { + for (ModuleEntry rf : pool.getTransformedResourceFiles().getResourceFiles()) { all.add(rf); } }); @@ -151,7 +151,7 @@ public final class AsmPools { } @Override - public ResourceFile getResourceFile(Pool.ModuleData res) { + public ResourceFile getResourceFile(ModuleEntry res) { return visitPools((AsmModulePool pool) -> { return pool.getTransformedResourceFiles().getResourceFile(res); }); @@ -175,10 +175,10 @@ public final class AsmPools { } @Override - public Collection<Pool.ModuleData> getClasses() { - List<Pool.ModuleData> all = new ArrayList<>(); + public Collection<ModuleEntry> getClasses() { + List<ModuleEntry> all = new ArrayList<>(); visitAllPools((AsmModulePool pool) -> { - for (Pool.ModuleData rf : pool.getClasses()) { + for (ModuleEntry rf : pool.getClasses()) { all.add(rf); } }); @@ -186,10 +186,10 @@ public final class AsmPools { } @Override - public Collection<Pool.ModuleData> getResourceFiles() { - List<Pool.ModuleData> all = new ArrayList<>(); + public Collection<ModuleEntry> getResourceFiles() { + List<ModuleEntry> all = new ArrayList<>(); visitAllPools((AsmModulePool pool) -> { - for (Pool.ModuleData rf : pool.getResourceFiles()) { + for (ModuleEntry rf : pool.getResourceFiles()) { all.add(rf); } }); @@ -211,14 +211,14 @@ public final class AsmPools { } @Override - public ResourceFile getResourceFile(Pool.ModuleData res) { + public ResourceFile getResourceFile(ModuleEntry res) { return visitPools((AsmModulePool pool) -> { return pool.getResourceFile(res); }); } @Override - public ClassReader getClassReader(Pool.ModuleData res) { + public ClassReader getClassReader(ModuleEntry res) { return visitPoolsEx((AsmModulePool pool) -> { return pool.getClassReader(res); }); @@ -239,7 +239,7 @@ public final class AsmPools { } @Override - public void fillOutputResources(Pool outputResources) { + public void fillOutputResources(ModulePool outputResources) { AsmPools.this.fillOutputResources(outputResources); } @@ -324,15 +324,15 @@ public final class AsmPools { * * @param inputResources The raw resources to build the pool from. */ - public AsmPools(Pool inputResources) { + public AsmPools(ModulePool inputResources) { Objects.requireNonNull(inputResources); - Map<String, Pool> resPools = new LinkedHashMap<>(); + Map<String, ModulePool> resPools = new LinkedHashMap<>(); Map<String, ModuleDescriptor> descriptors = new HashMap<>(); - for (Pool.ModuleData res : inputResources.getContent()) { - Pool p = resPools.get(res.getModule()); + inputResources.entries().forEach(res -> { + ModulePool p = resPools.get(res.getModule()); if (p == null) { - p = new PoolImpl(inputResources.getByteOrder(), - ((PoolImpl)inputResources).getStringTable()); + p = new ModulePoolImpl(inputResources.getByteOrder(), + ((ModulePoolImpl)inputResources).getStringTable()); resPools.put(res.getModule(), p); } if (res.getPath().endsWith("module-info.class")) { @@ -341,11 +341,11 @@ public final class AsmPools { descriptors.put(res.getModule(), descriptor); } p.add(res); - } + }); poolsArray = new AsmModulePool[resPools.size()]; int i = 0; - for (Entry<String, Pool> entry : resPools.entrySet()) { + for (Entry<String, ModulePool> entry : resPools.entrySet()) { ModuleDescriptor descriptor = descriptors.get(entry.getKey()); if (descriptor == null) { throw new PluginException("module-info.class not found for " + entry.getKey() + " module"); @@ -405,7 +405,7 @@ public final class AsmPools { * * @param outputResources The pool used to fill the jimage. */ - public void fillOutputResources(Pool outputResources) { + public void fillOutputResources(ModulePool outputResources) { // First sort modules List<String> modules = new ArrayList<>(); for (String k : pools.keySet()) { @@ -414,8 +414,8 @@ public final class AsmPools { if (moduleSorter != null) { modules = moduleSorter.sort(modules); } - Pool output = new PoolImpl(outputResources.getByteOrder(), - ((PoolImpl)outputResources).getStringTable()); + ModulePool output = new ModulePoolImpl(outputResources.getByteOrder(), + ((ModulePoolImpl)outputResources).getStringTable()); for (String mn : modules) { AsmPool pool = pools.get(mn); pool.fillOutputResources(output); @@ -423,17 +423,17 @@ public final class AsmPools { sort(outputResources, output, global.sorter); } - static void sort(Pool outputResources, - Pool transientOutput, Sorter sorter) { + static void sort(ModulePool outputResources, + ModulePool transientOutput, Sorter sorter) { if (sorter != null) { List<String> order = sorter.sort(transientOutput); for (String s : order) { - outputResources.add(transientOutput.get(s)); + outputResources.add(transientOutput.findEntry(s).get()); } } else { - for (ModuleData res : transientOutput.getContent()) { + transientOutput.entries().forEach(res-> { outputResources.add(res); - } + }); } } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ExecutableImage.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ExecutableImage.java index d5e767cd553..499d23dd450 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ExecutableImage.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ExecutableImage.java @@ -24,66 +24,41 @@ */ package jdk.tools.jlink.plugin; -import java.nio.file.Files; import java.nio.file.Path; -import java.util.Collections; import java.util.List; -import java.util.Objects; import java.util.Set; /** - * An executable runtime image. Instance of this class contains the information - * needed to create image processes. + * An executable runtime image. Contains the information about the executable + * image created. */ -public abstract class ExecutableImage { - - private final Path home; - private final List<String> args; - private final Set<String> modules; - - protected ExecutableImage(Path home, Set<String> modules, - List<String> args) { - Objects.requireNonNull(home); - Objects.requireNonNull(args); - if (!Files.exists(home)) { - throw new IllegalArgumentException("Invalid image home"); - } - this.home = home; - this.modules = Collections.unmodifiableSet(modules); - this.args = Collections.unmodifiableList(args); - } +public interface ExecutableImage { /** * Image home directory, * * @return The home directory. */ - public Path getHome() { - return home; - } + public Path getHome(); /** * The names of the modules located in the image. * * @return The set of modules. */ - public Set<String> getModules() { - return modules; - } + public Set<String> getModules(); /** * The list of arguments required to execute the image. * * @return The list of arguments. */ - public List<String> getExecutionArgs() { - return args; - } + public List<String> getExecutionArgs(); /** * Store new arguments required to execute the image. * * @param args Additional arguments */ - public abstract void storeLaunchArgs(List<String> args); + public void storeLaunchArgs(List<String> args); } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/LinkModule.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/LinkModule.java new file mode 100644 index 00000000000..f516d8d0494 --- /dev/null +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/LinkModule.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, 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.tools.jlink.plugin; + +import java.lang.module.ModuleDescriptor; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +/** + * Link-time representation of a Java module. + */ +public interface LinkModule { + + /** + * The module name. + * + * @return The name. + */ + public String getName(); + + /** + * Retrieves a LinkModuleEntry from the given path (e.g: + * /mymodule/com.foo.bar/MyClass.class) + * + * @param path The piece of data path. + * @return A LinkModuleEntry of the given path, if found. + */ + public Optional<ModuleEntry> findEntry(String path); + + /** + * The module descriptor of this module. + * + * @return The module descriptor. + */ + public ModuleDescriptor getDescriptor(); + + /** + * Add a LinkModuleEntry to this module. + * + * @param data The LinkModuleEntry to add. + */ + public void add(ModuleEntry data); + + /** + * Retrieves all the packages located in this module. + * + * @return The set of packages. + */ + public Set<String> getAllPackages(); + + /** + * Retrieves the stream of LinkModuleEntry. + * + * @return The LinkModuleEntry stream. + */ + public Stream<? extends ModuleEntry> entries(); + + /** + * Return the number of LinkModuleEntry count in this LinkModule. + * + * @return the entry count. + */ + public int getEntryCount(); +} diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ModuleEntry.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ModuleEntry.java new file mode 100644 index 00000000000..61f828fc914 --- /dev/null +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ModuleEntry.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2016, 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.tools.jlink.plugin; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.Objects; +import jdk.tools.jlink.internal.ImageFileCreator; +import jdk.tools.jlink.internal.ModuleEntryImpl; + +/** + * A LinkModuleEntry is the elementary unit of data inside an image. It is + * generally a file. e.g.: a java class file, a resource file, a shared library, + * ... + * <br> + * A LinkModuleEntry is identified by a path of the form: + * <ul> + * <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file + * name}</li> + * <li>For other files (shared lib, launchers, config, ...):/{module name}/ + * {@literal bin|conf|native}/{dir1}>/.../{dirN}/{file name}</li> + * </ul> + */ +public interface ModuleEntry { + + /** + * Type of module data. + * <li> + * <ul>CLASS_OR_RESOURCE: A java class or resource file.</ul> + * <ul>CONFIG: A configuration file.</ul> + * <ul>NATIVE_CMD: A native process launcher.</ul> + * <ul>NATIVE_LIB: A native library.</ul> + * <ul>OTHER: Other kind of file.</ul> + * </li> + */ + public enum Type { + CLASS_OR_RESOURCE, + CONFIG, + NATIVE_CMD, + NATIVE_LIB, + OTHER + } + /** + * The LinkModuleEntry module name. + * + * @return The module name. + */ + public String getModule(); + + /** + * The LinkModuleEntry path. + * + * @return The module path. + */ + public String getPath(); + + /** + * The LinkModuleEntry's type. + * + * @return The data type. + */ + public Type getType(); + + /** + * The LinkModuleEntry content as an array of byte. + * + * @return An Array of bytes. + */ + public byte[] getBytes(); + + /** + * The LinkModuleEntry content length. + * + * @return The length. + */ + public long getLength(); + + /** + * The LinkModuleEntry stream. + * + * @return The module data stream. + */ + public InputStream stream(); + + + /** + * Create a LinkModuleEntry located inside a jimage file. Such + * LinkModuleEntry has a Type being equals to CLASS_OR_RESOURCE. + * + * @param path The complete resource path (contains the module radical). + * @param content The resource content. + * @param size The content size. + * @return A new LinkModuleEntry. + */ + public static ModuleEntry create(String path, InputStream content, long size) { + Objects.requireNonNull(path); + Objects.requireNonNull(content); + String[] split = ImageFileCreator.splitPath(path); + String module = split[0]; + return new ModuleEntryImpl(module, path, Type.CLASS_OR_RESOURCE, content, size); + } + + /** + * Create a LinkModuleEntry for a file that will be located inside a jimage + * file. + * + * @param path The resource path. + * @param content The resource content. + * @return A new LinkModuleEntry. + */ + public static ModuleEntry create(String path, byte[] content) { + return create(path, new ByteArrayInputStream(content), + content.length); + } + + /** + * Create a LinkModuleEntry for a file that will be located outside a jimage + * file. + * + * @param module The module in which this files is located. + * @param path The file path locator (doesn't contain the module name). + * @param type The LinkModuleEntry type. + * @param content The file content. + * @param size The content size. + * @return A new LinkModuleEntry. + */ + public static ModuleEntry create(String module, String path, ModuleEntry.Type type, + InputStream content, long size) { + Objects.requireNonNull(path); + Objects.requireNonNull(content); + return new ModuleEntryImpl(module, path, type, content, size); + } +} diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ModulePool.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ModulePool.java new file mode 100644 index 00000000000..4d0f230e1c6 --- /dev/null +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ModulePool.java @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2015, 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.tools.jlink.plugin; + +import java.nio.ByteOrder; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Stream; + +/** + * Pool of module data. + */ +public interface ModulePool { +/** + * Is this a read-only ModulePool? + * + * @return true if this is a read-only configuration. + */ + public boolean isReadOnly(); + + /** + * Add a ModuleEntry. + * + * @param data The ModuleEntry to add. + */ + public void add(ModuleEntry data); + /** + * Retrieves the module for the provided name. + * + * @param name The module name + * @return the module of matching name, if found + */ + public Optional<LinkModule> findModule(String name); + + /** + * The stream of modules contained in this ModulePool. + * + * @return The stream of modules. + */ + public Stream<? extends LinkModule> modules(); + + /** + * Return the number of LinkModule count in this ModulePool. + * + * @return the module count. + */ + public int getModuleCount(); + + /** + * Get all ModuleEntry contained in this ModulePool instance. + * + * @return The stream of LinkModuleEntries. + */ + public Stream<? extends ModuleEntry> entries(); + + /** + * Return the number of ModuleEntry count in this ModulePool. + * + * @return the entry count. + */ + public int getEntryCount(); + + /** + * Get the ModuleEntry for the passed path. + * + * @param path A data path + * @return A ModuleEntry instance or null if the data is not found + */ + public Optional<ModuleEntry> findEntry(String path); + + /** + * Check if the ModulePool contains the given ModuleEntry. + * + * @param data The module data to check existence for. + * @return The module data or null if not found. + */ + public boolean contains(ModuleEntry data); + + /** + * Check if the ModulePool contains some content at all. + * + * @return True, no content, false otherwise. + */ + public boolean isEmpty(); + + /** + * Visit each ModuleEntry in this ModulePool to transform it and copy + * the transformed ModuleEntry to the output ModulePool. + * + * @param transform The function called for each ModuleEntry found in the + * ModulePool. The transform function should return a ModuleEntry + * instance which will be added to the output or it should return null if + * the passed ModuleEntry is to be ignored for the output. + * + * @param output The ModulePool to be filled with Visitor returned + * ModuleEntry. + */ + public void transformAndCopy(Function<ModuleEntry, ModuleEntry> transform, ModulePool output); + + /** + * The ByteOrder currently in use when generating the jimage file. + * + * @return The ByteOrder. + */ + public ByteOrder getByteOrder(); + + /** + * Release properties such as OS, CPU name, version etc. + * + * @return the release properties + */ + public Map<String, String> getReleaseProperties(); +} diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java index 56e51bc9bc5..30633b546d3 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Plugin.java @@ -26,7 +26,6 @@ package jdk.tools.jlink.plugin; import java.util.Collections; import java.util.EnumSet; -import java.util.List; import java.util.Map; import java.util.Set; import jdk.tools.jlink.internal.plugins.PluginsResourceBundle; @@ -36,14 +35,6 @@ import jdk.tools.jlink.internal.plugins.PluginsResourceBundle; */ public interface Plugin { - /** - * Type of plugin. - */ - public interface PluginType { - - public String getName(); - } - /** * Order of categories: * <ol> @@ -53,28 +44,29 @@ public interface Plugin { * <li>MODULEINFO_TRANSFORMER: Transform only module-info.class</li> * <li>SORTER: Sort resources within the resource container.</li> * <li>COMPRESSOR: Compress resource within the resouce containers.</li> + * <li>METAINFO_ADDER: Added meta info (like release, copyright etc.)</li> * <li>VERIFIER: Does some image verification.</li> * <li>PROCESSOR: Does some post processing on image.</li> * <li>PACKAGER: Final processing</li> * </ol> */ - public enum CATEGORY implements PluginType { + public enum Category { FILTER("FILTER"), TRANSFORMER("TRANSFORMER"), MODULEINFO_TRANSFORMER("MODULEINFO_TRANSFORMER"), SORTER("SORTER"), COMPRESSOR("COMPRESSOR"), + METAINFO_ADDER("METAINFO_ADDER"), VERIFIER("VERIFIER"), PROCESSOR("PROCESSOR"), PACKAGER("PACKAGER"); private final String name; - CATEGORY(String name) { + Category(String name) { this.name = name; } - @Override public String getName() { return name; } @@ -91,7 +83,7 @@ public interface Plugin { * {@link #getStateDescription() getStateDescription} method</li> * </ul> */ - public enum STATE { + public enum State { DISABLED, AUTO_ENABLED, FUNCTIONAL @@ -101,7 +93,7 @@ public interface Plugin { * The Plugin set of types. * @return The set of types. */ - public default Set<PluginType> getType() { + public default Set<Category> getType() { return Collections.emptySet(); } @@ -109,8 +101,8 @@ public interface Plugin { * The Plugin set of states. * @return The set of states. */ - public default Set<STATE> getState() { - return EnumSet.of(STATE.FUNCTIONAL); + public default Set<State> getState() { + return EnumSet.of(State.FUNCTIONAL); } /** @@ -191,7 +183,7 @@ public interface Plugin { * @return A status description. */ public default String getStateDescription() { - return getState().contains(STATE.FUNCTIONAL) + return getState().contains(State.FUNCTIONAL) ? PluginsResourceBundle.getMessage("main.status.ok") : PluginsResourceBundle.getMessage("main.status.not.ok"); } @@ -206,18 +198,4 @@ public interface Plugin { */ public default void configure(Map<String, String> config) { } - - /** - * Configure the plugin based on the passed configuration. - * This method is called prior to invoke the plugin. - * - * @param config The plugin configuration. - * @param ctx The plugin context - * @throws IllegalArgumentException if a mandatory argument is missing or - * if an argument has invalid value. - * - */ - public default void configure(Map<String, String> config, PluginContext ctx) { - configure(config); - } } diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java deleted file mode 100644 index 380ca41ac1a..00000000000 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/Pool.java +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright (c) 2015, 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.tools.jlink.plugin; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UncheckedIOException; -import java.lang.module.ModuleDescriptor; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import jdk.tools.jlink.internal.ImageFileCreator; -import jdk.tools.jlink.internal.plugins.FileCopierPlugin; - -/** - * Pool of module data. - * - */ -public abstract class Pool { - - /** - * Interface to visit the content of a Pool. - */ - public interface Visitor { - - /** - * Called for each visited ModuleData. - * - * @param content A ModuleData - * @return A ModuleData instance or null if the passed ModuleData is to - * be removed from the image. - * @throws PluginException - */ - public ModuleData visit(ModuleData content); - } - - /** - * Type of module data. - * <li> - * <ul>CLASS_OR_RESOURCE: A java class or resource file.</ul> - * <ul>CONFIG: A configuration file.</ul> - * <ul>NATIVE_CMD: A native process launcher.</ul> - * <ul>NATIVE_LIB: A native library.</ul> - * <ul>OTHER: Other kind of file.</ul> - * </li> - */ - public static enum ModuleDataType { - - CLASS_OR_RESOURCE, - CONFIG, - NATIVE_CMD, - NATIVE_LIB, - OTHER; - } - - /** - * A module in the pool. - */ - public interface Module { - - /** - * The module name. - * - * @return The name. - */ - public String getName(); - - /** - * Retrieves a ModuleData from a path (e.g: - * /mymodule/com.foo.bar/MyClass.class) - * - * @param path The piece of data path. - * @return A ModuleData or null if the path doesn't identify a - * ModuleData. - */ - public ModuleData get(String path); - - /** - * The module descriptor of this module. - * - * @return The module descriptor. - */ - public ModuleDescriptor getDescriptor(); - - /** - * Add a ModuleData to this module. - * - * @param data The ModuleData to add. - */ - public void add(ModuleData data); - - /** - * Retrieves all the packages located in this module. - * - * @return The set of packages. - */ - public Set<String> getAllPackages(); - - /** - * Retrieves the collection of ModuleData. - * - * @return The ModuleData collection. - */ - public Collection<ModuleData> getContent(); - - } - - private class ModuleImpl implements Module { - - private final Map<String, ModuleData> moduleContent = new LinkedHashMap<>(); - private ModuleDescriptor descriptor; - private final String name; - - private ModuleImpl(String name) { - this.name = name; - } - - @Override - public String getName() { - return name; - } - - @Override - public ModuleData get(String path) { - if (!path.startsWith("/")) { - path = "/" + path; - } - if (!path.startsWith("/" + name)) { - path = "/" + name + path; - } - return moduleContent.get(path); - } - - @Override - public ModuleDescriptor getDescriptor() { - if (descriptor == null) { - String p = "/" + name + "/module-info.class"; - ModuleData content = moduleContent.get(p); - if (content == null) { - throw new PluginException("No module-info for " + name - + " module"); - } - ByteBuffer bb = ByteBuffer.wrap(content.getBytes()); - descriptor = ModuleDescriptor.read(bb); - } - return descriptor; - } - - @Override - public void add(ModuleData data) { - if (isReadOnly()) { - throw new PluginException("pool is readonly"); - } - Objects.requireNonNull(data); - if (!data.getModule().equals(name)) { - throw new PluginException("Can't add resource " + data.getPath() - + " to module " + name); - } - Pool.this.add(data); - } - - @Override - public Set<String> getAllPackages() { - Set<String> pkgs = new HashSet<>(); - moduleContent.values().stream().filter(m -> m.getType(). - equals(ModuleDataType.CLASS_OR_RESOURCE)).forEach((res) -> { - // Module metadata only contains packages with .class files - if (ImageFileCreator.isClassPackage(res.getPath())) { - String[] split = ImageFileCreator.splitPath(res.getPath()); - String pkg = split[1]; - if (pkg != null && !pkg.isEmpty()) { - pkgs.add(pkg); - } - } - }); - return pkgs; - } - - @Override - public String toString() { - return getName(); - } - - @Override - public Collection<ModuleData> getContent() { - return Collections.unmodifiableCollection(moduleContent.values()); - } - } - - /** - * A ModuleData is the elementary unit of data inside an image. It is - * generally a file. e.g.: a java class file, a resource file, a shared - * library, ... - * <br> - * A ModuleData is identified by a path of the form: - * <ul> - * <li>For jimage content: /{module name}/{package1}/.../{packageN}/{file - * name}</li> - * <li>For other files (shared lib, launchers, config, ...):/{module name}/ - * {@literal bin|conf|native}/{dir1}/.../{dirN}/{file name}</li> - * </ul> - */ - public static class ModuleData { - - private final ModuleDataType type; - private final String path; - private final String module; - private final long length; - private final InputStream stream; - private byte[] buffer; - - /** - * Create a new ModuleData. - * - * @param module The module name. - * @param path The data path identifier. - * @param type The data type. - * @param stream The data content stream. - * @param length The stream length. - */ - public ModuleData(String module, String path, ModuleDataType type, - InputStream stream, long length) { - Objects.requireNonNull(module); - Objects.requireNonNull(path); - Objects.requireNonNull(type); - Objects.requireNonNull(stream); - this.path = path; - this.type = type; - this.module = module; - this.stream = stream; - this.length = length; - } - - /** - * The ModuleData module name. - * - * @return The module name. - */ - public final String getModule() { - return module; - } - - /** - * The ModuleData path. - * - * @return The module path. - */ - public final String getPath() { - return path; - } - - /** - * The ModuleData type. - * - * @return The data type. - */ - public final ModuleDataType getType() { - return type; - } - - /** - * The ModuleData content as an array of byte. - * - * @return An Array of bytes. - */ - public byte[] getBytes() { - if (buffer == null) { - try { - buffer = stream.readAllBytes(); - } catch (IOException ex) { - throw new UncheckedIOException(ex); - } - } - return buffer; - } - - /** - * The ModuleData content length. - * - * @return The length. - */ - public long getLength() { - return length; - } - - /** - * The ModuleData stream. - * - * @return The module data stream. - */ - public InputStream stream() { - return stream; - } - - @Override - public int hashCode() { - int hash = 7; - hash = 89 * hash + Objects.hashCode(this.path); - return hash; - } - - @Override - public boolean equals(Object other) { - if (!(other instanceof ModuleData)) { - return false; - } - ModuleData f = (ModuleData) other; - return f.path.equals(path); - } - - @Override - public String toString() { - return getPath(); - } - } - - private final Map<String, ModuleData> resources = new LinkedHashMap<>(); - private final Map<String, ModuleImpl> modules = new LinkedHashMap<>(); - private final ModuleImpl fileCopierModule = new ModuleImpl(FileCopierPlugin.FAKE_MODULE); - - private final ByteOrder order; - - protected Pool() { - this(ByteOrder.nativeOrder()); - } - - protected Pool(ByteOrder order) { - Objects.requireNonNull(order); - this.order = order; - } - - /** - * Read only state. No data can be added to a ReadOnly Pool. - * - * @return true if readonly false otherwise. - */ - public abstract boolean isReadOnly(); - - /** - * Add a ModuleData. - * - * @param data The ModuleData to add. - */ - public void add(ModuleData data) { - if (isReadOnly()) { - throw new PluginException("pool is readonly"); - } - Objects.requireNonNull(data); - if (resources.get(data.getPath()) != null) { - throw new PluginException("Resource " + data.getPath() - + " already present"); - } - String modulename = data.getModule(); - ModuleImpl m = modules.get(modulename); - // ## TODO: FileCopierPlugin should not add content to a module - // FAKE_MODULE is not really a module to be added in the image - if (FileCopierPlugin.FAKE_MODULE.equals(modulename)) { - m = fileCopierModule; - } - if (m == null) { - m = new ModuleImpl(modulename); - modules.put(modulename, m); - } - resources.put(data.getPath(), data); - m.moduleContent.put(data.getPath(), data); - } - - /** - * Retrieves the module for the provided name. - * - * @param name The module name - * @return the module or null if the module doesn't exist. - */ - public Module getModule(String name) { - Objects.requireNonNull(name); - return modules.get(name); - } - - /** - * The collection of modules contained in this pool. - * - * @return The collection of modules. - */ - public Collection<Module> getModules() { - return Collections.unmodifiableCollection(modules.values()); - } - - /** - * Get all ModuleData contained in this pool instance. - * - * @return The collection of resources; - */ - public Collection<ModuleData> getContent() { - return Collections.unmodifiableCollection(resources.values()); - } - - /** - * Get the ModuleData for the passed path. - * - * @param path A data path - * @return A ModuleData instance or null if the data is not found - */ - public ModuleData get(String path) { - Objects.requireNonNull(path); - return resources.get(path); - } - - /** - * Check if the pool contains this data. - * - * @param data The module data to check existence for. - * @return The module data or null if not found. - */ - public boolean contains(ModuleData data) { - Objects.requireNonNull(data); - return get(data.getPath()) != null; - } - - /** - * Check if the Pool contains some content. - * - * @return True, no content, false otherwise. - */ - public boolean isEmpty() { - return resources.isEmpty(); - } - - /** - * Visit the pool. - * - * @param visitor The Visitor called for each ModuleData found in the pool. - * @param output The pool to be filled with Visitor returned ModuleData. - */ - public void visit(Visitor visitor, Pool output) { - for (ModuleData resource : getContent()) { - ModuleData res = visitor.visit(resource); - if (res != null) { - output.add(res); - } - } - } - - /** - * The ByteOrder currently in use when generating the jimage file. - * - * @return The ByteOrder. - */ - public ByteOrder getByteOrder() { - return order; - } - - /** - * Create a ModuleData located inside a jimage file. Such ModuleData has a - * ModuleDataType being equals to CLASS_OR_RESOURCE. - * - * @param path The complete resource path (contains the module radical). - * @param content The resource content. - * @param size The content size. - * @return A new ModuleData. - */ - public static ModuleData newResource(String path, InputStream content, long size) { - Objects.requireNonNull(path); - Objects.requireNonNull(content); - String[] split = ImageFileCreator.splitPath(path); - String module = split[0]; - return new ModuleData(module, path, ModuleDataType.CLASS_OR_RESOURCE, content, size); - } - - /** - * Create a ModuleData for a file that will be located inside a jimage file. - * - * @param path The resource path. - * @param content The resource content. - * @return A new ModuleData. - */ - public static ModuleData newResource(String path, byte[] content) { - return newResource(path, new ByteArrayInputStream(content), - content.length); - } - - /** - * Create a ModuleData for a file that will be located outside a jimage - * file. - * - * @param module The module in which this files is located. - * @param path The file path locator (doesn't contain the module name). - * @param type The ModuleData type. - * @param content The file content. - * @param size The content size. - * @return A new ModuleData. - */ - public static ModuleData newImageFile(String module, String path, ModuleDataType type, - InputStream content, long size) { - Objects.requireNonNull(path); - Objects.requireNonNull(content); - return new ModuleData(module, path, type, content, size); - } - -} diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/TransformerPlugin.java b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/TransformerPlugin.java index 4af4897e636..15133221c43 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/TransformerPlugin.java +++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/TransformerPlugin.java @@ -40,5 +40,5 @@ public interface TransformerPlugin extends Plugin { * * @throws PluginException */ - public void visit(Pool in, Pool out); + public void visit(ModulePool in, ModulePool out); } diff --git a/jdk/src/jdk.jlink/share/classes/module-info.java b/jdk/src/jdk.jlink/share/classes/module-info.java index 49e426fed12..c23116404ac 100644 --- a/jdk/src/jdk.jlink/share/classes/module-info.java +++ b/jdk/src/jdk.jlink/share/classes/module-info.java @@ -24,9 +24,7 @@ */ module jdk.jlink { - exports jdk.tools.jlink; exports jdk.tools.jlink.plugin; - exports jdk.tools.jlink.builder; requires jdk.internal.opt; requires jdk.jdeps; @@ -46,5 +44,5 @@ module jdk.jlink { provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.ExcludeVMPlugin; provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.IncludeLocalesPlugin; provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.GenerateJLIClassesPlugin; - provides jdk.tools.jlink.plugin.PostProcessorPlugin with jdk.tools.jlink.internal.plugins.ReleaseInfoPlugin; + provides jdk.tools.jlink.plugin.TransformerPlugin with jdk.tools.jlink.internal.plugins.ReleaseInfoPlugin; } diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt index de8331e3622..6e1cd7385d4 100644 --- a/jdk/test/ProblemList.txt +++ b/jdk/test/ProblemList.txt @@ -116,10 +116,8 @@ # jdk_beans -java/beans/XMLEncoder/Test4903007.java 8060027 generic-all -java/beans/XMLEncoder/java_awt_GridBagLayout.java 8060027 generic-all -java/beans/XMLDecoder/8028054/TestConstructorFinder.java 8060027 generic-all -java/beans/XMLDecoder/8028054/TestMethodFinder.java 8060027 generic-all +java/beans/XMLDecoder/8028054/TestConstructorFinder.java 8156579 generic-all +java/beans/XMLDecoder/8028054/TestMethodFinder.java 8156579 generic-all java/beans/Introspector/8132566/OverridePropertyInfoTest.java 8132565 generic-all java/beans/Introspector/8132566/OverrideUserDefPropertyInfoTest.java 8132565 generic-all @@ -145,6 +143,12 @@ java/lang/management/MemoryMXBean/LowMemoryTest.java 8130339 generic- ############################################################################ +# jdk_io + +java/io/pathNames/GeneralWin32.java 8156595 windows-all + +############################################################################ + # jdk_jmx com/sun/management/OperatingSystemMXBean/GetProcessCpuLoad.java 8030957 aix-all @@ -210,6 +214,10 @@ sun/security/krb5/auto/Unreachable.java 7164518 macosx-a java/security/KeyPairGenerator/SolarisShortDSA.java 7041639 solaris-all sun/security/tools/keytool/standard.sh 7041639 solaris-all +sun/security/tools/keytool/ListKeychainStore.sh 8156889 macosx-all + +sun/security/mscapi/ShortRSAKey1024.sh 8153948 windows-all + java/security/Security/ClassLoaderDeadlock/Deadlock2.sh 8062758 generic-all sun/security/tools/jarsigner/warnings/BadKeyUsageTest.java 8026393 generic-all @@ -224,6 +232,8 @@ sun/security/pkcs11/Cipher/TestSymmCiphersNoPad.java 8077138,8023434 sun/security/pkcs11/KeyAgreement/TestDH.java 8077138,8023434 windows-all sun/security/pkcs11/KeyAgreement/TestInterop.java 8077138,8023434 windows-all sun/security/pkcs11/KeyAgreement/TestShort.java 8077138,8023434 windows-all +sun/security/pkcs11/KeyAgreement/SupportedDHKeys.java 8154910 windows-all +sun/security/pkcs11/KeyAgreement/UnsupportedDHKeys.java 8154910 windows-all sun/security/pkcs11/KeyGenerator/DESParity.java 8077138,8023434 windows-all sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java 8077138,8023434 windows-all sun/security/pkcs11/KeyPairGenerator/TestDH2048.java 8077138,8023434 windows-all @@ -288,7 +298,6 @@ sun/security/x509/URICertStore/ExtensionsWithLDAP.java 8134577 generic- # jdk_sound -javax/sound/midi/Gervill/SoftProvider/GetDevice.java 8059743 generic-all javax/sound/sampled/DirectAudio/bug6400879.java 8148915 linux-all ############################################################################ @@ -323,6 +332,8 @@ tools/launcher/FXLauncherTest.java 8068049 linux-al tools/pack200/Pack200Props.java 8155857 generic-all +tools/pack200/TestNormal.java 8156807 windows-all + ############################################################################ # jdk_jdi diff --git a/jdk/test/com/oracle/security/ucrypto/TestDigest.java b/jdk/test/com/oracle/security/ucrypto/TestDigest.java index 5bd6f412f29..5dabb55095e 100644 --- a/jdk/test/com/oracle/security/ucrypto/TestDigest.java +++ b/jdk/test/com/oracle/security/ucrypto/TestDigest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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,7 +23,7 @@ /* * @test - * @bug 7088989 + * @bug 7088989 8000415 * @summary Ensure the various message digests works correctly * @key randomness */ @@ -40,84 +40,106 @@ public class TestDigest extends UcryptoTest { private static final String[] MD_ALGOS = { "MD5", "SHA", + "SHA-224", "SHA-256", "SHA-384", - "SHA-512" + "SHA-512", + "SHA3-224", + "SHA3-256", + "SHA3-384", + "SHA3-512" }; public static void main(String[] args) throws Exception { main(new TestDigest(), null); } - public void doTest(Provider p) { + public void doTest(Provider p) throws Exception { boolean testPassed = true; byte[] msg = new byte[200]; (new SecureRandom()).nextBytes(msg); String interopProvName = "SUN"; + MessageDigest md, md2; + for (String a : MD_ALGOS) { + System.out.println("Testing " + a); try { - MessageDigest md, md2; - try { - md = MessageDigest.getInstance(a, p); - } catch (NoSuchAlgorithmException nsae) { - System.out.println("Skipping Unsupported MD algo: " + a); - continue; - } - md2 = MessageDigest.getInstance(a, interopProvName); - // Test Interoperability for update+digest calls - for (int i = 0; i < 3; i++) { - md.update(msg); - byte[] digest = md.digest(); - md2.update(msg); - byte[] digest2 = md2.digest(); - if (!Arrays.equals(digest, digest2)) { - System.out.println("DIFF1 FAILED for: " + a + " at iter " + i); - testPassed = false; - } - } - - // Test Interoperability for digest calls md = MessageDigest.getInstance(a, p); + } catch (NoSuchAlgorithmException nsae) { + System.out.println("=> Skip, unsupported"); + continue; + } + try { md2 = MessageDigest.getInstance(a, interopProvName); + } catch (NoSuchAlgorithmException nsae) { + System.out.println("=> Skip, no interop provider found"); + continue; + } - for (int i = 0; i < 3; i++) { - byte[] digest = md.digest(); - byte[] digest2 = md2.digest(); - if (!Arrays.equals(digest, digest2)) { - System.out.println("DIFF2 FAILED for: " + a + " at iter " + i); - testPassed = false; - } + // Test Interoperability for update+digest calls + for (int i = 0; i < 3; i++) { + md.update(msg); + byte[] digest = md.digest(); + md2.update(msg); + byte[] digest2 = md2.digest(); + if (!Arrays.equals(digest, digest2)) { + System.out.println("DIFF1 FAILED at iter " + i); + testPassed = false; + } else { + System.out.println("...diff1 test passed"); } + } - // Test Cloning functionality - md = MessageDigest.getInstance(a, p); - md2 = (MessageDigest) md.clone(); // clone right after construction + // Test Interoperability for digest calls + md = MessageDigest.getInstance(a, p); + md2 = MessageDigest.getInstance(a, interopProvName); + + for (int i = 0; i < 3; i++) { byte[] digest = md.digest(); byte[] digest2 = md2.digest(); if (!Arrays.equals(digest, digest2)) { - System.out.println("DIFF-3.1 FAILED for: " + a); + System.out.println("DIFF2 FAILED at iter " + i); testPassed = false; + } else { + System.out.println("...diff2 test passed"); } - md.update(msg); - md2 = (MessageDigest) md.clone(); // clone again after update call - digest = md.digest(); - digest2 = md2.digest(); - if (!Arrays.equals(digest, digest2)) { - System.out.println("DIFF-3.2 FAILED for: " + a); - testPassed = false; - } - md2 = (MessageDigest) md.clone(); // clone after digest - digest = md.digest(); - digest2 = md2.digest(); - if (!Arrays.equals(digest, digest2)) { - System.out.println("DIFF-3.3 FAILED for: " + a); - testPassed = false; - } - } catch(Exception ex) { - System.out.println("Unexpected Exception: " + a); - ex.printStackTrace(); + } + + // Test Cloning functionality if supported + md = MessageDigest.getInstance(a, p); + try { + md2 = (MessageDigest) md.clone(); // clone right after construction + } catch (CloneNotSupportedException cnse) { + System.out.println("...no clone support"); + continue; + } + byte[] digest = md.digest(); + byte[] digest2 = md2.digest(); + if (!Arrays.equals(digest, digest2)) { + System.out.println("DIFF-3.1 FAILED"); testPassed = false; + } else { + System.out.println("...diff3.1 tests passed"); + } + md.update(msg); + md2 = (MessageDigest) md.clone(); // clone again after update call + digest = md.digest(); + digest2 = md2.digest(); + if (!Arrays.equals(digest, digest2)) { + System.out.println("DIFF-3.2 FAILED"); + testPassed = false; + } else { + System.out.println("...diff3.2 tests passed"); + } + md2 = (MessageDigest) md.clone(); // clone after digest + digest = md.digest(); + digest2 = md2.digest(); + if (!Arrays.equals(digest, digest2)) { + System.out.println("DIFF-3.3 FAILED"); + testPassed = false; + } else { + System.out.println("...diff3.3 tests passed"); } } if (!testPassed) { diff --git a/jdk/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java b/jdk/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java index a162debb3f8..9052737aad5 100644 --- a/jdk/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java +++ b/jdk/test/java/lang/Class/getDeclaredField/FieldSetAccessibleTest.java @@ -228,12 +228,18 @@ public class FieldSetAccessibleTest { } static boolean test(String s, boolean addExports) { + String clsName = s.replace('/', '.').substring(0, s.length() - 6); try { + System.out.println("Loading " + clsName); final Class<?> c = Class.forName( - s.replace('/', '.').substring(0, s.length() - 6), + clsName, false, systemClassLoader); return test(c, addExports); + } catch (VerifyError ve) { + System.err.println("VerifyError for " + clsName); + ve.printStackTrace(System.err); + failed.add(s); } catch (Exception t) { t.printStackTrace(System.err); failed.add(s); diff --git a/jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh b/jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh index 3872f813ffd..a00c14077d6 100644 --- a/jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh +++ b/jdk/test/java/lang/ClassLoader/deadlock/TestCrossDelegate.sh @@ -106,7 +106,7 @@ done # run test ${TESTJAVA}${FS}bin${FS}java \ ${TESTVMOPTS} \ - -verbose:class -Xlog:classload -cp . \ + -verbose:class -Xlog:class+load -cp . \ -Dtest.classes=${TESTCLASSES} \ Starter cross # -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass \ diff --git a/jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh b/jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh index 198cd70827a..1289b4c861e 100644 --- a/jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh +++ b/jdk/test/java/lang/ClassLoader/deadlock/TestOneWayDelegate.sh @@ -102,7 +102,7 @@ done # run test ${TESTJAVA}${FS}bin${FS}java \ ${TESTVMOPTS} \ - -verbose:class -Xlog:classload -cp . \ + -verbose:class -Xlog:class+load -cp . \ -Dtest.classes=${TESTCLASSES} \ Starter one-way # -XX:+UnlockDiagnosticVMOptions -XX:+UnsyncloadClass \ diff --git a/jdk/test/java/lang/StackWalker/CountLocalSlots.java b/jdk/test/java/lang/StackWalker/CountLocalSlots.java new file mode 100644 index 00000000000..c78a4cb7bf4 --- /dev/null +++ b/jdk/test/java/lang/StackWalker/CountLocalSlots.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2016 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 8147039 + * @summary Confirm locals[] always has expected length, even for "dead" locals + * @compile LocalsAndOperands.java + * @run testng/othervm -Xcomp CountLocalSlots + */ + +import org.testng.annotations.Test; +import java.lang.StackWalker.StackFrame; + +public class CountLocalSlots { + final static boolean debug = true; + + @Test(dataProvider = "provider", dataProviderClass = LocalsAndOperands.class) + public void countLocalSlots(StackFrame... frames) { + for (StackFrame frame : frames) { + if (debug) { + System.out.println("Running countLocalSlots"); + LocalsAndOperands.dumpStackWithLocals(frames); + } + // Confirm expected number of locals + String methodName = frame.getMethodName(); + Integer expectedObj = (Integer) LocalsAndOperands.Tester.NUM_LOCALS.get(methodName); + if (expectedObj == null) { + if (!debug) { LocalsAndOperands.dumpStackWithLocals(frames); } + throw new RuntimeException("No NUM_LOCALS entry for " + + methodName + "(). Update test?"); + } + Object[] locals = (Object[]) LocalsAndOperands.invokeGetLocals(frame); + if (locals.length != expectedObj) { + if (!debug) { LocalsAndOperands.dumpStackWithLocals(frames); } + throw new RuntimeException(methodName + "(): number of locals (" + + locals.length + ") did not match expected (" + expectedObj + ")"); + } + } + } +} diff --git a/jdk/test/java/lang/StackWalker/LocalsAndOperands.java b/jdk/test/java/lang/StackWalker/LocalsAndOperands.java index 63a6731a164..b253ab27e81 100644 --- a/jdk/test/java/lang/StackWalker/LocalsAndOperands.java +++ b/jdk/test/java/lang/StackWalker/LocalsAndOperands.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016 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,17 +23,20 @@ /* * @test - * @bug 8020968 - * @summary Sanity test for locals and operands - * @run main LocalsAndOperands + * @bug 8020968 8147039 + * @summary Tests for locals and operands + * @run testng LocalsAndOperands */ +import org.testng.annotations.*; import java.lang.StackWalker.StackFrame; import java.lang.reflect.*; -import java.util.List; -import java.util.stream.Collectors; +import java.util.*; +import java.util.stream.*; public class LocalsAndOperands { + static final boolean debug = true; + static Class<?> liveStackFrameClass; static Class<?> primitiveValueClass; static StackWalker extendedWalker; @@ -41,92 +44,319 @@ public class LocalsAndOperands { static Method getOperands; static Method getMonitors; static Method primitiveType; - public static void main(String... args) throws Exception { - liveStackFrameClass = Class.forName("java.lang.LiveStackFrame"); - primitiveValueClass = Class.forName("java.lang.LiveStackFrame$PrimitiveValue"); - getLocals = liveStackFrameClass.getDeclaredMethod("getLocals"); - getLocals.setAccessible(true); + static { + try { + liveStackFrameClass = Class.forName("java.lang.LiveStackFrame"); + primitiveValueClass = Class.forName("java.lang.LiveStackFrame$PrimitiveValue"); - getOperands = liveStackFrameClass.getDeclaredMethod("getStack"); - getOperands.setAccessible(true); + getLocals = liveStackFrameClass.getDeclaredMethod("getLocals"); + getLocals.setAccessible(true); - getMonitors = liveStackFrameClass.getDeclaredMethod("getMonitors"); - getMonitors.setAccessible(true); + getOperands = liveStackFrameClass.getDeclaredMethod("getStack"); + getOperands.setAccessible(true); - primitiveType = primitiveValueClass.getDeclaredMethod("type"); - primitiveType.setAccessible(true); + getMonitors = liveStackFrameClass.getDeclaredMethod("getMonitors"); + getMonitors.setAccessible(true); - Method method = liveStackFrameClass.getMethod("getStackWalker"); - method.setAccessible(true); - extendedWalker = (StackWalker) method.invoke(null); - new LocalsAndOperands(extendedWalker, true).test(); + primitiveType = primitiveValueClass.getDeclaredMethod("type"); + primitiveType.setAccessible(true); - // no access to local and operands. - new LocalsAndOperands(StackWalker.getInstance(), false).test(); + Method method = liveStackFrameClass.getMethod("getStackWalker"); + method.setAccessible(true); + extendedWalker = (StackWalker) method.invoke(null); + } catch (Throwable t) { throw new RuntimeException(t); } } - private final StackWalker walker; - private final boolean extended; - LocalsAndOperands(StackWalker walker, boolean extended) { - this.walker = walker; - this.extended = extended; + /** Helper method to return a StackFrame's locals */ + static Object[] invokeGetLocals(StackFrame arg) { + try { + return (Object[]) getLocals.invoke(arg); + } catch (Exception e) { throw new RuntimeException(e); } } - synchronized void test() throws Exception { - int x = 10; - char c = 'z'; - String hi = "himom"; - long l = 1000000L; - double d = 3.1415926; + /***************** + * DataProviders * + *****************/ - List<StackWalker.StackFrame> frames = walker.walk(s -> s.collect(Collectors.toList())); - if (extended) { - for (StackWalker.StackFrame f : frames) { - System.out.println("frame: " + f); - Object[] locals = (Object[]) getLocals.invoke(f); + /** Calls testLocals() and provides LiveStackFrames for testLocals* methods */ + @DataProvider + public static StackFrame[][] provider() { + return new StackFrame[][] { + new Tester().testLocals() + }; + } + + /** + * Calls testLocalsKeepAlive() and provides LiveStackFrames for testLocals* methods. + * Local variables in testLocalsKeepAlive() are ensured to not become dead. + */ + @DataProvider + public static StackFrame[][] keepAliveProvider() { + return new StackFrame[][] { + new Tester().testLocalsKeepAlive() + }; + } + + /** + * Provides StackFrames from a StackWalker without the LOCALS_AND_OPERANDS + * option. + */ + @DataProvider + public static StackFrame[][] noLocalsProvider() { + // Use default StackWalker + return new StackFrame[][] { + new Tester(StackWalker.getInstance(), true).testLocals() + }; + } + + /** + * Calls testLocals() and provides LiveStackFrames for *all* called methods, + * including test infrastructure (jtreg, testng, etc) + * + */ + @DataProvider + public static StackFrame[][] unfilteredProvider() { + return new StackFrame[][] { + new Tester(extendedWalker, false).testLocals() + }; + } + + /**************** + * Test methods * + ****************/ + + /** + * Check for expected local values and types in the LiveStackFrame + */ + @Test(dataProvider = "keepAliveProvider") + public static void checkLocalValues(StackFrame... frames) { + if (debug) { + System.out.println("Running checkLocalValues"); + dumpStackWithLocals(frames); + } + Arrays.stream(frames).filter(f -> f.getMethodName() + .equals("testLocalsKeepAlive")) + .forEach( + f -> { + Object[] locals = invokeGetLocals(f); for (int i = 0; i < locals.length; i++) { - System.out.format(" local %d: %s type %s\n", i, locals[i], type(locals[i])); + // Value + String expected = Tester.LOCAL_VALUES[i]; + Object observed = locals[i]; + if (expected != null /* skip nulls in golden values */ && + !expected.equals(observed.toString())) { + System.err.println("Local value mismatch:"); + if (!debug) { dumpStackWithLocals(frames); } + throw new RuntimeException("local " + i + " value is " + + observed + ", expected " + expected); + } - // check for non-null locals in LocalsAndOperands.test() - if (f.getClassName().equals("LocalsAndOperands") && - f.getMethodName().equals("test")) { - if (locals[i] == null) { - throw new RuntimeException("kept-alive locals should not be null"); - } + // Type + expected = Tester.LOCAL_TYPES[i]; + observed = type(locals[i]); + if (expected != null /* skip nulls in golden values */ && + !expected.equals(observed)) { + System.err.println("Local type mismatch:"); + if (!debug) { dumpStackWithLocals(frames); } + throw new RuntimeException("local " + i + " type is " + + observed + ", expected " + expected); } } - - Object[] operands = (Object[]) getOperands.invoke(f); - for (int i = 0; i < operands.length; i++) { - System.out.format(" operand %d: %s type %s%n", i, operands[i], - type(operands[i])); - } - - Object[] monitors = (Object[]) getMonitors.invoke(f); - for (int i = 0; i < monitors.length; i++) { - System.out.format(" monitor %d: %s%n", i, monitors[i]); - } } - } else { - for (StackFrame f : frames) { - if (liveStackFrameClass.isInstance(f)) { - throw new RuntimeException("should not be LiveStackFrame"); - } - } - } - // Use local variables so they stay alive - System.out.println("Stayin' alive: "+x+" "+c+" "+hi+" "+l+" "+d); + ); } - String type(Object o) throws Exception { - if (o == null) { - return "null"; - } else if (primitiveValueClass.isInstance(o)) { - char c = (char)primitiveType.invoke(o); - return String.valueOf(c); - } else { - return o.getClass().getName(); + /** + * Basic sanity check for locals and operands + */ + @Test(dataProvider = "provider") + public static void sanityCheck(StackFrame... frames) { + if (debug) { + System.out.println("Running sanityCheck"); } + try { + Stream<StackFrame> stream = Arrays.stream(frames); + if (debug) { + stream.forEach(LocalsAndOperands::printLocals); + } else { + System.out.println(stream.count() + " frames"); + } + } catch (Throwable t) { + dumpStackWithLocals(frames); + throw t; + } + } + + /** + * Sanity check for locals and operands, including testng/jtreg frames + */ + @Test(dataProvider = "unfilteredProvider") + public static void unfilteredSanityCheck(StackFrame... frames) { + if (debug) { + System.out.println("Running unfilteredSanityCheck"); + } + try { + Stream<StackFrame> stream = Arrays.stream(frames); + if (debug) { + stream.forEach(f -> { System.out.println(f + ": " + + invokeGetLocals(f).length + " locals"); } ); + } else { + System.out.println(stream.count() + " frames"); + } + } catch (Throwable t) { + dumpStackWithLocals(frames); + throw t; + } + } + + /** + * Test that LiveStackFrames are not provided with the default StackWalker + * options. + */ + @Test(dataProvider = "noLocalsProvider") + public static void withoutLocalsAndOperands(StackFrame... frames) { + for (StackFrame frame : frames) { + if (liveStackFrameClass.isInstance(frame)) { + throw new RuntimeException("should not be LiveStackFrame"); + } + } + } + + static class Tester { + private StackWalker walker; + private boolean filter = true; // Filter out testng/jtreg/etc frames? + + Tester() { + this.walker = extendedWalker; + } + + Tester(StackWalker walker, boolean filter) { + this.walker = walker; + this.filter = filter; + } + + /** + * Perform stackwalk without keeping local variables alive and return an + * array of the collected StackFrames + */ + private synchronized StackFrame[] testLocals() { + // Unused local variables will become dead + int x = 10; + char c = 'z'; + String hi = "himom"; + long l = 1000000L; + double d = 3.1415926; + + if (filter) { + return walker.walk(s -> s.filter(f -> TEST_METHODS.contains(f + .getMethodName())).collect(Collectors.toList())) + .toArray(new StackFrame[0]); + } else { + return walker.walk(s -> s.collect(Collectors.toList())) + .toArray(new StackFrame[0]); + } + } + + /** + * Perform stackwalk, keeping local variables alive, and return a list of + * the collected StackFrames + */ + private synchronized StackFrame[] testLocalsKeepAlive() { + int x = 10; + char c = 'z'; + String hi = "himom"; + long l = 1000000L; + double d = 3.1415926; + + List<StackWalker.StackFrame> frames; + if (filter) { + frames = walker.walk(s -> s.filter(f -> TEST_METHODS.contains(f + .getMethodName())).collect(Collectors.toList())); + } else { + frames = walker.walk(s -> s.collect(Collectors.toList())); + } + + // Use local variables so they stay alive + System.out.println("Stayin' alive: "+x+" "+c+" "+hi+" "+l+" "+d); + return frames.toArray(new StackFrame[0]); // FIXME: convert to Array here + } + + // Expected values for locals in testLocals() & testLocalsKeepAlive() + // TODO: use real values instead of Strings, rebuild doubles & floats, etc + private final static String[] LOCAL_VALUES = new String[] { + null, // skip, LocalsAndOperands$Tester@XXX identity is different each run + "10", + "122", + "himom", + "0", + null, // skip, fix in 8156073 + null, // skip, fix in 8156073 + null, // skip, fix in 8156073 + "0" + }; + + // Expected types for locals in testLocals() & testLocalsKeepAlive() + // TODO: use real types + private final static String[] LOCAL_TYPES = new String[] { + null, // skip + "I", + "I", + "java.lang.String", + "I", + "I", + "I", + "I", + "I" + }; + + final static Map NUM_LOCALS = Map.of("testLocals", 8, + "testLocalsKeepAlive", + LOCAL_VALUES.length); + private final static Collection<String> TEST_METHODS = NUM_LOCALS.keySet(); + } + + /** + * Print stack trace with locals + */ + public static void dumpStackWithLocals(StackFrame...frames) { + Arrays.stream(frames).forEach(LocalsAndOperands::printLocals); + } + + /** + * Print the StackFrame and an indexed list of its locals + */ + public static void printLocals(StackWalker.StackFrame frame) { + try { + System.out.println(frame); + Object[] locals = (Object[]) getLocals.invoke(frame); + for (int i = 0; i < locals.length; i++) { + System.out.format(" local %d: %s type %s\n", i, locals[i], type(locals[i])); + } + + Object[] operands = (Object[]) getOperands.invoke(frame); + for (int i = 0; i < operands.length; i++) { + System.out.format(" operand %d: %s type %s%n", i, operands[i], + type(operands[i])); + } + + Object[] monitors = (Object[]) getMonitors.invoke(frame); + for (int i = 0; i < monitors.length; i++) { + System.out.format(" monitor %d: %s%n", i, monitors[i]); + } + } catch (Exception e) { throw new RuntimeException(e); } + } + + private static String type(Object o) { + try { + if (o == null) { + return "null"; + } else if (primitiveValueClass.isInstance(o)) { + char c = (char)primitiveType.invoke(o); + return String.valueOf(c); + } else { + return o.getClass().getName(); + } + } catch(Exception e) { throw new RuntimeException(e); } } } diff --git a/jdk/test/java/lang/StackWalker/LocalsCrash.java b/jdk/test/java/lang/StackWalker/LocalsCrash.java new file mode 100644 index 00000000000..b50dd263f00 --- /dev/null +++ b/jdk/test/java/lang/StackWalker/LocalsCrash.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016 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 8147039 + * @summary Test for -Xcomp crash that happened before 8147039 fix + * @run testng/othervm -Xcomp LocalsCrash + */ + +import org.testng.annotations.*; +import java.lang.reflect.*; +import java.util.List; +import java.util.stream.Collectors; + +public class LocalsCrash { + static Class<?> liveStackFrameClass; + static Method getStackWalker; + + static { + try { + liveStackFrameClass = Class.forName("java.lang.LiveStackFrame"); + getStackWalker = liveStackFrameClass.getMethod("getStackWalker"); + getStackWalker.setAccessible(true); + } catch (Throwable t) { throw new RuntimeException(t); } + } + + private StackWalker walker; + + LocalsCrash() { + try { + walker = (StackWalker) getStackWalker.invoke(null); + } catch (Exception e) { throw new RuntimeException(e); } + } + + @Test + public void test00() { doStackWalk(); } + + @Test + public void test01() { doStackWalk(); } + + private synchronized List<StackWalker.StackFrame> doStackWalk() { + try { + // Unused local variables will become dead + int x = 10; + char c = 'z'; + String hi = "himom"; + long l = 1000000L; + double d = 3.1415926; + + return walker.walk(s -> s.collect(Collectors.toList())); + } catch (Exception e) { throw new RuntimeException(e); } + } +} diff --git a/jdk/test/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh b/jdk/test/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh index f5bb3b83179..b428a59bb28 100644 --- a/jdk/test/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh +++ b/jdk/test/java/lang/instrument/appendToClassLoaderSearch/ClassUnloadTest.sh @@ -80,5 +80,5 @@ $JAR ${TESTTOOLVMOPTS} -cfm "${TESTCLASSES}"/ClassUnloadTest.jar "${MANIFEST}" \ # Finally we run the test (cd "${TESTCLASSES}"; \ - $JAVA ${TESTVMOPTS} -Xverify:none -Xlog:classunload \ + $JAVA ${TESTVMOPTS} -Xverify:none -Xlog:class+unload \ -javaagent:ClassUnloadTest.jar ClassUnloadTest "${OTHERDIR}" Bar.jar) diff --git a/jdk/test/java/lang/invoke/ArrayLengthTest.java b/jdk/test/java/lang/invoke/ArrayLengthTest.java new file mode 100644 index 00000000000..3eabf9789c2 --- /dev/null +++ b/jdk/test/java/lang/invoke/ArrayLengthTest.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016, 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. + */ + +/* @test + * @run testng/othervm -ea -esa test.java.lang.invoke.ArrayLengthTest + */ +package test.java.lang.invoke; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; + +import static org.testng.AssertJUnit.*; + +import org.testng.annotations.*; + +public class ArrayLengthTest { + + @DataProvider + Object[][] arrayClasses() { + return new Object[][] { + {int[].class}, + {long[].class}, + {float[].class}, + {double[].class}, + {boolean[].class}, + {byte[].class}, + {short[].class}, + {char[].class}, + {Object[].class}, + {StringBuffer[].class} + }; + } + + @Test(dataProvider = "arrayClasses") + public void testArrayLength(Class<?> arrayClass) throws Throwable { + MethodHandle arrayLength = MethodHandles.arrayLength(arrayClass); + assertEquals(int.class, arrayLength.type().returnType()); + assertEquals(arrayClass, arrayLength.type().parameterType(0)); + Object array = MethodHandles.arrayConstructor(arrayClass).invoke(10); + assertEquals(10, arrayLength.invoke(array)); + } + + @Test(dataProvider = "arrayClasses", expectedExceptions = NullPointerException.class) + public void testArrayLengthInvokeNPE(Class<?> arrayClass) throws Throwable { + MethodHandle arrayLength = MethodHandles.arrayLength(arrayClass); + arrayLength.invoke(null); + } + + @Test(expectedExceptions = IllegalArgumentException.class) + public void testArrayLengthNoArray() { + MethodHandles.arrayLength(String.class); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testArrayLengthNPE() { + MethodHandles.arrayLength(null); + } + +} diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java index 59737dbeb7b..b8cbc17784d 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleBaseTest.java @@ -40,6 +40,7 @@ import static org.testng.Assert.*; abstract class VarHandleBaseTest { static final int ITERS = Integer.getInteger("iters", 1); + static final int WEAK_ATTEMPTS = Integer.getInteger("weakAttempts", 10); interface ThrowingRunnable { void run() throws Throwable; @@ -211,7 +212,6 @@ abstract class VarHandleBaseTest { } static MethodHandle findVirtual(VarHandle vh, TestAccessMode tam, MethodType mt) { - mt = vh.accessModeType(tam.toAccessMode()); MethodHandle mh; try { mh = MethodHandles.publicLookup(). @@ -221,36 +221,26 @@ abstract class VarHandleBaseTest { } catch (Exception e) { throw new RuntimeException(e); } - return bind(vh, tam, mh, mt); + return bind(vh, mh, mt); } - static MethodHandle varHandleInvokerWithAccessModeType(VarHandle vh, TestAccessMode tam, MethodType mt) { - mt = vh.accessModeType(tam.toAccessMode()); + static MethodHandle varHandleInvoker(VarHandle vh, TestAccessMode tam, MethodType mt) { MethodHandle mh = MethodHandles.varHandleInvoker( tam.toAccessMode(), mt); - return bind(vh, tam, mh, mt); + return bind(vh, mh, mt); } - static MethodHandle varHandleInvokerWithSymbolicTypeDescriptor(VarHandle vh, TestAccessMode tam, MethodType mt) { - MethodHandle mh = MethodHandles.varHandleInvoker( - tam.toAccessMode(), - mt); - - return bind(vh, tam, mh, mt); - } - - static MethodHandle varHandleExactInvokerWithAccessModeType(VarHandle vh, TestAccessMode tam, MethodType mt) { - mt = vh.accessModeType(tam.toAccessMode()); + static MethodHandle varHandleExactInvoker(VarHandle vh, TestAccessMode tam, MethodType mt) { MethodHandle mh = MethodHandles.varHandleExactInvoker( tam.toAccessMode(), mt); - return bind(vh, tam, mh, mt); + return bind(vh, mh, mt); } - private static MethodHandle bind(VarHandle vh, TestAccessMode testAccessMode, MethodHandle mh, MethodType emt) { + private static MethodHandle bind(VarHandle vh, MethodHandle mh, MethodType emt) { assertEquals(mh.type(), emt.insertParameterTypes(0, VarHandle.class), "MethodHandle type differs from access mode type"); @@ -268,33 +258,30 @@ abstract class VarHandleBaseTest { enum VarHandleToMethodHandle { VAR_HANDLE_TO_METHOD_HANDLE( "VarHandle.toMethodHandle", + true, VarHandleBaseTest::toMethodHandle), METHOD_HANDLES_LOOKUP_FIND_VIRTUAL( "Lookup.findVirtual", + false, VarHandleBaseTest::findVirtual), - METHOD_HANDLES_VAR_HANDLE_INVOKER_WITH_ACCESS_MODE_TYPE( - "MethodHandles.varHandleInvoker(accessModeType)", - VarHandleBaseTest::varHandleInvokerWithAccessModeType), - METHOD_HANDLES_VAR_HANDLE_INVOKER_WITH_SYMBOLIC_TYPE_DESCRIPTOR( - "MethodHandles.varHandleInvoker(symbolicTypeDescriptor)", - VarHandleBaseTest::varHandleInvokerWithSymbolicTypeDescriptor), - METHOD_HANDLES_VAR_HANDLE_EXACT_INVOKER_WITH_ACCESS_MODE_TYPE( - "MethodHandles.varHandleExactInvoker(accessModeType)", - VarHandleBaseTest::varHandleExactInvokerWithAccessModeType); + METHOD_HANDLES_VAR_HANDLE_INVOKER( + "MethodHandles.varHandleInvoker", + false, + VarHandleBaseTest::varHandleInvoker), + METHOD_HANDLES_VAR_HANDLE_EXACT_INVOKER( + "MethodHandles.varHandleExactInvoker", + true, + VarHandleBaseTest::varHandleExactInvoker); final String desc; + final boolean isExact; final TriFunction<VarHandle, TestAccessMode, MethodType, MethodHandle> f; - final boolean exact; - VarHandleToMethodHandle(String desc, TriFunction<VarHandle, TestAccessMode, MethodType, MethodHandle> f) { - this(desc, f, false); - } - - VarHandleToMethodHandle(String desc, TriFunction<VarHandle, TestAccessMode, MethodType, MethodHandle> f, - boolean exact) { + VarHandleToMethodHandle(String desc, boolean isExact, + TriFunction<VarHandle, TestAccessMode, MethodType, MethodHandle> f) { this.desc = desc; this.f = f; - this.exact = exact; + this.isExact = isExact; } MethodHandle apply(VarHandle vh, TestAccessMode am, MethodType mt) { @@ -363,6 +350,15 @@ abstract class VarHandleBaseTest { return amToHandle.computeIfAbsent( amt, k -> f.apply(vh, am, mt)); } + + Class<? extends Throwable> getWMTEOOrOther(Class<? extends Throwable> c) { + return f.isExact ? WrongMethodTypeException.class : c; + } + + void checkWMTEOrCCE(ThrowingRunnable r) { + checkWithThrowable(getWMTEOOrOther(ClassCastException.class), null, r); + } + } interface AccessTestAction<T> { @@ -475,4 +471,4 @@ abstract class VarHandleBaseTest { assertEquals(mt.parameterType(mt.parameterCount() - 1), vh.varType()); } } -} \ No newline at end of file +} diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java index 021091484e6..06d2a65b1dd 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessBoolean * @run testng/othervm -Diters=20000 VarHandleTestAccessBoolean * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessBoolean + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestAccessBoolean */ import org.testng.annotations.BeforeClass; @@ -292,6 +293,10 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, true, false); }); + checkUOE(() -> { + boolean r = (boolean) vh.getAndSet(recv, true); + }); + checkUOE(() -> { boolean o = (boolean) vh.getAndAdd(recv, true); }); @@ -378,6 +383,10 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(true, false); }); + checkUOE(() -> { + boolean r = (boolean) vh.getAndSet(true); + }); + checkUOE(() -> { boolean o = (boolean) vh.getAndAdd(true); }); @@ -454,6 +463,10 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, true, false); }); + checkUOE(() -> { + boolean r = (boolean) vh.getAndSet(recv, true); + }); + checkUOE(() -> { boolean o = (boolean) vh.getAndAdd(recv, true); }); @@ -530,6 +543,10 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(true, false); }); + checkUOE(() -> { + boolean r = (boolean) vh.getAndSet(true); + }); + checkUOE(() -> { boolean o = (boolean) vh.getAndAdd(true); }); @@ -613,6 +630,10 @@ public class VarHandleTestAccessBoolean extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(array, i, true, false); }); + checkUOE(() -> { + boolean r = (boolean) vh.getAndSet(array, i, true); + }); + checkUOE(() -> { boolean o = (boolean) vh.getAndAdd(array, i, true); }); diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java index e550815156c..2ba0afbef2d 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessByte * @run testng/othervm -Diters=20000 VarHandleTestAccessByte * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessByte + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestAccessByte */ import org.testng.annotations.BeforeClass; @@ -292,6 +293,10 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2); }); + checkUOE(() -> { + byte r = (byte) vh.getAndSet(recv, (byte)1); + }); + checkUOE(() -> { byte o = (byte) vh.getAndAdd(recv, (byte)1); }); @@ -378,6 +383,10 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2); }); + checkUOE(() -> { + byte r = (byte) vh.getAndSet((byte)1); + }); + checkUOE(() -> { byte o = (byte) vh.getAndAdd((byte)1); }); @@ -454,6 +463,10 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, (byte)1, (byte)2); }); + checkUOE(() -> { + byte r = (byte) vh.getAndSet(recv, (byte)1); + }); + checkUOE(() -> { byte o = (byte) vh.getAndAdd(recv, (byte)1); }); @@ -530,6 +543,10 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease((byte)1, (byte)2); }); + checkUOE(() -> { + byte r = (byte) vh.getAndSet((byte)1); + }); + checkUOE(() -> { byte o = (byte) vh.getAndAdd((byte)1); }); @@ -613,6 +630,10 @@ public class VarHandleTestAccessByte extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(array, i, (byte)1, (byte)2); }); + checkUOE(() -> { + byte r = (byte) vh.getAndSet(array, i, (byte)1); + }); + checkUOE(() -> { byte o = (byte) vh.getAndAdd(array, i, (byte)1); }); diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java index 5c13c6d6677..bcc42a3c335 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessChar * @run testng/othervm -Diters=20000 VarHandleTestAccessChar * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessChar + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestAccessChar */ import org.testng.annotations.BeforeClass; @@ -292,6 +293,10 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, 'a', 'b'); }); + checkUOE(() -> { + char r = (char) vh.getAndSet(recv, 'a'); + }); + checkUOE(() -> { char o = (char) vh.getAndAdd(recv, 'a'); }); @@ -378,6 +383,10 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease('a', 'b'); }); + checkUOE(() -> { + char r = (char) vh.getAndSet('a'); + }); + checkUOE(() -> { char o = (char) vh.getAndAdd('a'); }); @@ -454,6 +463,10 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, 'a', 'b'); }); + checkUOE(() -> { + char r = (char) vh.getAndSet(recv, 'a'); + }); + checkUOE(() -> { char o = (char) vh.getAndAdd(recv, 'a'); }); @@ -530,6 +543,10 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease('a', 'b'); }); + checkUOE(() -> { + char r = (char) vh.getAndSet('a'); + }); + checkUOE(() -> { char o = (char) vh.getAndAdd('a'); }); @@ -613,6 +630,10 @@ public class VarHandleTestAccessChar extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(array, i, 'a', 'b'); }); + checkUOE(() -> { + char r = (char) vh.getAndSet(array, i, 'a'); + }); + checkUOE(() -> { char o = (char) vh.getAndAdd(array, i, 'a'); }); diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java index 65125e3f62e..74f0765f709 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessDouble * @run testng/othervm -Diters=20000 VarHandleTestAccessDouble * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessDouble + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestAccessDouble */ import org.testng.annotations.BeforeClass; @@ -292,6 +293,10 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d); }); + checkUOE(() -> { + double r = (double) vh.getAndSet(recv, 1.0d); + }); + checkUOE(() -> { double o = (double) vh.getAndAdd(recv, 1.0d); }); @@ -378,6 +383,10 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(1.0d, 2.0d); }); + checkUOE(() -> { + double r = (double) vh.getAndSet(1.0d); + }); + checkUOE(() -> { double o = (double) vh.getAndAdd(1.0d); }); @@ -454,6 +463,10 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, 1.0d, 2.0d); }); + checkUOE(() -> { + double r = (double) vh.getAndSet(recv, 1.0d); + }); + checkUOE(() -> { double o = (double) vh.getAndAdd(recv, 1.0d); }); @@ -530,6 +543,10 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(1.0d, 2.0d); }); + checkUOE(() -> { + double r = (double) vh.getAndSet(1.0d); + }); + checkUOE(() -> { double o = (double) vh.getAndAdd(1.0d); }); @@ -613,6 +630,10 @@ public class VarHandleTestAccessDouble extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(array, i, 1.0d, 2.0d); }); + checkUOE(() -> { + double r = (double) vh.getAndSet(array, i, 1.0d); + }); + checkUOE(() -> { double o = (double) vh.getAndAdd(array, i, 1.0d); }); diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java index 8e7491ad45a..241e0897414 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessFloat * @run testng/othervm -Diters=20000 VarHandleTestAccessFloat * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessFloat + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestAccessFloat */ import org.testng.annotations.BeforeClass; @@ -292,6 +293,10 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f); }); + checkUOE(() -> { + float r = (float) vh.getAndSet(recv, 1.0f); + }); + checkUOE(() -> { float o = (float) vh.getAndAdd(recv, 1.0f); }); @@ -378,6 +383,10 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(1.0f, 2.0f); }); + checkUOE(() -> { + float r = (float) vh.getAndSet(1.0f); + }); + checkUOE(() -> { float o = (float) vh.getAndAdd(1.0f); }); @@ -454,6 +463,10 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, 1.0f, 2.0f); }); + checkUOE(() -> { + float r = (float) vh.getAndSet(recv, 1.0f); + }); + checkUOE(() -> { float o = (float) vh.getAndAdd(recv, 1.0f); }); @@ -530,6 +543,10 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(1.0f, 2.0f); }); + checkUOE(() -> { + float r = (float) vh.getAndSet(1.0f); + }); + checkUOE(() -> { float o = (float) vh.getAndAdd(1.0f); }); @@ -613,6 +630,10 @@ public class VarHandleTestAccessFloat extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(array, i, 1.0f, 2.0f); }); + checkUOE(() -> { + float r = (float) vh.getAndSet(array, i, 1.0f); + }); + checkUOE(() -> { float o = (float) vh.getAndAdd(array, i, 1.0f); }); diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java index bfcb5feec4c..3adb9b83fa7 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessInt * @run testng/othervm -Diters=20000 VarHandleTestAccessInt * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessInt + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestAccessInt */ import org.testng.annotations.BeforeClass; @@ -402,29 +403,41 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } { - boolean r = vh.weakCompareAndSet(recv, 1, 2); - assertEquals(r, true, "weakCompareAndSet int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(recv, 1, 2); + } + assertEquals(success, true, "weakCompareAndSet int"); int x = (int) vh.get(recv); assertEquals(x, 2, "weakCompareAndSet int value"); } { - boolean r = vh.weakCompareAndSetAcquire(recv, 2, 1); - assertEquals(r, true, "weakCompareAndSetAcquire int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(recv, 2, 1); + } + assertEquals(success, true, "weakCompareAndSetAcquire int"); int x = (int) vh.get(recv); assertEquals(x, 1, "weakCompareAndSetAcquire int"); } { - boolean r = vh.weakCompareAndSetRelease(recv, 1, 2); - assertEquals(r, true, "weakCompareAndSetRelease int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(recv, 1, 2); + } + assertEquals(success, true, "weakCompareAndSetRelease int"); int x = (int) vh.get(recv); assertEquals(x, 2, "weakCompareAndSetRelease int"); } { - boolean r = vh.weakCompareAndSetVolatile(recv, 2, 1); - assertEquals(r, true, "weakCompareAndSetVolatile int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetVolatile(recv, 2, 1); + } + assertEquals(success, true, "weakCompareAndSetVolatile int"); int x = (int) vh.get(recv); assertEquals(x, 1, "weakCompareAndSetVolatile int value"); } @@ -543,36 +556,48 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } { - boolean r = (boolean) vh.weakCompareAndSet(1, 2); - assertEquals(r, true, "weakCompareAndSet int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(1, 2); + } + assertEquals(success, true, "weakCompareAndSet int"); int x = (int) vh.get(); assertEquals(x, 2, "weakCompareAndSet int value"); } { - boolean r = (boolean) vh.weakCompareAndSetAcquire(2, 1); - assertEquals(r, true, "weakCompareAndSetAcquire int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(2, 1); + } + assertEquals(success, true, "weakCompareAndSetAcquire int"); int x = (int) vh.get(); assertEquals(x, 1, "weakCompareAndSetAcquire int"); } { - boolean r = (boolean) vh.weakCompareAndSetRelease(1, 2); - assertEquals(r, true, "weakCompareAndSetRelease int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(1, 2); + } + assertEquals(success, true, "weakCompareAndSetRelease int"); int x = (int) vh.get(); assertEquals(x, 2, "weakCompareAndSetRelease int"); } { - boolean r = (boolean) vh.weakCompareAndSetVolatile(2, 1); - assertEquals(r, true, "weakCompareAndSetVolatile int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(2, 1); + } + assertEquals(success, true, "weakCompareAndSetVolatile int"); int x = (int) vh.get(); - assertEquals(x, 1, "weakCompareAndSetVolatile int value"); + assertEquals(x, 1, "weakCompareAndSetVolatile int"); } // Compare set and get { - int o = (int) vh.getAndSet( 2); + int o = (int) vh.getAndSet(2); assertEquals(o, 1, "getAndSet int"); int x = (int) vh.get(); assertEquals(x, 2, "getAndSet int value"); @@ -687,31 +712,43 @@ public class VarHandleTestAccessInt extends VarHandleBaseTest { } { - boolean r = vh.weakCompareAndSet(array, i, 1, 2); - assertEquals(r, true, "weakCompareAndSet int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, 1, 2); + } + assertEquals(success, true, "weakCompareAndSet int"); int x = (int) vh.get(array, i); assertEquals(x, 2, "weakCompareAndSet int value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, 2, 1); - assertEquals(r, true, "weakCompareAndSetAcquire int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, 2, 1); + } + assertEquals(success, true, "weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); assertEquals(x, 1, "weakCompareAndSetAcquire int"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, 1, 2); - assertEquals(r, true, "weakCompareAndSetRelease int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, 1, 2); + } + assertEquals(success, true, "weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); assertEquals(x, 2, "weakCompareAndSetRelease int"); } { - boolean r = vh.weakCompareAndSetVolatile(array, i, 2, 1); - assertEquals(r, true, "weakCompareAndSetVolatile int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetVolatile(array, i, 2, 1); + } + assertEquals(success, true, "weakCompareAndSetVolatile int"); int x = (int) vh.get(array, i); - assertEquals(x, 1, "weakCompareAndSetVolatile int value"); + assertEquals(x, 1, "weakCompareAndSetVolatile int"); } // Compare set and get diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java index 1f02bed9045..9afb2de8320 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessLong * @run testng/othervm -Diters=20000 VarHandleTestAccessLong * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessLong + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestAccessLong */ import org.testng.annotations.BeforeClass; @@ -402,29 +403,41 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } { - boolean r = vh.weakCompareAndSet(recv, 1L, 2L); - assertEquals(r, true, "weakCompareAndSet long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(recv, 1L, 2L); + } + assertEquals(success, true, "weakCompareAndSet long"); long x = (long) vh.get(recv); assertEquals(x, 2L, "weakCompareAndSet long value"); } { - boolean r = vh.weakCompareAndSetAcquire(recv, 2L, 1L); - assertEquals(r, true, "weakCompareAndSetAcquire long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(recv, 2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetAcquire long"); long x = (long) vh.get(recv); assertEquals(x, 1L, "weakCompareAndSetAcquire long"); } { - boolean r = vh.weakCompareAndSetRelease(recv, 1L, 2L); - assertEquals(r, true, "weakCompareAndSetRelease long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(recv, 1L, 2L); + } + assertEquals(success, true, "weakCompareAndSetRelease long"); long x = (long) vh.get(recv); assertEquals(x, 2L, "weakCompareAndSetRelease long"); } { - boolean r = vh.weakCompareAndSetVolatile(recv, 2L, 1L); - assertEquals(r, true, "weakCompareAndSetVolatile long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetVolatile(recv, 2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetVolatile long"); long x = (long) vh.get(recv); assertEquals(x, 1L, "weakCompareAndSetVolatile long value"); } @@ -543,36 +556,48 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } { - boolean r = (boolean) vh.weakCompareAndSet(1L, 2L); - assertEquals(r, true, "weakCompareAndSet long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(1L, 2L); + } + assertEquals(success, true, "weakCompareAndSet long"); long x = (long) vh.get(); assertEquals(x, 2L, "weakCompareAndSet long value"); } { - boolean r = (boolean) vh.weakCompareAndSetAcquire(2L, 1L); - assertEquals(r, true, "weakCompareAndSetAcquire long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetAcquire long"); long x = (long) vh.get(); assertEquals(x, 1L, "weakCompareAndSetAcquire long"); } { - boolean r = (boolean) vh.weakCompareAndSetRelease(1L, 2L); - assertEquals(r, true, "weakCompareAndSetRelease long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(1L, 2L); + } + assertEquals(success, true, "weakCompareAndSetRelease long"); long x = (long) vh.get(); assertEquals(x, 2L, "weakCompareAndSetRelease long"); } { - boolean r = (boolean) vh.weakCompareAndSetVolatile(2L, 1L); - assertEquals(r, true, "weakCompareAndSetVolatile long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetVolatile long"); long x = (long) vh.get(); - assertEquals(x, 1L, "weakCompareAndSetVolatile long value"); + assertEquals(x, 1L, "weakCompareAndSetVolatile long"); } // Compare set and get { - long o = (long) vh.getAndSet( 2L); + long o = (long) vh.getAndSet(2L); assertEquals(o, 1L, "getAndSet long"); long x = (long) vh.get(); assertEquals(x, 2L, "getAndSet long value"); @@ -687,31 +712,43 @@ public class VarHandleTestAccessLong extends VarHandleBaseTest { } { - boolean r = vh.weakCompareAndSet(array, i, 1L, 2L); - assertEquals(r, true, "weakCompareAndSet long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, 1L, 2L); + } + assertEquals(success, true, "weakCompareAndSet long"); long x = (long) vh.get(array, i); assertEquals(x, 2L, "weakCompareAndSet long value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, 2L, 1L); - assertEquals(r, true, "weakCompareAndSetAcquire long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, 2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); assertEquals(x, 1L, "weakCompareAndSetAcquire long"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, 1L, 2L); - assertEquals(r, true, "weakCompareAndSetRelease long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, 1L, 2L); + } + assertEquals(success, true, "weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); assertEquals(x, 2L, "weakCompareAndSetRelease long"); } { - boolean r = vh.weakCompareAndSetVolatile(array, i, 2L, 1L); - assertEquals(r, true, "weakCompareAndSetVolatile long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetVolatile(array, i, 2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetVolatile long"); long x = (long) vh.get(array, i); - assertEquals(x, 1L, "weakCompareAndSetVolatile long value"); + assertEquals(x, 1L, "weakCompareAndSetVolatile long"); } // Compare set and get diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java index 822252f7a7d..a64ed990cb9 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessShort * @run testng/othervm -Diters=20000 VarHandleTestAccessShort * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessShort + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestAccessShort */ import org.testng.annotations.BeforeClass; @@ -292,6 +293,10 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, (short)1, (short)2); }); + checkUOE(() -> { + short r = (short) vh.getAndSet(recv, (short)1); + }); + checkUOE(() -> { short o = (short) vh.getAndAdd(recv, (short)1); }); @@ -378,6 +383,10 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease((short)1, (short)2); }); + checkUOE(() -> { + short r = (short) vh.getAndSet((short)1); + }); + checkUOE(() -> { short o = (short) vh.getAndAdd((short)1); }); @@ -454,6 +463,10 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(recv, (short)1, (short)2); }); + checkUOE(() -> { + short r = (short) vh.getAndSet(recv, (short)1); + }); + checkUOE(() -> { short o = (short) vh.getAndAdd(recv, (short)1); }); @@ -530,6 +543,10 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease((short)1, (short)2); }); + checkUOE(() -> { + short r = (short) vh.getAndSet((short)1); + }); + checkUOE(() -> { short o = (short) vh.getAndAdd((short)1); }); @@ -613,6 +630,10 @@ public class VarHandleTestAccessShort extends VarHandleBaseTest { boolean r = vh.weakCompareAndSetRelease(array, i, (short)1, (short)2); }); + checkUOE(() -> { + short r = (short) vh.getAndSet(array, i, (short)1); + }); + checkUOE(() -> { short o = (short) vh.getAndAdd(array, i, (short)1); }); diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java index 9e4ec77768b..74f08bda535 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestAccessString.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessString * @run testng/othervm -Diters=20000 VarHandleTestAccessString * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessString + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestAccessString */ import org.testng.annotations.BeforeClass; @@ -416,29 +417,41 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } { - boolean r = vh.weakCompareAndSet(recv, "foo", "bar"); - assertEquals(r, true, "weakCompareAndSet String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(recv, "foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSet String"); String x = (String) vh.get(recv); assertEquals(x, "bar", "weakCompareAndSet String value"); } { - boolean r = vh.weakCompareAndSetAcquire(recv, "bar", "foo"); - assertEquals(r, true, "weakCompareAndSetAcquire String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(recv, "bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetAcquire String"); String x = (String) vh.get(recv); assertEquals(x, "foo", "weakCompareAndSetAcquire String"); } { - boolean r = vh.weakCompareAndSetRelease(recv, "foo", "bar"); - assertEquals(r, true, "weakCompareAndSetRelease String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(recv, "foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSetRelease String"); String x = (String) vh.get(recv); assertEquals(x, "bar", "weakCompareAndSetRelease String"); } { - boolean r = vh.weakCompareAndSetVolatile(recv, "bar", "foo"); - assertEquals(r, true, "weakCompareAndSetVolatile String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetVolatile(recv, "bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetVolatile String"); String x = (String) vh.get(recv); assertEquals(x, "foo", "weakCompareAndSetVolatile String value"); } @@ -555,36 +568,48 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } { - boolean r = (boolean) vh.weakCompareAndSet("foo", "bar"); - assertEquals(r, true, "weakCompareAndSet String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet("foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSet String"); String x = (String) vh.get(); assertEquals(x, "bar", "weakCompareAndSet String value"); } { - boolean r = (boolean) vh.weakCompareAndSetAcquire("bar", "foo"); - assertEquals(r, true, "weakCompareAndSetAcquire String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire("bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetAcquire String"); String x = (String) vh.get(); assertEquals(x, "foo", "weakCompareAndSetAcquire String"); } { - boolean r = (boolean) vh.weakCompareAndSetRelease("foo", "bar"); - assertEquals(r, true, "weakCompareAndSetRelease String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease("foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSetRelease String"); String x = (String) vh.get(); assertEquals(x, "bar", "weakCompareAndSetRelease String"); } { - boolean r = (boolean) vh.weakCompareAndSetVolatile("bar", "foo"); - assertEquals(r, true, "weakCompareAndSetVolatile String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease("bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetVolatile String"); String x = (String) vh.get(); - assertEquals(x, "foo", "weakCompareAndSetVolatile String value"); + assertEquals(x, "foo", "weakCompareAndSetVolatile String"); } // Compare set and get { - String o = (String) vh.getAndSet( "bar"); + String o = (String) vh.getAndSet("bar"); assertEquals(o, "foo", "getAndSet String"); String x = (String) vh.get(); assertEquals(x, "bar", "getAndSet String value"); @@ -697,31 +722,43 @@ public class VarHandleTestAccessString extends VarHandleBaseTest { } { - boolean r = vh.weakCompareAndSet(array, i, "foo", "bar"); - assertEquals(r, true, "weakCompareAndSet String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, "foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSet String"); String x = (String) vh.get(array, i); assertEquals(x, "bar", "weakCompareAndSet String value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, "bar", "foo"); - assertEquals(r, true, "weakCompareAndSetAcquire String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, "bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetAcquire String"); String x = (String) vh.get(array, i); assertEquals(x, "foo", "weakCompareAndSetAcquire String"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, "foo", "bar"); - assertEquals(r, true, "weakCompareAndSetRelease String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, "foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSetRelease String"); String x = (String) vh.get(array, i); assertEquals(x, "bar", "weakCompareAndSetRelease String"); } { - boolean r = vh.weakCompareAndSetVolatile(array, i, "bar", "foo"); - assertEquals(r, true, "weakCompareAndSetVolatile String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetVolatile(array, i, "bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetVolatile String"); String x = (String) vh.get(array, i); - assertEquals(x, "foo", "weakCompareAndSetVolatile String value"); + assertEquals(x, "foo", "weakCompareAndSetVolatile String"); } // Compare set and get diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java index 8159e16ff62..a2221b50a20 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsChar.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsChar * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsChar * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsChar + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestByteArrayAsChar */ import org.testng.annotations.DataProvider; @@ -50,7 +51,7 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { static final char VALUE_2 = (char)0x1112; - static final char VALUE_3 = (char)0x2122; + static final char VALUE_3 = (char)0xFFFE; @Override @@ -253,6 +254,10 @@ public class VarHandleTestByteArrayAsChar extends VarHandleBaseByteArrayTest { checkROBE(() -> { vh.setOpaque(array, ci, VALUE_1); }); + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + checkUOE(() -> { char r = (char) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); }); diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java index a327b00fb77..79305710ce2 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsDouble.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsDouble * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsDouble * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsDouble + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestByteArrayAsDouble */ import org.testng.annotations.DataProvider; @@ -50,7 +51,7 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { static final double VALUE_2 = 0x1112131415161718L; - static final double VALUE_3 = 0x2122232425262728L; + static final double VALUE_3 = 0xFFFEFDFCFBFAF9F8L; @Override @@ -254,9 +255,7 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { checkROBE(() -> { double o = (double) vh.getAndSet(array, ci, VALUE_1); }); - checkUOE(() -> { - boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); - }); + checkUOE(() -> { double o = (double) vh.getAndAdd(array, ci, VALUE_1); @@ -700,22 +699,31 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { } { - boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSet double"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSet double"); double x = (double) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSet double value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); - assertEquals(r, true, "weakCompareAndSetAcquire double"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + } + assertEquals(success, true, "weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSetRelease double"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSetRelease double"); } @@ -840,22 +848,31 @@ public class VarHandleTestByteArrayAsDouble extends VarHandleBaseByteArrayTest { } { - boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSet double"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSet double"); double x = (double) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSet double value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); - assertEquals(r, true, "weakCompareAndSetAcquire double"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + } + assertEquals(success, true, "weakCompareAndSetAcquire double"); double x = (double) vh.get(array, i); assertEquals(x, VALUE_1, "weakCompareAndSetAcquire double"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSetRelease double"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSetRelease double"); double x = (double) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSetRelease double"); } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java index 196c8101723..b3545b4f69c 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsFloat.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsFloat * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsFloat * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsFloat + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestByteArrayAsFloat */ import org.testng.annotations.DataProvider; @@ -50,7 +51,7 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { static final float VALUE_2 = 0x11121314; - static final float VALUE_3 = 0x21222324; + static final float VALUE_3 = 0xFFFEFDFC; @Override @@ -254,9 +255,7 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { checkROBE(() -> { float o = (float) vh.getAndSet(array, ci, VALUE_1); }); - checkUOE(() -> { - boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); - }); + checkUOE(() -> { float o = (float) vh.getAndAdd(array, ci, VALUE_1); @@ -700,22 +699,31 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { } { - boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSet float"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSet float"); float x = (float) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSet float value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); - assertEquals(r, true, "weakCompareAndSetAcquire float"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + } + assertEquals(success, true, "weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSetRelease float"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSetRelease float"); } @@ -840,22 +848,31 @@ public class VarHandleTestByteArrayAsFloat extends VarHandleBaseByteArrayTest { } { - boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSet float"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSet float"); float x = (float) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSet float value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); - assertEquals(r, true, "weakCompareAndSetAcquire float"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + } + assertEquals(success, true, "weakCompareAndSetAcquire float"); float x = (float) vh.get(array, i); assertEquals(x, VALUE_1, "weakCompareAndSetAcquire float"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSetRelease float"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSetRelease float"); float x = (float) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSetRelease float"); } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java index 400c20605c5..b733bb34054 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsInt.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsInt * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsInt * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsInt + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestByteArrayAsInt */ import org.testng.annotations.DataProvider; @@ -50,7 +51,7 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { static final int VALUE_2 = 0x11121314; - static final int VALUE_3 = 0x21222324; + static final int VALUE_3 = 0xFFFEFDFC; @Override @@ -247,9 +248,7 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { checkROBE(() -> { int o = (int) vh.getAndSet(array, ci, VALUE_1); }); - checkUOE(() -> { - boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); - }); + checkROBE(() -> { int o = (int) vh.getAndAdd(array, ci, VALUE_1); @@ -714,22 +713,31 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { } { - boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSet int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSet int"); int x = (int) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSet int value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); - assertEquals(r, true, "weakCompareAndSetAcquire int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + } + assertEquals(success, true, "weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); assertEquals(x, VALUE_1, "weakCompareAndSetAcquire int"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSetRelease int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSetRelease int"); } @@ -863,22 +871,31 @@ public class VarHandleTestByteArrayAsInt extends VarHandleBaseByteArrayTest { } { - boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSet int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSet int"); int x = (int) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSet int value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); - assertEquals(r, true, "weakCompareAndSetAcquire int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + } + assertEquals(success, true, "weakCompareAndSetAcquire int"); int x = (int) vh.get(array, i); assertEquals(x, VALUE_1, "weakCompareAndSetAcquire int"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSetRelease int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSetRelease int"); int x = (int) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSetRelease int"); } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java index a0cabc8653a..88bf198272b 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsLong.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsLong * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsLong * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsLong + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestByteArrayAsLong */ import org.testng.annotations.DataProvider; @@ -50,7 +51,7 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { static final long VALUE_2 = 0x1112131415161718L; - static final long VALUE_3 = 0x2122232425262728L; + static final long VALUE_3 = 0xFFFEFDFCFBFAF9F8L; @Override @@ -247,9 +248,7 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { checkROBE(() -> { long o = (long) vh.getAndSet(array, ci, VALUE_1); }); - checkUOE(() -> { - boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); - }); + checkROBE(() -> { long o = (long) vh.getAndAdd(array, ci, VALUE_1); @@ -714,22 +713,31 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { } { - boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSet long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSet long"); long x = (long) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSet long value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); - assertEquals(r, true, "weakCompareAndSetAcquire long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + } + assertEquals(success, true, "weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSetRelease long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSetRelease long"); } @@ -863,22 +871,31 @@ public class VarHandleTestByteArrayAsLong extends VarHandleBaseByteArrayTest { } { - boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSet long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSet long"); long x = (long) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSet long value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); - assertEquals(r, true, "weakCompareAndSetAcquire long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + } + assertEquals(success, true, "weakCompareAndSetAcquire long"); long x = (long) vh.get(array, i); assertEquals(x, VALUE_1, "weakCompareAndSetAcquire long"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSetRelease long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSetRelease long"); long x = (long) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSetRelease long"); } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java index 2632b00bd23..5ed9d6099f7 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestByteArrayAsShort.java @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAsShort * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAsShort * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAsShort + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestByteArrayAsShort */ import org.testng.annotations.DataProvider; @@ -50,7 +51,7 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { static final short VALUE_2 = (short)0x1112; - static final short VALUE_3 = (short)0x2122; + static final short VALUE_3 = (short)0xFFFE; @Override @@ -253,6 +254,10 @@ public class VarHandleTestByteArrayAsShort extends VarHandleBaseByteArrayTest { checkROBE(() -> { vh.setOpaque(array, ci, VALUE_1); }); + checkUOE(() -> { + boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); + }); + checkUOE(() -> { short r = (short) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); }); diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java index 32761fe0e3f..f43fcc1b82c 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessBoolean.java @@ -24,6 +24,7 @@ /* * @test * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessBoolean + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodHandleAccessBoolean */ import org.testng.annotations.BeforeClass; diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java index 8c36eb861c5..3d5c27e8bfd 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessByte.java @@ -24,6 +24,7 @@ /* * @test * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessByte + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodHandleAccessByte */ import org.testng.annotations.BeforeClass; diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java index fb1f3877342..bde76a69c05 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessChar.java @@ -24,6 +24,7 @@ /* * @test * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessChar + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodHandleAccessChar */ import org.testng.annotations.BeforeClass; diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java index cd2c15d04d3..de683ce6997 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessDouble.java @@ -24,6 +24,7 @@ /* * @test * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessDouble + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodHandleAccessDouble */ import org.testng.annotations.BeforeClass; diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java index 58d9e295298..99309e5081f 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessFloat.java @@ -24,6 +24,7 @@ /* * @test * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessFloat + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodHandleAccessFloat */ import org.testng.annotations.BeforeClass; diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java index 8ccf7983056..fc0e8f214f9 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessInt.java @@ -24,6 +24,7 @@ /* * @test * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessInt + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodHandleAccessInt */ import org.testng.annotations.BeforeClass; @@ -208,31 +209,43 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 1, 2); - assertEquals(r, true, "weakCompareAndSet int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 1, 2); + } + assertEquals(success, true, "weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, 2, "weakCompareAndSet int value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2, 1); - assertEquals(r, true, "weakCompareAndSetAcquire int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2, 1); + } + assertEquals(success, true, "weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, 1, "weakCompareAndSetAcquire int"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1, 2); - assertEquals(r, true, "weakCompareAndSetRelease int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1, 2); + } + assertEquals(success, true, "weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, 2, "weakCompareAndSetRelease int"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, 2, 1); - assertEquals(r, true, "weakCompareAndSetVolatile int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, 2, 1); + } + assertEquals(success, true, "weakCompareAndSetVolatile int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1, "weakCompareAndSetVolatile int value"); + assertEquals(x, 1, "weakCompareAndSetVolatile int"); } // Compare set and get @@ -349,36 +362,48 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(1, 2); - assertEquals(r, true, "weakCompareAndSet int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(1, 2); + } + assertEquals(success, true, "weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 2, "weakCompareAndSet int value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2, 1); - assertEquals(r, true, "weakCompareAndSetAcquire int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2, 1); + } + assertEquals(success, true, "weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 1, "weakCompareAndSetAcquire int"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1, 2); - assertEquals(r, true, "weakCompareAndSetRelease int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1, 2); + } + assertEquals(success, true, "weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 2, "weakCompareAndSetRelease int"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(2, 1); - assertEquals(r, true, "weakCompareAndSetVolatile int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(2, 1); + } + assertEquals(success, true, "weakCompareAndSetVolatile int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1, "weakCompareAndSetVolatile int value"); + assertEquals(x, 1, "weakCompareAndSetVolatile int"); } // Compare set and get { - int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact(2); + int o = (int) hs.get(TestAccessMode.GET_AND_SET).invokeExact( 2); assertEquals(o, 1, "getAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 2, "getAndSet int value"); @@ -493,31 +518,43 @@ public class VarHandleTestMethodHandleAccessInt extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 1, 2); - assertEquals(r, true, "weakCompareAndSet int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 1, 2); + } + assertEquals(success, true, "weakCompareAndSet int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, 2, "weakCompareAndSet int value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2, 1); - assertEquals(r, true, "weakCompareAndSetAcquire int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2, 1); + } + assertEquals(success, true, "weakCompareAndSetAcquire int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, 1, "weakCompareAndSetAcquire int"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 1, 2); - assertEquals(r, true, "weakCompareAndSetRelease int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 1, 2); + } + assertEquals(success, true, "weakCompareAndSetRelease int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, 2, "weakCompareAndSetRelease int"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, 2, 1); - assertEquals(r, true, "weakCompareAndSetVolatile int"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, 2, 1); + } + assertEquals(success, true, "weakCompareAndSetVolatile int"); int x = (int) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1, "weakCompareAndSetVolatile int value"); + assertEquals(x, 1, "weakCompareAndSetVolatile int"); } // Compare set and get diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java index 65493ec2b49..0f265da3f2e 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessLong.java @@ -24,6 +24,7 @@ /* * @test * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessLong + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodHandleAccessLong */ import org.testng.annotations.BeforeClass; @@ -208,31 +209,43 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 1L, 2L); - assertEquals(r, true, "weakCompareAndSet long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, 1L, 2L); + } + assertEquals(success, true, "weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, 2L, "weakCompareAndSet long value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2L, 1L); - assertEquals(r, true, "weakCompareAndSetAcquire long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, 2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, 1L, "weakCompareAndSetAcquire long"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1L, 2L); - assertEquals(r, true, "weakCompareAndSetRelease long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, 1L, 2L); + } + assertEquals(success, true, "weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, 2L, "weakCompareAndSetRelease long"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, 2L, 1L); - assertEquals(r, true, "weakCompareAndSetVolatile long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, 2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetVolatile long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, 1L, "weakCompareAndSetVolatile long value"); + assertEquals(x, 1L, "weakCompareAndSetVolatile long"); } // Compare set and get @@ -349,36 +362,48 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(1L, 2L); - assertEquals(r, true, "weakCompareAndSet long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(1L, 2L); + } + assertEquals(success, true, "weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 2L, "weakCompareAndSet long value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2L, 1L); - assertEquals(r, true, "weakCompareAndSetAcquire long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 1L, "weakCompareAndSetAcquire long"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1L, 2L); - assertEquals(r, true, "weakCompareAndSetRelease long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(1L, 2L); + } + assertEquals(success, true, "weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 2L, "weakCompareAndSetRelease long"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(2L, 1L); - assertEquals(r, true, "weakCompareAndSetVolatile long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetVolatile long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, 1L, "weakCompareAndSetVolatile long value"); + assertEquals(x, 1L, "weakCompareAndSetVolatile long"); } // Compare set and get { - long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact(2L); + long o = (long) hs.get(TestAccessMode.GET_AND_SET).invokeExact( 2L); assertEquals(o, 1L, "getAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, 2L, "getAndSet long value"); @@ -493,31 +518,43 @@ public class VarHandleTestMethodHandleAccessLong extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 1L, 2L); - assertEquals(r, true, "weakCompareAndSet long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, 1L, 2L); + } + assertEquals(success, true, "weakCompareAndSet long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, 2L, "weakCompareAndSet long value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2L, 1L); - assertEquals(r, true, "weakCompareAndSetAcquire long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, 2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetAcquire long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, 1L, "weakCompareAndSetAcquire long"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 1L, 2L); - assertEquals(r, true, "weakCompareAndSetRelease long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, 1L, 2L); + } + assertEquals(success, true, "weakCompareAndSetRelease long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, 2L, "weakCompareAndSetRelease long"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, 2L, 1L); - assertEquals(r, true, "weakCompareAndSetVolatile long"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, 2L, 1L); + } + assertEquals(success, true, "weakCompareAndSetVolatile long"); long x = (long) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, 1L, "weakCompareAndSetVolatile long value"); + assertEquals(x, 1L, "weakCompareAndSetVolatile long"); } // Compare set and get diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java index 6edc9b19b68..51b51e73747 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessShort.java @@ -24,6 +24,7 @@ /* * @test * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessShort + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodHandleAccessShort */ import org.testng.annotations.BeforeClass; diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java index 5ae7c877854..ce5167a0b91 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodHandleAccessString.java @@ -24,6 +24,7 @@ /* * @test * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccessString + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodHandleAccessString */ import org.testng.annotations.BeforeClass; @@ -208,31 +209,43 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, "foo", "bar"); - assertEquals(r, true, "weakCompareAndSet String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, "foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, "bar", "weakCompareAndSet String value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, "bar", "foo"); - assertEquals(r, true, "weakCompareAndSetAcquire String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, "bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, "foo", "weakCompareAndSetAcquire String"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, "foo", "bar"); - assertEquals(r, true, "weakCompareAndSetRelease String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, "foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, "bar", "weakCompareAndSetRelease String"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, "bar", "foo"); - assertEquals(r, true, "weakCompareAndSetVolatile String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, "bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetVolatile String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, "foo", "weakCompareAndSetVolatile String value"); + assertEquals(x, "foo", "weakCompareAndSetVolatile String"); } // Compare set and get @@ -345,36 +358,48 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact("foo", "bar"); - assertEquals(r, true, "weakCompareAndSet String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact("foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, "bar", "weakCompareAndSet String value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact("bar", "foo"); - assertEquals(r, true, "weakCompareAndSetAcquire String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact("bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, "foo", "weakCompareAndSetAcquire String"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "bar"); - assertEquals(r, true, "weakCompareAndSetRelease String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact("foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, "bar", "weakCompareAndSetRelease String"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact("bar", "foo"); - assertEquals(r, true, "weakCompareAndSetVolatile String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact("bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetVolatile String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, "foo", "weakCompareAndSetVolatile String value"); + assertEquals(x, "foo", "weakCompareAndSetVolatile String"); } // Compare set and get { - String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact("bar"); + String o = (String) hs.get(TestAccessMode.GET_AND_SET).invokeExact( "bar"); assertEquals(o, "foo", "getAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, "bar", "getAndSet String value"); @@ -485,31 +510,43 @@ public class VarHandleTestMethodHandleAccessString extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, "foo", "bar"); - assertEquals(r, true, "weakCompareAndSet String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, "foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSet String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, "bar", "weakCompareAndSet String value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "bar", "foo"); - assertEquals(r, true, "weakCompareAndSetAcquire String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, "bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetAcquire String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, "foo", "weakCompareAndSetAcquire String"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, "foo", "bar"); - assertEquals(r, true, "weakCompareAndSetRelease String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, "foo", "bar"); + } + assertEquals(success, true, "weakCompareAndSetRelease String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, "bar", "weakCompareAndSetRelease String"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, "bar", "foo"); - assertEquals(r, true, "weakCompareAndSetVolatile String"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, "bar", "foo"); + } + assertEquals(success, true, "weakCompareAndSetVolatile String"); String x = (String) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, "foo", "weakCompareAndSetVolatile String value"); + assertEquals(x, "foo", "weakCompareAndSetVolatile String"); } // Compare set and get diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java index 75ba7ae3dc2..df680146374 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeBoolean.java @@ -23,6 +23,7 @@ /* * @test + * @bug 8156486 * @run testng/othervm VarHandleTestMethodTypeBoolean * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeBoolean */ @@ -81,27 +82,28 @@ public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest { public Object[][] accessTestCaseProvider() throws Exception { List<AccessTestCase<?>> cases = new ArrayList<>(); - cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + cases.add(new VarHandleAccessTestCase("Instance field", vhField, vh -> testInstanceFieldWrongMethodType(this, vh), false)); - cases.add(new VarHandleAccessTestCase("Static field wrong method type", + cases.add(new VarHandleAccessTestCase("Static field", vhStaticField, VarHandleTestMethodTypeBoolean::testStaticFieldWrongMethodType, false)); - cases.add(new VarHandleAccessTestCase("Array wrong method type", + cases.add(new VarHandleAccessTestCase("Array", vhArray, VarHandleTestMethodTypeBoolean::testArrayWrongMethodType, false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { - cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + cases.add(new MethodHandleAccessTestCase("Instance field", vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), false)); - cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + cases.add(new MethodHandleAccessTestCase("Static field", vhStaticField, f, VarHandleTestMethodTypeBoolean::testStaticFieldWrongMethodType, false)); - cases.add(new MethodHandleAccessTestCase("Array wrong method type", + cases.add(new MethodHandleAccessTestCase("Array", vhArray, f, VarHandleTestMethodTypeBoolean::testArrayWrongMethodType, false)); } @@ -329,63 +331,63 @@ public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null receiver - boolean x = (boolean) hs.get(am, methodType(boolean.class, Void.class)). - invoke(null); + boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeBoolean.class)). + invokeExact((VarHandleTestMethodTypeBoolean) null); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class boolean x = (boolean) hs.get(am, methodType(boolean.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); checkWMTE(() -> { // receiver primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)). - invoke(0); + invokeExact(0); }); // Incorrect return type checkWMTE(() -> { // reference class - Void x = (Void) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeBoolean.class)). - invoke(recv); + Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeBoolean.class)). + invokeExact(recv); }); checkWMTE(() -> { // primitive class int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeBoolean.class)). - invoke(recv); + invokeExact(recv); }); // Incorrect arity checkWMTE(() -> { // 0 boolean x = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeBoolean.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - hs.get(am, methodType(void.class, Void.class, boolean.class)). - invoke(null, true); + hs.get(am, methodType(void.class, VarHandleTestMethodTypeBoolean.class, boolean.class)). + invokeExact((VarHandleTestMethodTypeBoolean) null, true); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class hs.get(am, methodType(void.class, Class.class, boolean.class)). - invoke(Void.class, true); + invokeExact(Void.class, true); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, VarHandleTestMethodTypeBoolean.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, boolean.class)). - invoke(0, true); + invokeExact(0, true); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, VarHandleTestMethodTypeBoolean.class, boolean.class, Class.class)). - invoke(recv, true, Void.class); + invokeExact(recv, true, Void.class); }); } @@ -513,32 +515,32 @@ public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest { // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // primitive class int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); // Incorrect arity checkWMTE(() -> { // > boolean x = (boolean) hs.get(am, methodType(Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, boolean.class, Class.class)). - invoke(true, Void.class); + invokeExact(true, Void.class); }); } @@ -783,71 +785,71 @@ public class VarHandleTestMethodTypeBoolean extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null array - boolean x = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class)). - invoke(null, 0); + boolean x = (boolean) hs.get(am, methodType(boolean.class, boolean[].class, int.class)). + invokeExact((boolean[]) null, 0); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class boolean x = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class)). - invoke(Void.class, 0); + invokeExact(Void.class, 0); }); checkWMTE(() -> { // array primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class)). - invoke(0, 0); + invokeExact(0, 0); }); checkWMTE(() -> { // index reference class boolean x = (boolean) hs.get(am, methodType(boolean.class, boolean[].class, Class.class)). - invoke(array, Void.class); + invokeExact(array, Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class, boolean[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); checkWMTE(() -> { // primitive class int x = (int) hs.get(am, methodType(int.class, boolean[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); // Incorrect arity checkWMTE(() -> { // 0 boolean x = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean x = (boolean) hs.get(am, methodType(boolean.class, boolean[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null array - hs.get(am, methodType(void.class, Void.class, int.class, boolean.class)). - invoke(null, 0, true); + hs.get(am, methodType(void.class, boolean[].class, int.class, boolean.class)). + invokeExact((boolean[]) null, 0, true); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class hs.get(am, methodType(void.class, Class.class, int.class, boolean.class)). - invoke(Void.class, 0, true); + invokeExact(Void.class, 0, true); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, boolean[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, int.class, boolean.class)). - invoke(0, 0, true); + invokeExact(0, 0, true); }); checkWMTE(() -> { // index reference class hs.get(am, methodType(void.class, boolean[].class, Class.class, boolean.class)). - invoke(array, Void.class, true); + invokeExact(array, Void.class, true); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, boolean[].class, int.class, Class.class)). - invoke(array, 0, true, Void.class); + invokeExact(array, 0, true, Void.class); }); } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java index b212bfc9d7d..0bfddc7ad27 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeByte.java @@ -23,6 +23,7 @@ /* * @test + * @bug 8156486 * @run testng/othervm VarHandleTestMethodTypeByte * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeByte */ @@ -81,27 +82,28 @@ public class VarHandleTestMethodTypeByte extends VarHandleBaseTest { public Object[][] accessTestCaseProvider() throws Exception { List<AccessTestCase<?>> cases = new ArrayList<>(); - cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + cases.add(new VarHandleAccessTestCase("Instance field", vhField, vh -> testInstanceFieldWrongMethodType(this, vh), false)); - cases.add(new VarHandleAccessTestCase("Static field wrong method type", + cases.add(new VarHandleAccessTestCase("Static field", vhStaticField, VarHandleTestMethodTypeByte::testStaticFieldWrongMethodType, false)); - cases.add(new VarHandleAccessTestCase("Array wrong method type", + cases.add(new VarHandleAccessTestCase("Array", vhArray, VarHandleTestMethodTypeByte::testArrayWrongMethodType, false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { - cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + cases.add(new MethodHandleAccessTestCase("Instance field", vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), false)); - cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + cases.add(new MethodHandleAccessTestCase("Static field", vhStaticField, f, VarHandleTestMethodTypeByte::testStaticFieldWrongMethodType, false)); - cases.add(new MethodHandleAccessTestCase("Array wrong method type", + cases.add(new MethodHandleAccessTestCase("Array", vhArray, f, VarHandleTestMethodTypeByte::testArrayWrongMethodType, false)); } @@ -329,63 +331,63 @@ public class VarHandleTestMethodTypeByte extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null receiver - byte x = (byte) hs.get(am, methodType(byte.class, Void.class)). - invoke(null); + byte x = (byte) hs.get(am, methodType(byte.class, VarHandleTestMethodTypeByte.class)). + invokeExact((VarHandleTestMethodTypeByte) null); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class byte x = (byte) hs.get(am, methodType(byte.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); checkWMTE(() -> { // receiver primitive class byte x = (byte) hs.get(am, methodType(byte.class, int.class)). - invoke(0); + invokeExact(0); }); // Incorrect return type checkWMTE(() -> { // reference class - Void x = (Void) hs.get(am, methodType(byte.class, VarHandleTestMethodTypeByte.class)). - invoke(recv); + Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeByte.class)). + invokeExact(recv); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeByte.class)). - invoke(recv); + invokeExact(recv); }); // Incorrect arity checkWMTE(() -> { // 0 byte x = (byte) hs.get(am, methodType(byte.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > byte x = (byte) hs.get(am, methodType(byte.class, VarHandleTestMethodTypeByte.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - hs.get(am, methodType(void.class, Void.class, byte.class)). - invoke(null, (byte)1); + hs.get(am, methodType(void.class, VarHandleTestMethodTypeByte.class, byte.class)). + invokeExact((VarHandleTestMethodTypeByte) null, (byte)1); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class hs.get(am, methodType(void.class, Class.class, byte.class)). - invoke(Void.class, (byte)1); + invokeExact(Void.class, (byte)1); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, VarHandleTestMethodTypeByte.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, byte.class)). - invoke(0, (byte)1); + invokeExact(0, (byte)1); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, VarHandleTestMethodTypeByte.class, byte.class, Class.class)). - invoke(recv, (byte)1, Void.class); + invokeExact(recv, (byte)1, Void.class); }); } @@ -513,32 +515,32 @@ public class VarHandleTestMethodTypeByte extends VarHandleBaseTest { // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); // Incorrect arity checkWMTE(() -> { // > byte x = (byte) hs.get(am, methodType(Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, byte.class, Class.class)). - invoke((byte)1, Void.class); + invokeExact((byte)1, Void.class); }); } @@ -783,71 +785,71 @@ public class VarHandleTestMethodTypeByte extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null array - byte x = (byte) hs.get(am, methodType(byte.class, Void.class, int.class)). - invoke(null, 0); + byte x = (byte) hs.get(am, methodType(byte.class, byte[].class, int.class)). + invokeExact((byte[]) null, 0); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class byte x = (byte) hs.get(am, methodType(byte.class, Class.class, int.class)). - invoke(Void.class, 0); + invokeExact(Void.class, 0); }); checkWMTE(() -> { // array primitive class byte x = (byte) hs.get(am, methodType(byte.class, int.class, int.class)). - invoke(0, 0); + invokeExact(0, 0); }); checkWMTE(() -> { // index reference class byte x = (byte) hs.get(am, methodType(byte.class, byte[].class, Class.class)). - invoke(array, Void.class); + invokeExact(array, Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class, byte[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, byte[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); // Incorrect arity checkWMTE(() -> { // 0 byte x = (byte) hs.get(am, methodType(byte.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > byte x = (byte) hs.get(am, methodType(byte.class, byte[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null array - hs.get(am, methodType(void.class, Void.class, int.class, byte.class)). - invoke(null, 0, (byte)1); + hs.get(am, methodType(void.class, byte[].class, int.class, byte.class)). + invokeExact((byte[]) null, 0, (byte)1); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class hs.get(am, methodType(void.class, Class.class, int.class, byte.class)). - invoke(Void.class, 0, (byte)1); + invokeExact(Void.class, 0, (byte)1); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, byte[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, int.class, byte.class)). - invoke(0, 0, (byte)1); + invokeExact(0, 0, (byte)1); }); checkWMTE(() -> { // index reference class hs.get(am, methodType(void.class, byte[].class, Class.class, byte.class)). - invoke(array, Void.class, (byte)1); + invokeExact(array, Void.class, (byte)1); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, byte[].class, int.class, Class.class)). - invoke(array, 0, (byte)1, Void.class); + invokeExact(array, 0, (byte)1, Void.class); }); } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java index 6ac8a0fed70..8d5166d8644 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeChar.java @@ -23,6 +23,7 @@ /* * @test + * @bug 8156486 * @run testng/othervm VarHandleTestMethodTypeChar * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeChar */ @@ -81,27 +82,28 @@ public class VarHandleTestMethodTypeChar extends VarHandleBaseTest { public Object[][] accessTestCaseProvider() throws Exception { List<AccessTestCase<?>> cases = new ArrayList<>(); - cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + cases.add(new VarHandleAccessTestCase("Instance field", vhField, vh -> testInstanceFieldWrongMethodType(this, vh), false)); - cases.add(new VarHandleAccessTestCase("Static field wrong method type", + cases.add(new VarHandleAccessTestCase("Static field", vhStaticField, VarHandleTestMethodTypeChar::testStaticFieldWrongMethodType, false)); - cases.add(new VarHandleAccessTestCase("Array wrong method type", + cases.add(new VarHandleAccessTestCase("Array", vhArray, VarHandleTestMethodTypeChar::testArrayWrongMethodType, false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { - cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + cases.add(new MethodHandleAccessTestCase("Instance field", vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), false)); - cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + cases.add(new MethodHandleAccessTestCase("Static field", vhStaticField, f, VarHandleTestMethodTypeChar::testStaticFieldWrongMethodType, false)); - cases.add(new MethodHandleAccessTestCase("Array wrong method type", + cases.add(new MethodHandleAccessTestCase("Array", vhArray, f, VarHandleTestMethodTypeChar::testArrayWrongMethodType, false)); } @@ -329,63 +331,63 @@ public class VarHandleTestMethodTypeChar extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null receiver - char x = (char) hs.get(am, methodType(char.class, Void.class)). - invoke(null); + char x = (char) hs.get(am, methodType(char.class, VarHandleTestMethodTypeChar.class)). + invokeExact((VarHandleTestMethodTypeChar) null); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class char x = (char) hs.get(am, methodType(char.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); checkWMTE(() -> { // receiver primitive class char x = (char) hs.get(am, methodType(char.class, int.class)). - invoke(0); + invokeExact(0); }); // Incorrect return type checkWMTE(() -> { // reference class - Void x = (Void) hs.get(am, methodType(char.class, VarHandleTestMethodTypeChar.class)). - invoke(recv); + Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeChar.class)). + invokeExact(recv); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeChar.class)). - invoke(recv); + invokeExact(recv); }); // Incorrect arity checkWMTE(() -> { // 0 char x = (char) hs.get(am, methodType(char.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > char x = (char) hs.get(am, methodType(char.class, VarHandleTestMethodTypeChar.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - hs.get(am, methodType(void.class, Void.class, char.class)). - invoke(null, 'a'); + hs.get(am, methodType(void.class, VarHandleTestMethodTypeChar.class, char.class)). + invokeExact((VarHandleTestMethodTypeChar) null, 'a'); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class hs.get(am, methodType(void.class, Class.class, char.class)). - invoke(Void.class, 'a'); + invokeExact(Void.class, 'a'); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, VarHandleTestMethodTypeChar.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, char.class)). - invoke(0, 'a'); + invokeExact(0, 'a'); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, VarHandleTestMethodTypeChar.class, char.class, Class.class)). - invoke(recv, 'a', Void.class); + invokeExact(recv, 'a', Void.class); }); } @@ -513,32 +515,32 @@ public class VarHandleTestMethodTypeChar extends VarHandleBaseTest { // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); // Incorrect arity checkWMTE(() -> { // > char x = (char) hs.get(am, methodType(Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, char.class, Class.class)). - invoke('a', Void.class); + invokeExact('a', Void.class); }); } @@ -783,71 +785,71 @@ public class VarHandleTestMethodTypeChar extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null array - char x = (char) hs.get(am, methodType(char.class, Void.class, int.class)). - invoke(null, 0); + char x = (char) hs.get(am, methodType(char.class, char[].class, int.class)). + invokeExact((char[]) null, 0); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class char x = (char) hs.get(am, methodType(char.class, Class.class, int.class)). - invoke(Void.class, 0); + invokeExact(Void.class, 0); }); checkWMTE(() -> { // array primitive class char x = (char) hs.get(am, methodType(char.class, int.class, int.class)). - invoke(0, 0); + invokeExact(0, 0); }); checkWMTE(() -> { // index reference class char x = (char) hs.get(am, methodType(char.class, char[].class, Class.class)). - invoke(array, Void.class); + invokeExact(array, Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class, char[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, char[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); // Incorrect arity checkWMTE(() -> { // 0 char x = (char) hs.get(am, methodType(char.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > char x = (char) hs.get(am, methodType(char.class, char[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null array - hs.get(am, methodType(void.class, Void.class, int.class, char.class)). - invoke(null, 0, 'a'); + hs.get(am, methodType(void.class, char[].class, int.class, char.class)). + invokeExact((char[]) null, 0, 'a'); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class hs.get(am, methodType(void.class, Class.class, int.class, char.class)). - invoke(Void.class, 0, 'a'); + invokeExact(Void.class, 0, 'a'); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, char[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, int.class, char.class)). - invoke(0, 0, 'a'); + invokeExact(0, 0, 'a'); }); checkWMTE(() -> { // index reference class hs.get(am, methodType(void.class, char[].class, Class.class, char.class)). - invoke(array, Void.class, 'a'); + invokeExact(array, Void.class, 'a'); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, char[].class, int.class, Class.class)). - invoke(array, 0, 'a', Void.class); + invokeExact(array, 0, 'a', Void.class); }); } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java index e5fc073d191..f3531016262 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeDouble.java @@ -23,6 +23,7 @@ /* * @test + * @bug 8156486 * @run testng/othervm VarHandleTestMethodTypeDouble * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeDouble */ @@ -81,27 +82,28 @@ public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest { public Object[][] accessTestCaseProvider() throws Exception { List<AccessTestCase<?>> cases = new ArrayList<>(); - cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + cases.add(new VarHandleAccessTestCase("Instance field", vhField, vh -> testInstanceFieldWrongMethodType(this, vh), false)); - cases.add(new VarHandleAccessTestCase("Static field wrong method type", + cases.add(new VarHandleAccessTestCase("Static field", vhStaticField, VarHandleTestMethodTypeDouble::testStaticFieldWrongMethodType, false)); - cases.add(new VarHandleAccessTestCase("Array wrong method type", + cases.add(new VarHandleAccessTestCase("Array", vhArray, VarHandleTestMethodTypeDouble::testArrayWrongMethodType, false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { - cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + cases.add(new MethodHandleAccessTestCase("Instance field", vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), false)); - cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + cases.add(new MethodHandleAccessTestCase("Static field", vhStaticField, f, VarHandleTestMethodTypeDouble::testStaticFieldWrongMethodType, false)); - cases.add(new MethodHandleAccessTestCase("Array wrong method type", + cases.add(new MethodHandleAccessTestCase("Array", vhArray, f, VarHandleTestMethodTypeDouble::testArrayWrongMethodType, false)); } @@ -329,63 +331,63 @@ public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null receiver - double x = (double) hs.get(am, methodType(double.class, Void.class)). - invoke(null); + double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class)). + invokeExact((VarHandleTestMethodTypeDouble) null); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class double x = (double) hs.get(am, methodType(double.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); checkWMTE(() -> { // receiver primitive class double x = (double) hs.get(am, methodType(double.class, int.class)). - invoke(0); + invokeExact(0); }); // Incorrect return type checkWMTE(() -> { // reference class - Void x = (Void) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class)). - invoke(recv); + Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeDouble.class)). + invokeExact(recv); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeDouble.class)). - invoke(recv); + invokeExact(recv); }); // Incorrect arity checkWMTE(() -> { // 0 double x = (double) hs.get(am, methodType(double.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > double x = (double) hs.get(am, methodType(double.class, VarHandleTestMethodTypeDouble.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - hs.get(am, methodType(void.class, Void.class, double.class)). - invoke(null, 1.0d); + hs.get(am, methodType(void.class, VarHandleTestMethodTypeDouble.class, double.class)). + invokeExact((VarHandleTestMethodTypeDouble) null, 1.0d); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class hs.get(am, methodType(void.class, Class.class, double.class)). - invoke(Void.class, 1.0d); + invokeExact(Void.class, 1.0d); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, VarHandleTestMethodTypeDouble.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, double.class)). - invoke(0, 1.0d); + invokeExact(0, 1.0d); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, VarHandleTestMethodTypeDouble.class, double.class, Class.class)). - invoke(recv, 1.0d, Void.class); + invokeExact(recv, 1.0d, Void.class); }); } @@ -513,32 +515,32 @@ public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest { // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); // Incorrect arity checkWMTE(() -> { // > double x = (double) hs.get(am, methodType(Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, double.class, Class.class)). - invoke(1.0d, Void.class); + invokeExact(1.0d, Void.class); }); } @@ -783,71 +785,71 @@ public class VarHandleTestMethodTypeDouble extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null array - double x = (double) hs.get(am, methodType(double.class, Void.class, int.class)). - invoke(null, 0); + double x = (double) hs.get(am, methodType(double.class, double[].class, int.class)). + invokeExact((double[]) null, 0); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class double x = (double) hs.get(am, methodType(double.class, Class.class, int.class)). - invoke(Void.class, 0); + invokeExact(Void.class, 0); }); checkWMTE(() -> { // array primitive class double x = (double) hs.get(am, methodType(double.class, int.class, int.class)). - invoke(0, 0); + invokeExact(0, 0); }); checkWMTE(() -> { // index reference class double x = (double) hs.get(am, methodType(double.class, double[].class, Class.class)). - invoke(array, Void.class); + invokeExact(array, Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class, double[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, double[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); // Incorrect arity checkWMTE(() -> { // 0 double x = (double) hs.get(am, methodType(double.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > double x = (double) hs.get(am, methodType(double.class, double[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null array - hs.get(am, methodType(void.class, Void.class, int.class, double.class)). - invoke(null, 0, 1.0d); + hs.get(am, methodType(void.class, double[].class, int.class, double.class)). + invokeExact((double[]) null, 0, 1.0d); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class hs.get(am, methodType(void.class, Class.class, int.class, double.class)). - invoke(Void.class, 0, 1.0d); + invokeExact(Void.class, 0, 1.0d); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, double[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, int.class, double.class)). - invoke(0, 0, 1.0d); + invokeExact(0, 0, 1.0d); }); checkWMTE(() -> { // index reference class hs.get(am, methodType(void.class, double[].class, Class.class, double.class)). - invoke(array, Void.class, 1.0d); + invokeExact(array, Void.class, 1.0d); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, double[].class, int.class, Class.class)). - invoke(array, 0, 1.0d, Void.class); + invokeExact(array, 0, 1.0d, Void.class); }); } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java index c1bee039b73..b07049d64b0 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeFloat.java @@ -23,6 +23,7 @@ /* * @test + * @bug 8156486 * @run testng/othervm VarHandleTestMethodTypeFloat * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeFloat */ @@ -81,27 +82,28 @@ public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest { public Object[][] accessTestCaseProvider() throws Exception { List<AccessTestCase<?>> cases = new ArrayList<>(); - cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + cases.add(new VarHandleAccessTestCase("Instance field", vhField, vh -> testInstanceFieldWrongMethodType(this, vh), false)); - cases.add(new VarHandleAccessTestCase("Static field wrong method type", + cases.add(new VarHandleAccessTestCase("Static field", vhStaticField, VarHandleTestMethodTypeFloat::testStaticFieldWrongMethodType, false)); - cases.add(new VarHandleAccessTestCase("Array wrong method type", + cases.add(new VarHandleAccessTestCase("Array", vhArray, VarHandleTestMethodTypeFloat::testArrayWrongMethodType, false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { - cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + cases.add(new MethodHandleAccessTestCase("Instance field", vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), false)); - cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + cases.add(new MethodHandleAccessTestCase("Static field", vhStaticField, f, VarHandleTestMethodTypeFloat::testStaticFieldWrongMethodType, false)); - cases.add(new MethodHandleAccessTestCase("Array wrong method type", + cases.add(new MethodHandleAccessTestCase("Array", vhArray, f, VarHandleTestMethodTypeFloat::testArrayWrongMethodType, false)); } @@ -329,63 +331,63 @@ public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null receiver - float x = (float) hs.get(am, methodType(float.class, Void.class)). - invoke(null); + float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class)). + invokeExact((VarHandleTestMethodTypeFloat) null); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class float x = (float) hs.get(am, methodType(float.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); checkWMTE(() -> { // receiver primitive class float x = (float) hs.get(am, methodType(float.class, int.class)). - invoke(0); + invokeExact(0); }); // Incorrect return type checkWMTE(() -> { // reference class - Void x = (Void) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class)). - invoke(recv); + Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeFloat.class)). + invokeExact(recv); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeFloat.class)). - invoke(recv); + invokeExact(recv); }); // Incorrect arity checkWMTE(() -> { // 0 float x = (float) hs.get(am, methodType(float.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > float x = (float) hs.get(am, methodType(float.class, VarHandleTestMethodTypeFloat.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - hs.get(am, methodType(void.class, Void.class, float.class)). - invoke(null, 1.0f); + hs.get(am, methodType(void.class, VarHandleTestMethodTypeFloat.class, float.class)). + invokeExact((VarHandleTestMethodTypeFloat) null, 1.0f); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class hs.get(am, methodType(void.class, Class.class, float.class)). - invoke(Void.class, 1.0f); + invokeExact(Void.class, 1.0f); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, VarHandleTestMethodTypeFloat.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, float.class)). - invoke(0, 1.0f); + invokeExact(0, 1.0f); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, VarHandleTestMethodTypeFloat.class, float.class, Class.class)). - invoke(recv, 1.0f, Void.class); + invokeExact(recv, 1.0f, Void.class); }); } @@ -513,32 +515,32 @@ public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest { // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); // Incorrect arity checkWMTE(() -> { // > float x = (float) hs.get(am, methodType(Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, float.class, Class.class)). - invoke(1.0f, Void.class); + invokeExact(1.0f, Void.class); }); } @@ -783,71 +785,71 @@ public class VarHandleTestMethodTypeFloat extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null array - float x = (float) hs.get(am, methodType(float.class, Void.class, int.class)). - invoke(null, 0); + float x = (float) hs.get(am, methodType(float.class, float[].class, int.class)). + invokeExact((float[]) null, 0); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class float x = (float) hs.get(am, methodType(float.class, Class.class, int.class)). - invoke(Void.class, 0); + invokeExact(Void.class, 0); }); checkWMTE(() -> { // array primitive class float x = (float) hs.get(am, methodType(float.class, int.class, int.class)). - invoke(0, 0); + invokeExact(0, 0); }); checkWMTE(() -> { // index reference class float x = (float) hs.get(am, methodType(float.class, float[].class, Class.class)). - invoke(array, Void.class); + invokeExact(array, Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class, float[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, float[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); // Incorrect arity checkWMTE(() -> { // 0 float x = (float) hs.get(am, methodType(float.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > float x = (float) hs.get(am, methodType(float.class, float[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null array - hs.get(am, methodType(void.class, Void.class, int.class, float.class)). - invoke(null, 0, 1.0f); + hs.get(am, methodType(void.class, float[].class, int.class, float.class)). + invokeExact((float[]) null, 0, 1.0f); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class hs.get(am, methodType(void.class, Class.class, int.class, float.class)). - invoke(Void.class, 0, 1.0f); + invokeExact(Void.class, 0, 1.0f); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, float[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, int.class, float.class)). - invoke(0, 0, 1.0f); + invokeExact(0, 0, 1.0f); }); checkWMTE(() -> { // index reference class hs.get(am, methodType(void.class, float[].class, Class.class, float.class)). - invoke(array, Void.class, 1.0f); + invokeExact(array, Void.class, 1.0f); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, float[].class, int.class, Class.class)). - invoke(array, 0, 1.0f, Void.class); + invokeExact(array, 0, 1.0f, Void.class); }); } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java index 13b6b0607b0..67fca94c49a 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeInt.java @@ -23,6 +23,7 @@ /* * @test + * @bug 8156486 * @run testng/othervm VarHandleTestMethodTypeInt * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeInt */ @@ -81,27 +82,28 @@ public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { public Object[][] accessTestCaseProvider() throws Exception { List<AccessTestCase<?>> cases = new ArrayList<>(); - cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + cases.add(new VarHandleAccessTestCase("Instance field", vhField, vh -> testInstanceFieldWrongMethodType(this, vh), false)); - cases.add(new VarHandleAccessTestCase("Static field wrong method type", + cases.add(new VarHandleAccessTestCase("Static field", vhStaticField, VarHandleTestMethodTypeInt::testStaticFieldWrongMethodType, false)); - cases.add(new VarHandleAccessTestCase("Array wrong method type", + cases.add(new VarHandleAccessTestCase("Array", vhArray, VarHandleTestMethodTypeInt::testArrayWrongMethodType, false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { - cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + cases.add(new MethodHandleAccessTestCase("Instance field", vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), false)); - cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + cases.add(new MethodHandleAccessTestCase("Static field", vhStaticField, f, VarHandleTestMethodTypeInt::testStaticFieldWrongMethodType, false)); - cases.add(new MethodHandleAccessTestCase("Array wrong method type", + cases.add(new MethodHandleAccessTestCase("Array", vhArray, f, VarHandleTestMethodTypeInt::testArrayWrongMethodType, false)); } @@ -644,211 +646,211 @@ public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null receiver - int x = (int) hs.get(am, methodType(int.class, Void.class)). - invoke(null); + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class)). + invokeExact((VarHandleTestMethodTypeInt) null); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class int x = (int) hs.get(am, methodType(int.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); checkWMTE(() -> { // receiver primitive class int x = (int) hs.get(am, methodType(int.class, int.class)). - invoke(0); + invokeExact(0); }); // Incorrect return type checkWMTE(() -> { // reference class - Void x = (Void) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class)). - invoke(recv); + Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class)). + invokeExact(recv); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class)). - invoke(recv); + invokeExact(recv); }); // Incorrect arity checkWMTE(() -> { // 0 int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - hs.get(am, methodType(void.class, Void.class, int.class)). - invoke(null, 1); + hs.get(am, methodType(void.class, VarHandleTestMethodTypeInt.class, int.class)). + invokeExact((VarHandleTestMethodTypeInt) null, 1); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class hs.get(am, methodType(void.class, Class.class, int.class)). - invoke(Void.class, 1); + invokeExact(Void.class, 1); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, VarHandleTestMethodTypeInt.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, int.class)). - invoke(0, 1); + invokeExact(0, 1); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)). - invoke(recv, 1, Void.class); + invokeExact(recv, 1, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, int.class)). - invoke(null, 1, 1); + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class, int.class)). + invokeExact((VarHandleTestMethodTypeInt) null, 1, 1); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, int.class)). - invoke(Void.class, 1, 1); + invokeExact(Void.class, 1, 1); }); checkWMTE(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, Class.class, int.class)). - invoke(recv, Void.class, 1); + invokeExact(recv, Void.class, 1); }); checkWMTE(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)). - invoke(recv, 1, Void.class); + invokeExact(recv, 1, Void.class); }); checkWMTE(() -> { // receiver primitive class boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , int.class, int.class)). - invoke(0, 1, 1); + invokeExact(0, 1, 1); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class, int.class, Class.class)). - invoke(recv, 1, 1, Void.class); + invokeExact(recv, 1, 1, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { checkNPE(() -> { // null receiver - int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)). - invoke(null, 1, 1); + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class, int.class)). + invokeExact((VarHandleTestMethodTypeInt) null, 1, 1); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)). - invoke(Void.class, 1, 1); + invokeExact(Void.class, 1, 1); }); checkWMTE(() -> { // expected reference class int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class, int.class)). - invoke(recv, Void.class, 1); + invokeExact(recv, Void.class, 1); }); checkWMTE(() -> { // actual reference class int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class, Class.class)). - invoke(recv, 1, Void.class); + invokeExact(recv, 1, Void.class); }); checkWMTE(() -> { // reciever primitive class int x = (int) hs.get(am, methodType(int.class, int.class , int.class, int.class)). - invoke(0, 1, 1); + invokeExact(0, 1, 1); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class , int.class, int.class)). - invoke(recv, 1, 1); + invokeExact(recv, 1, 1); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class , int.class, int.class)). - invoke(recv, 1, 1); + invokeExact(recv, 1, 1); }); // Incorrect arity checkWMTE(() -> { // 0 int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class, int.class, Class.class)). - invoke(recv, 1, 1, Void.class); + invokeExact(recv, 1, 1, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) { checkNPE(() -> { // null receiver - int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)). - invoke(null, 1); + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class)). + invokeExact((VarHandleTestMethodTypeInt) null, 1); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)). - invoke(Void.class, 1); + invokeExact(Void.class, 1); }); checkWMTE(() -> { // value reference class int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // reciever primitive class int x = (int) hs.get(am, methodType(int.class, int.class, int.class)). - invoke(0, 1); + invokeExact(0, 1); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class, int.class)). - invoke(recv, 1); + invokeExact(recv, 1); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class)). - invoke(recv, 1); + invokeExact(recv, 1); }); // Incorrect arity checkWMTE(() -> { // 0 int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class)). - invoke(recv, 1, Void.class); + invokeExact(recv, 1, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) { checkNPE(() -> { // null receiver - int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)). - invoke(null, 1); + int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class)). + invokeExact((VarHandleTestMethodTypeInt) null, 1); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)). - invoke(Void.class, 1); + invokeExact(Void.class, 1); }); checkWMTE(() -> { // value reference class int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // reciever primitive class int x = (int) hs.get(am, methodType(int.class, int.class, int.class)). - invoke(0, 1); + invokeExact(0, 1); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeInt.class, int.class)). - invoke(recv, 1); + invokeExact(recv, 1); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeInt.class, int.class)). - invoke(recv, 1); + invokeExact(recv, 1); }); // Incorrect arity checkWMTE(() -> { // 0 int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(int.class, VarHandleTestMethodTypeInt.class, int.class)). - invoke(recv, 1, Void.class); + invokeExact(recv, 1, Void.class); }); } } @@ -1190,52 +1192,52 @@ public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); // Incorrect arity checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, int.class, Class.class)). - invoke(1, Void.class); + invokeExact(1, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types checkWMTE(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class)). - invoke(Void.class, 1); + invokeExact(Void.class, 1); }); checkWMTE(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, Class.class)). - invoke(1, Void.class); + invokeExact(1, Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, Class.class)). - invoke(1, 1, Void.class); + invokeExact(1, 1, Void.class); }); } @@ -1243,29 +1245,29 @@ public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { // Incorrect argument types checkWMTE(() -> { // expected reference class int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)). - invoke(Void.class, 1); + invokeExact(Void.class, 1); }); checkWMTE(() -> { // actual reference class int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)). - invoke(1, Void.class); + invokeExact(1, Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, int.class, int.class)). - invoke(1, 1); + invokeExact(1, 1); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class)). - invoke(1, 1); + invokeExact(1, 1); }); // Incorrect arity checkWMTE(() -> { // 0 int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(int.class, int.class, int.class, Class.class)). - invoke(1, 1, Void.class); + invokeExact(1, 1, Void.class); }); } @@ -1273,25 +1275,25 @@ public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { // Incorrect argument types checkWMTE(() -> { // value reference class int x = (int) hs.get(am, methodType(int.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, int.class)). - invoke(1); + invokeExact(1); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)). - invoke(1); + invokeExact(1); }); // Incorrect arity checkWMTE(() -> { // 0 int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)). - invoke(1, Void.class); + invokeExact(1, Void.class); }); } @@ -1299,25 +1301,25 @@ public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { // Incorrect argument types checkWMTE(() -> { // value reference class int x = (int) hs.get(am, methodType(int.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, int.class)). - invoke(1); + invokeExact(1); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, int.class)). - invoke(1); + invokeExact(1); }); // Incorrect arity checkWMTE(() -> { // 0 int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(int.class, int.class, Class.class)). - invoke(1, Void.class); + invokeExact(1, Void.class); }); } } @@ -1909,237 +1911,237 @@ public class VarHandleTestMethodTypeInt extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null array - int x = (int) hs.get(am, methodType(int.class, Void.class, int.class)). - invoke(null, 0); + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class)). + invokeExact((int[]) null, 0); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class int x = (int) hs.get(am, methodType(int.class, Class.class, int.class)). - invoke(Void.class, 0); + invokeExact(Void.class, 0); }); checkWMTE(() -> { // array primitive class int x = (int) hs.get(am, methodType(int.class, int.class, int.class)). - invoke(0, 0); + invokeExact(0, 0); }); checkWMTE(() -> { // index reference class int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class)). - invoke(array, Void.class); + invokeExact(array, Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class, int[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); // Incorrect arity checkWMTE(() -> { // 0 int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null array - hs.get(am, methodType(void.class, Void.class, int.class, int.class)). - invoke(null, 0, 1); + hs.get(am, methodType(void.class, int[].class, int.class, int.class)). + invokeExact((int[]) null, 0, 1); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class hs.get(am, methodType(void.class, Class.class, int.class, int.class)). - invoke(Void.class, 0, 1); + invokeExact(Void.class, 0, 1); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, int[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, int.class, int.class)). - invoke(0, 0, 1); + invokeExact(0, 0, 1); }); checkWMTE(() -> { // index reference class hs.get(am, methodType(void.class, int[].class, Class.class, int.class)). - invoke(array, Void.class, 1); + invokeExact(array, Void.class, 1); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, int[].class, int.class, Class.class)). - invoke(array, 0, 1, Void.class); + invokeExact(array, 0, 1, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, int.class, int.class)). - invoke(null, 0, 1, 1); + boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, int.class)). + invokeExact((int[]) null, 0, 1, 1); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, int.class, int.class)). - invoke(Void.class, 0, 1, 1); + invokeExact(Void.class, 0, 1, 1); }); checkWMTE(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, Class.class, int.class)). - invoke(array, 0, Void.class, 1); + invokeExact(array, 0, Void.class, 1); }); checkWMTE(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, Class.class)). - invoke(array, 0, 1, Void.class); + invokeExact(array, 0, 1, Void.class); }); checkWMTE(() -> { // receiver primitive class boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, int.class, int.class)). - invoke(0, 0, 1, 1); + invokeExact(0, 0, 1, 1); }); checkWMTE(() -> { // index reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, Class.class, int.class, int.class)). - invoke(array, Void.class, 1, 1); + invokeExact(array, Void.class, 1, 1); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, int.class, Class.class)). - invoke(array, 0, 1, 1, Void.class); + invokeExact(array, 0, 1, 1, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { // Incorrect argument types checkNPE(() -> { // null receiver - int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class, int.class)). - invoke(null, 0, 1, 1); + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, int.class)). + invokeExact((int[]) null, 0, 1, 1); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class, int.class)). - invoke(Void.class, 0, 1, 1); + invokeExact(Void.class, 0, 1, 1); }); checkWMTE(() -> { // expected reference class int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class, int.class)). - invoke(array, 0, Void.class, 1); + invokeExact(array, 0, Void.class, 1); }); checkWMTE(() -> { // actual reference class int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)). - invoke(array, 0, 1, Void.class); + invokeExact(array, 0, 1, Void.class); }); checkWMTE(() -> { // array primitive class int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class, int.class)). - invoke(0, 0, 1, 1); + invokeExact(0, 0, 1, 1); }); checkWMTE(() -> { // index reference class int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class, int.class)). - invoke(array, Void.class, 1, 1); + invokeExact(array, Void.class, 1, 1); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class, int.class)). - invoke(array, 0, 1, 1); + invokeExact(array, 0, 1, 1); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class, int.class)). - invoke(array, 0, 1, 1); + invokeExact(array, 0, 1, 1); }); // Incorrect arity checkWMTE(() -> { // 0 int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, int.class, Class.class)). - invoke(array, 0, 1, 1, Void.class); + invokeExact(array, 0, 1, 1, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null array - int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)). - invoke(null, 0, 1); + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class)). + invokeExact((int[]) null, 0, 1); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)). - invoke(Void.class, 0, 1); + invokeExact(Void.class, 0, 1); }); checkWMTE(() -> { // value reference class int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // array primitive class int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class)). - invoke(0, 0, 1); + invokeExact(0, 0, 1); }); checkWMTE(() -> { // index reference class int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class)). - invoke(array, Void.class, 1); + invokeExact(array, Void.class, 1); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class)). - invoke(array, 0, 1); + invokeExact(array, 0, 1); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class)). - invoke(array, 0, 1); + invokeExact(array, 0, 1); }); // Incorrect arity checkWMTE(() -> { // 0 int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)). - invoke(array, 0, 1, Void.class); + invokeExact(array, 0, 1, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) { // Incorrect argument types checkNPE(() -> { // null array - int x = (int) hs.get(am, methodType(int.class, Void.class, int.class, int.class)). - invoke(null, 0, 1); + int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class)). + invokeExact((int[]) null, 0, 1); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class int x = (int) hs.get(am, methodType(int.class, Class.class, int.class, int.class)). - invoke(Void.class, 0, 1); + invokeExact(Void.class, 0, 1); }); checkWMTE(() -> { // value reference class int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // array primitive class int x = (int) hs.get(am, methodType(int.class, int.class, int.class, int.class)). - invoke(0, 0, 1); + invokeExact(0, 0, 1); }); checkWMTE(() -> { // index reference class int x = (int) hs.get(am, methodType(int.class, int[].class, Class.class, int.class)). - invoke(array, Void.class, 1); + invokeExact(array, Void.class, 1); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, int[].class, int.class, int.class)). - invoke(array, 0, 1); + invokeExact(array, 0, 1); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, int[].class, int.class, int.class)). - invoke(array, 0, 1); + invokeExact(array, 0, 1); }); // Incorrect arity checkWMTE(() -> { // 0 int x = (int) hs.get(am, methodType(int.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > int x = (int) hs.get(am, methodType(int.class, int[].class, int.class, int.class, Class.class)). - invoke(array, 0, 1, Void.class); + invokeExact(array, 0, 1, Void.class); }); } } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java index 44151683133..0972e663cc7 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeLong.java @@ -23,6 +23,7 @@ /* * @test + * @bug 8156486 * @run testng/othervm VarHandleTestMethodTypeLong * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeLong */ @@ -81,27 +82,28 @@ public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { public Object[][] accessTestCaseProvider() throws Exception { List<AccessTestCase<?>> cases = new ArrayList<>(); - cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + cases.add(new VarHandleAccessTestCase("Instance field", vhField, vh -> testInstanceFieldWrongMethodType(this, vh), false)); - cases.add(new VarHandleAccessTestCase("Static field wrong method type", + cases.add(new VarHandleAccessTestCase("Static field", vhStaticField, VarHandleTestMethodTypeLong::testStaticFieldWrongMethodType, false)); - cases.add(new VarHandleAccessTestCase("Array wrong method type", + cases.add(new VarHandleAccessTestCase("Array", vhArray, VarHandleTestMethodTypeLong::testArrayWrongMethodType, false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { - cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + cases.add(new MethodHandleAccessTestCase("Instance field", vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), false)); - cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + cases.add(new MethodHandleAccessTestCase("Static field", vhStaticField, f, VarHandleTestMethodTypeLong::testStaticFieldWrongMethodType, false)); - cases.add(new MethodHandleAccessTestCase("Array wrong method type", + cases.add(new MethodHandleAccessTestCase("Array", vhArray, f, VarHandleTestMethodTypeLong::testArrayWrongMethodType, false)); } @@ -644,211 +646,211 @@ public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null receiver - long x = (long) hs.get(am, methodType(long.class, Void.class)). - invoke(null); + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class)). + invokeExact((VarHandleTestMethodTypeLong) null); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class long x = (long) hs.get(am, methodType(long.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); checkWMTE(() -> { // receiver primitive class long x = (long) hs.get(am, methodType(long.class, int.class)). - invoke(0); + invokeExact(0); }); // Incorrect return type checkWMTE(() -> { // reference class - Void x = (Void) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class)). - invoke(recv); + Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class)). + invokeExact(recv); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class)). - invoke(recv); + invokeExact(recv); }); // Incorrect arity checkWMTE(() -> { // 0 long x = (long) hs.get(am, methodType(long.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - hs.get(am, methodType(void.class, Void.class, long.class)). - invoke(null, 1L); + hs.get(am, methodType(void.class, VarHandleTestMethodTypeLong.class, long.class)). + invokeExact((VarHandleTestMethodTypeLong) null, 1L); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class hs.get(am, methodType(void.class, Class.class, long.class)). - invoke(Void.class, 1L); + invokeExact(Void.class, 1L); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, VarHandleTestMethodTypeLong.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, long.class)). - invoke(0, 1L); + invokeExact(0, 1L); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)). - invoke(recv, 1L, Void.class); + invokeExact(recv, 1L, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, long.class, long.class)). - invoke(null, 1L, 1L); + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class, long.class)). + invokeExact((VarHandleTestMethodTypeLong) null, 1L, 1L); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, long.class, long.class)). - invoke(Void.class, 1L, 1L); + invokeExact(Void.class, 1L, 1L); }); checkWMTE(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, Class.class, long.class)). - invoke(recv, Void.class, 1L); + invokeExact(recv, Void.class, 1L); }); checkWMTE(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)). - invoke(recv, 1L, Void.class); + invokeExact(recv, 1L, Void.class); }); checkWMTE(() -> { // receiver primitive class boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , long.class, long.class)). - invoke(0, 1L, 1L); + invokeExact(0, 1L, 1L); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class, long.class, Class.class)). - invoke(recv, 1L, 1L, Void.class); + invokeExact(recv, 1L, 1L, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { checkNPE(() -> { // null receiver - long x = (long) hs.get(am, methodType(long.class, Void.class, long.class, long.class)). - invoke(null, 1L, 1L); + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class, long.class)). + invokeExact((VarHandleTestMethodTypeLong) null, 1L, 1L); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class long x = (long) hs.get(am, methodType(long.class, Class.class, long.class, long.class)). - invoke(Void.class, 1L, 1L); + invokeExact(Void.class, 1L, 1L); }); checkWMTE(() -> { // expected reference class long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class, long.class)). - invoke(recv, Void.class, 1L); + invokeExact(recv, Void.class, 1L); }); checkWMTE(() -> { // actual reference class long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class, Class.class)). - invoke(recv, 1L, Void.class); + invokeExact(recv, 1L, Void.class); }); checkWMTE(() -> { // reciever primitive class long x = (long) hs.get(am, methodType(long.class, int.class , long.class, long.class)). - invoke(0, 1L, 1L); + invokeExact(0, 1L, 1L); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class , long.class, long.class)). - invoke(recv, 1L, 1L); + invokeExact(recv, 1L, 1L); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class , long.class, long.class)). - invoke(recv, 1L, 1L); + invokeExact(recv, 1L, 1L); }); // Incorrect arity checkWMTE(() -> { // 0 long x = (long) hs.get(am, methodType(long.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class, long.class, Class.class)). - invoke(recv, 1L, 1L, Void.class); + invokeExact(recv, 1L, 1L, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) { checkNPE(() -> { // null receiver - long x = (long) hs.get(am, methodType(long.class, Void.class, long.class)). - invoke(null, 1L); + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class)). + invokeExact((VarHandleTestMethodTypeLong) null, 1L); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)). - invoke(Void.class, 1L); + invokeExact(Void.class, 1L); }); checkWMTE(() -> { // value reference class long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // reciever primitive class long x = (long) hs.get(am, methodType(long.class, int.class, long.class)). - invoke(0, 1L); + invokeExact(0, 1L); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class, long.class)). - invoke(recv, 1L); + invokeExact(recv, 1L); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class)). - invoke(recv, 1L); + invokeExact(recv, 1L); }); // Incorrect arity checkWMTE(() -> { // 0 long x = (long) hs.get(am, methodType(long.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class)). - invoke(recv, 1L, Void.class); + invokeExact(recv, 1L, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) { checkNPE(() -> { // null receiver - long x = (long) hs.get(am, methodType(long.class, Void.class, long.class)). - invoke(null, 1L); + long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class)). + invokeExact((VarHandleTestMethodTypeLong) null, 1L); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)). - invoke(Void.class, 1L); + invokeExact(Void.class, 1L); }); checkWMTE(() -> { // value reference class long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // reciever primitive class long x = (long) hs.get(am, methodType(long.class, int.class, long.class)). - invoke(0, 1L); + invokeExact(0, 1L); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeLong.class, long.class)). - invoke(recv, 1L); + invokeExact(recv, 1L); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeLong.class, long.class)). - invoke(recv, 1L); + invokeExact(recv, 1L); }); // Incorrect arity checkWMTE(() -> { // 0 long x = (long) hs.get(am, methodType(long.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(long.class, VarHandleTestMethodTypeLong.class, long.class)). - invoke(recv, 1L, Void.class); + invokeExact(recv, 1L, Void.class); }); } } @@ -1190,52 +1192,52 @@ public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); // Incorrect arity checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, long.class, Class.class)). - invoke(1L, Void.class); + invokeExact(1L, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types checkWMTE(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, long.class)). - invoke(Void.class, 1L); + invokeExact(Void.class, 1L); }); checkWMTE(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, long.class, Class.class)). - invoke(1L, Void.class); + invokeExact(1L, Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, long.class, long.class, Class.class)). - invoke(1L, 1L, Void.class); + invokeExact(1L, 1L, Void.class); }); } @@ -1243,29 +1245,29 @@ public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { // Incorrect argument types checkWMTE(() -> { // expected reference class long x = (long) hs.get(am, methodType(long.class, Class.class, long.class)). - invoke(Void.class, 1L); + invokeExact(Void.class, 1L); }); checkWMTE(() -> { // actual reference class long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)). - invoke(1L, Void.class); + invokeExact(1L, Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, long.class, long.class)). - invoke(1L, 1L); + invokeExact(1L, 1L); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class, long.class)). - invoke(1L, 1L); + invokeExact(1L, 1L); }); // Incorrect arity checkWMTE(() -> { // 0 long x = (long) hs.get(am, methodType(long.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(long.class, long.class, long.class, Class.class)). - invoke(1L, 1L, Void.class); + invokeExact(1L, 1L, Void.class); }); } @@ -1273,25 +1275,25 @@ public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { // Incorrect argument types checkWMTE(() -> { // value reference class long x = (long) hs.get(am, methodType(long.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, long.class)). - invoke(1L); + invokeExact(1L); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class)). - invoke(1L); + invokeExact(1L); }); // Incorrect arity checkWMTE(() -> { // 0 long x = (long) hs.get(am, methodType(long.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)). - invoke(1L, Void.class); + invokeExact(1L, Void.class); }); } @@ -1299,25 +1301,25 @@ public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { // Incorrect argument types checkWMTE(() -> { // value reference class long x = (long) hs.get(am, methodType(long.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, long.class)). - invoke(1L); + invokeExact(1L); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, long.class)). - invoke(1L); + invokeExact(1L); }); // Incorrect arity checkWMTE(() -> { // 0 long x = (long) hs.get(am, methodType(long.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(long.class, long.class, Class.class)). - invoke(1L, Void.class); + invokeExact(1L, Void.class); }); } } @@ -1909,237 +1911,237 @@ public class VarHandleTestMethodTypeLong extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null array - long x = (long) hs.get(am, methodType(long.class, Void.class, int.class)). - invoke(null, 0); + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class)). + invokeExact((long[]) null, 0); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class long x = (long) hs.get(am, methodType(long.class, Class.class, int.class)). - invoke(Void.class, 0); + invokeExact(Void.class, 0); }); checkWMTE(() -> { // array primitive class long x = (long) hs.get(am, methodType(long.class, int.class, int.class)). - invoke(0, 0); + invokeExact(0, 0); }); checkWMTE(() -> { // index reference class long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class)). - invoke(array, Void.class); + invokeExact(array, Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class, long[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); // Incorrect arity checkWMTE(() -> { // 0 long x = (long) hs.get(am, methodType(long.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null array - hs.get(am, methodType(void.class, Void.class, int.class, long.class)). - invoke(null, 0, 1L); + hs.get(am, methodType(void.class, long[].class, int.class, long.class)). + invokeExact((long[]) null, 0, 1L); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class hs.get(am, methodType(void.class, Class.class, int.class, long.class)). - invoke(Void.class, 0, 1L); + invokeExact(Void.class, 0, 1L); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, long[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, int.class, long.class)). - invoke(0, 0, 1L); + invokeExact(0, 0, 1L); }); checkWMTE(() -> { // index reference class hs.get(am, methodType(void.class, long[].class, Class.class, long.class)). - invoke(array, Void.class, 1L); + invokeExact(array, Void.class, 1L); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, long[].class, int.class, Class.class)). - invoke(array, 0, 1L, Void.class); + invokeExact(array, 0, 1L, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, long.class, long.class)). - invoke(null, 0, 1L, 1L); + boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, long.class)). + invokeExact((long[]) null, 0, 1L, 1L); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, long.class, long.class)). - invoke(Void.class, 0, 1L, 1L); + invokeExact(Void.class, 0, 1L, 1L); }); checkWMTE(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, Class.class, long.class)). - invoke(array, 0, Void.class, 1L); + invokeExact(array, 0, Void.class, 1L); }); checkWMTE(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, Class.class)). - invoke(array, 0, 1L, Void.class); + invokeExact(array, 0, 1L, Void.class); }); checkWMTE(() -> { // receiver primitive class boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, long.class, long.class)). - invoke(0, 0, 1L, 1L); + invokeExact(0, 0, 1L, 1L); }); checkWMTE(() -> { // index reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, Class.class, long.class, long.class)). - invoke(array, Void.class, 1L, 1L); + invokeExact(array, Void.class, 1L, 1L); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, long.class, Class.class)). - invoke(array, 0, 1L, 1L, Void.class); + invokeExact(array, 0, 1L, 1L, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { // Incorrect argument types checkNPE(() -> { // null receiver - long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class, long.class)). - invoke(null, 0, 1L, 1L); + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, long.class)). + invokeExact((long[]) null, 0, 1L, 1L); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class, long.class)). - invoke(Void.class, 0, 1L, 1L); + invokeExact(Void.class, 0, 1L, 1L); }); checkWMTE(() -> { // expected reference class long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class, long.class)). - invoke(array, 0, Void.class, 1L); + invokeExact(array, 0, Void.class, 1L); }); checkWMTE(() -> { // actual reference class long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)). - invoke(array, 0, 1L, Void.class); + invokeExact(array, 0, 1L, Void.class); }); checkWMTE(() -> { // array primitive class long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class, long.class)). - invoke(0, 0, 1L, 1L); + invokeExact(0, 0, 1L, 1L); }); checkWMTE(() -> { // index reference class long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class, long.class)). - invoke(array, Void.class, 1L, 1L); + invokeExact(array, Void.class, 1L, 1L); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class, long.class)). - invoke(array, 0, 1L, 1L); + invokeExact(array, 0, 1L, 1L); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class, long.class)). - invoke(array, 0, 1L, 1L); + invokeExact(array, 0, 1L, 1L); }); // Incorrect arity checkWMTE(() -> { // 0 long x = (long) hs.get(am, methodType(long.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, long.class, Class.class)). - invoke(array, 0, 1L, 1L, Void.class); + invokeExact(array, 0, 1L, 1L, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null array - long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class)). - invoke(null, 0, 1L); + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class)). + invokeExact((long[]) null, 0, 1L); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class)). - invoke(Void.class, 0, 1L); + invokeExact(Void.class, 0, 1L); }); checkWMTE(() -> { // value reference class long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // array primitive class long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class)). - invoke(0, 0, 1L); + invokeExact(0, 0, 1L); }); checkWMTE(() -> { // index reference class long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class)). - invoke(array, Void.class, 1L); + invokeExact(array, Void.class, 1L); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class)). - invoke(array, 0, 1L); + invokeExact(array, 0, 1L); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class)). - invoke(array, 0, 1L); + invokeExact(array, 0, 1L); }); // Incorrect arity checkWMTE(() -> { // 0 long x = (long) hs.get(am, methodType(long.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)). - invoke(array, 0, 1L, Void.class); + invokeExact(array, 0, 1L, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) { // Incorrect argument types checkNPE(() -> { // null array - long x = (long) hs.get(am, methodType(long.class, Void.class, int.class, long.class)). - invoke(null, 0, 1L); + long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class)). + invokeExact((long[]) null, 0, 1L); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class long x = (long) hs.get(am, methodType(long.class, Class.class, int.class, long.class)). - invoke(Void.class, 0, 1L); + invokeExact(Void.class, 0, 1L); }); checkWMTE(() -> { // value reference class long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // array primitive class long x = (long) hs.get(am, methodType(long.class, int.class, int.class, long.class)). - invoke(0, 0, 1L); + invokeExact(0, 0, 1L); }); checkWMTE(() -> { // index reference class long x = (long) hs.get(am, methodType(long.class, long[].class, Class.class, long.class)). - invoke(array, Void.class, 1L); + invokeExact(array, Void.class, 1L); }); // Incorrect return type checkWMTE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, long[].class, int.class, long.class)). - invoke(array, 0, 1L); + invokeExact(array, 0, 1L); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, long[].class, int.class, long.class)). - invoke(array, 0, 1L); + invokeExact(array, 0, 1L); }); // Incorrect arity checkWMTE(() -> { // 0 long x = (long) hs.get(am, methodType(long.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > long x = (long) hs.get(am, methodType(long.class, long[].class, int.class, long.class, Class.class)). - invoke(array, 0, 1L, Void.class); + invokeExact(array, 0, 1L, Void.class); }); } } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java index 634646e78c1..16efabe0917 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeShort.java @@ -23,6 +23,7 @@ /* * @test + * @bug 8156486 * @run testng/othervm VarHandleTestMethodTypeShort * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeShort */ @@ -81,27 +82,28 @@ public class VarHandleTestMethodTypeShort extends VarHandleBaseTest { public Object[][] accessTestCaseProvider() throws Exception { List<AccessTestCase<?>> cases = new ArrayList<>(); - cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + cases.add(new VarHandleAccessTestCase("Instance field", vhField, vh -> testInstanceFieldWrongMethodType(this, vh), false)); - cases.add(new VarHandleAccessTestCase("Static field wrong method type", + cases.add(new VarHandleAccessTestCase("Static field", vhStaticField, VarHandleTestMethodTypeShort::testStaticFieldWrongMethodType, false)); - cases.add(new VarHandleAccessTestCase("Array wrong method type", + cases.add(new VarHandleAccessTestCase("Array", vhArray, VarHandleTestMethodTypeShort::testArrayWrongMethodType, false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { - cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + cases.add(new MethodHandleAccessTestCase("Instance field", vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), false)); - cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + cases.add(new MethodHandleAccessTestCase("Static field", vhStaticField, f, VarHandleTestMethodTypeShort::testStaticFieldWrongMethodType, false)); - cases.add(new MethodHandleAccessTestCase("Array wrong method type", + cases.add(new MethodHandleAccessTestCase("Array", vhArray, f, VarHandleTestMethodTypeShort::testArrayWrongMethodType, false)); } @@ -329,63 +331,63 @@ public class VarHandleTestMethodTypeShort extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null receiver - short x = (short) hs.get(am, methodType(short.class, Void.class)). - invoke(null); + short x = (short) hs.get(am, methodType(short.class, VarHandleTestMethodTypeShort.class)). + invokeExact((VarHandleTestMethodTypeShort) null); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class short x = (short) hs.get(am, methodType(short.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); checkWMTE(() -> { // receiver primitive class short x = (short) hs.get(am, methodType(short.class, int.class)). - invoke(0); + invokeExact(0); }); // Incorrect return type checkWMTE(() -> { // reference class - Void x = (Void) hs.get(am, methodType(short.class, VarHandleTestMethodTypeShort.class)). - invoke(recv); + Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeShort.class)). + invokeExact(recv); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeShort.class)). - invoke(recv); + invokeExact(recv); }); // Incorrect arity checkWMTE(() -> { // 0 short x = (short) hs.get(am, methodType(short.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > short x = (short) hs.get(am, methodType(short.class, VarHandleTestMethodTypeShort.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - hs.get(am, methodType(void.class, Void.class, short.class)). - invoke(null, (short)1); + hs.get(am, methodType(void.class, VarHandleTestMethodTypeShort.class, short.class)). + invokeExact((VarHandleTestMethodTypeShort) null, (short)1); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class hs.get(am, methodType(void.class, Class.class, short.class)). - invoke(Void.class, (short)1); + invokeExact(Void.class, (short)1); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, VarHandleTestMethodTypeShort.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, short.class)). - invoke(0, (short)1); + invokeExact(0, (short)1); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, VarHandleTestMethodTypeShort.class, short.class, Class.class)). - invoke(recv, (short)1, Void.class); + invokeExact(recv, (short)1, Void.class); }); } @@ -513,32 +515,32 @@ public class VarHandleTestMethodTypeShort extends VarHandleBaseTest { // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); // Incorrect arity checkWMTE(() -> { // > short x = (short) hs.get(am, methodType(Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, short.class, Class.class)). - invoke((short)1, Void.class); + invokeExact((short)1, Void.class); }); } @@ -783,71 +785,71 @@ public class VarHandleTestMethodTypeShort extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null array - short x = (short) hs.get(am, methodType(short.class, Void.class, int.class)). - invoke(null, 0); + short x = (short) hs.get(am, methodType(short.class, short[].class, int.class)). + invokeExact((short[]) null, 0); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class short x = (short) hs.get(am, methodType(short.class, Class.class, int.class)). - invoke(Void.class, 0); + invokeExact(Void.class, 0); }); checkWMTE(() -> { // array primitive class short x = (short) hs.get(am, methodType(short.class, int.class, int.class)). - invoke(0, 0); + invokeExact(0, 0); }); checkWMTE(() -> { // index reference class short x = (short) hs.get(am, methodType(short.class, short[].class, Class.class)). - invoke(array, Void.class); + invokeExact(array, Void.class); }); // Incorrect return type checkWMTE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class, short[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, short[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); // Incorrect arity checkWMTE(() -> { // 0 short x = (short) hs.get(am, methodType(short.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > short x = (short) hs.get(am, methodType(short.class, short[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null array - hs.get(am, methodType(void.class, Void.class, int.class, short.class)). - invoke(null, 0, (short)1); + hs.get(am, methodType(void.class, short[].class, int.class, short.class)). + invokeExact((short[]) null, 0, (short)1); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class hs.get(am, methodType(void.class, Class.class, int.class, short.class)). - invoke(Void.class, 0, (short)1); + invokeExact(Void.class, 0, (short)1); }); checkWMTE(() -> { // value reference class hs.get(am, methodType(void.class, short[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, int.class, short.class)). - invoke(0, 0, (short)1); + invokeExact(0, 0, (short)1); }); checkWMTE(() -> { // index reference class hs.get(am, methodType(void.class, short[].class, Class.class, short.class)). - invoke(array, Void.class, (short)1); + invokeExact(array, Void.class, (short)1); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, short[].class, int.class, Class.class)). - invoke(array, 0, (short)1, Void.class); + invokeExact(array, 0, (short)1, Void.class); }); } diff --git a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java index f3b58c9e2f9..2cc853349ce 100644 --- a/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java +++ b/jdk/test/java/lang/invoke/VarHandles/VarHandleTestMethodTypeString.java @@ -23,6 +23,7 @@ /* * @test + * @bug 8156486 * @run testng/othervm VarHandleTestMethodTypeString * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodTypeString */ @@ -81,27 +82,28 @@ public class VarHandleTestMethodTypeString extends VarHandleBaseTest { public Object[][] accessTestCaseProvider() throws Exception { List<AccessTestCase<?>> cases = new ArrayList<>(); - cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + cases.add(new VarHandleAccessTestCase("Instance field", vhField, vh -> testInstanceFieldWrongMethodType(this, vh), false)); - cases.add(new VarHandleAccessTestCase("Static field wrong method type", + cases.add(new VarHandleAccessTestCase("Static field", vhStaticField, VarHandleTestMethodTypeString::testStaticFieldWrongMethodType, false)); - cases.add(new VarHandleAccessTestCase("Array wrong method type", + cases.add(new VarHandleAccessTestCase("Array", vhArray, VarHandleTestMethodTypeString::testArrayWrongMethodType, false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { - cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + cases.add(new MethodHandleAccessTestCase("Instance field", vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), false)); - cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + cases.add(new MethodHandleAccessTestCase("Static field", vhStaticField, f, VarHandleTestMethodTypeString::testStaticFieldWrongMethodType, false)); - cases.add(new MethodHandleAccessTestCase("Array wrong method type", + cases.add(new MethodHandleAccessTestCase("Array", vhArray, f, VarHandleTestMethodTypeString::testArrayWrongMethodType, false)); } @@ -586,174 +588,174 @@ public class VarHandleTestMethodTypeString extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null receiver - String x = (String) hs.get(am, methodType(String.class, Void.class)). - invoke(null); + String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class)). + invokeExact((VarHandleTestMethodTypeString) null); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class String x = (String) hs.get(am, methodType(String.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); checkWMTE(() -> { // receiver primitive class String x = (String) hs.get(am, methodType(String.class, int.class)). - invoke(0); + invokeExact(0); }); // Incorrect return type - checkCCE(() -> { // reference class - Void x = (Void) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class)). - invoke(recv); + hs.checkWMTEOrCCE(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class)). + invokeExact(recv); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class)). - invoke(recv); + invokeExact(recv); }); // Incorrect arity checkWMTE(() -> { // 0 String x = (String) hs.get(am, methodType(String.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - hs.get(am, methodType(void.class, Void.class, String.class)). - invoke(null, "foo"); + hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, String.class)). + invokeExact((VarHandleTestMethodTypeString) null, "foo"); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class hs.get(am, methodType(void.class, Class.class, String.class)). - invoke(Void.class, "foo"); + invokeExact(Void.class, "foo"); }); - checkCCE(() -> { // value reference class + hs.checkWMTEOrCCE(() -> { // value reference class hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, String.class)). - invoke(0, "foo"); + invokeExact(0, "foo"); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, VarHandleTestMethodTypeString.class, String.class, Class.class)). - invoke(recv, "foo", Void.class); + invokeExact(recv, "foo", Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, String.class, String.class)). - invoke(null, "foo", "foo"); + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, String.class)). + invokeExact((VarHandleTestMethodTypeString) null, "foo", "foo"); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class, String.class)). - invoke(Void.class, "foo", "foo"); + invokeExact(Void.class, "foo", "foo"); }); - checkCCE(() -> { // expected reference class + hs.checkWMTEOrCCE(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, Class.class, String.class)). - invoke(recv, Void.class, "foo"); + invokeExact(recv, Void.class, "foo"); }); - checkCCE(() -> { // actual reference class + hs.checkWMTEOrCCE(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, Class.class)). - invoke(recv, "foo", Void.class); + invokeExact(recv, "foo", Void.class); }); checkWMTE(() -> { // receiver primitive class boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , String.class, String.class)). - invoke(0, "foo", "foo"); + invokeExact(0, "foo", "foo"); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)). - invoke(recv, "foo", "foo", Void.class); + invokeExact(recv, "foo", "foo", Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { checkNPE(() -> { // null receiver - String x = (String) hs.get(am, methodType(String.class, Void.class, String.class, String.class)). - invoke(null, "foo", "foo"); + String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, String.class)). + invokeExact((VarHandleTestMethodTypeString) null, "foo", "foo"); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class String x = (String) hs.get(am, methodType(String.class, Class.class, String.class, String.class)). - invoke(Void.class, "foo", "foo"); + invokeExact(Void.class, "foo", "foo"); }); - checkCCE(() -> { // expected reference class + hs.checkWMTEOrCCE(() -> { // expected reference class String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class, String.class)). - invoke(recv, Void.class, "foo"); + invokeExact(recv, Void.class, "foo"); }); - checkCCE(() -> { // actual reference class + hs.checkWMTEOrCCE(() -> { // actual reference class String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, Class.class)). - invoke(recv, "foo", Void.class); + invokeExact(recv, "foo", Void.class); }); checkWMTE(() -> { // reciever primitive class String x = (String) hs.get(am, methodType(String.class, int.class , String.class, String.class)). - invoke(0, "foo", "foo"); + invokeExact(0, "foo", "foo"); }); // Incorrect return type - checkCCE(() -> { // reference class + hs.checkWMTEOrCCE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class , String.class, String.class)). - invoke(recv, "foo", "foo"); + invokeExact(recv, "foo", "foo"); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class , String.class, String.class)). - invoke(recv, "foo", "foo"); + invokeExact(recv, "foo", "foo"); }); // Incorrect arity checkWMTE(() -> { // 0 String x = (String) hs.get(am, methodType(String.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class, String.class, Class.class)). - invoke(recv, "foo", "foo", Void.class); + invokeExact(recv, "foo", "foo", Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) { checkNPE(() -> { // null receiver - String x = (String) hs.get(am, methodType(String.class, Void.class, String.class)). - invoke(null, "foo"); + String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class)). + invokeExact((VarHandleTestMethodTypeString) null, "foo"); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)). - invoke(Void.class, "foo"); + invokeExact(Void.class, "foo"); }); - checkCCE(() -> { // value reference class + hs.checkWMTEOrCCE(() -> { // value reference class String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // reciever primitive class String x = (String) hs.get(am, methodType(String.class, int.class, String.class)). - invoke(0, "foo"); + invokeExact(0, "foo"); }); // Incorrect return type - checkCCE(() -> { // reference class + hs.checkWMTEOrCCE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodTypeString.class, String.class)). - invoke(recv, "foo"); + invokeExact(recv, "foo"); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodTypeString.class, String.class)). - invoke(recv, "foo"); + invokeExact(recv, "foo"); }); // Incorrect arity checkWMTE(() -> { // 0 String x = (String) hs.get(am, methodType(String.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > String x = (String) hs.get(am, methodType(String.class, VarHandleTestMethodTypeString.class, String.class)). - invoke(recv, "foo", Void.class); + invokeExact(recv, "foo", Void.class); }); } @@ -1054,110 +1056,110 @@ public class VarHandleTestMethodTypeString extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect return type - checkCCE(() -> { // reference class + hs.checkWMTEOrCCE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); // Incorrect arity checkWMTE(() -> { // > String x = (String) hs.get(am, methodType(Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { - checkCCE(() -> { // value reference class + hs.checkWMTEOrCCE(() -> { // value reference class hs.get(am, methodType(void.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, String.class, Class.class)). - invoke("foo", Void.class); + invokeExact("foo", Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types - checkCCE(() -> { // expected reference class + hs.checkWMTEOrCCE(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, String.class)). - invoke(Void.class, "foo"); + invokeExact(Void.class, "foo"); }); - checkCCE(() -> { // actual reference class + hs.checkWMTEOrCCE(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, Class.class)). - invoke("foo", Void.class); + invokeExact("foo", Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class, Class.class)). - invoke("foo", "foo", Void.class); + invokeExact("foo", "foo", Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { // Incorrect argument types - checkCCE(() -> { // expected reference class + hs.checkWMTEOrCCE(() -> { // expected reference class String x = (String) hs.get(am, methodType(String.class, Class.class, String.class)). - invoke(Void.class, "foo"); + invokeExact(Void.class, "foo"); }); - checkCCE(() -> { // actual reference class + hs.checkWMTEOrCCE(() -> { // actual reference class String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)). - invoke("foo", Void.class); + invokeExact("foo", Void.class); }); // Incorrect return type - checkCCE(() -> { // reference class + hs.checkWMTEOrCCE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, String.class, String.class)). - invoke("foo", "foo"); + invokeExact("foo", "foo"); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class, String.class)). - invoke("foo", "foo"); + invokeExact("foo", "foo"); }); // Incorrect arity checkWMTE(() -> { // 0 String x = (String) hs.get(am, methodType(String.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > String x = (String) hs.get(am, methodType(String.class, String.class, String.class, Class.class)). - invoke("foo", "foo", Void.class); + invokeExact("foo", "foo", Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) { // Incorrect argument types - checkCCE(() -> { // value reference class + hs.checkWMTEOrCCE(() -> { // value reference class String x = (String) hs.get(am, methodType(String.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect return type - checkCCE(() -> { // reference class + hs.checkWMTEOrCCE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, String.class)). - invoke("foo"); + invokeExact("foo"); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, String.class)). - invoke("foo"); + invokeExact("foo"); }); // Incorrect arity checkWMTE(() -> { // 0 String x = (String) hs.get(am, methodType(String.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > String x = (String) hs.get(am, methodType(String.class, String.class, Class.class)). - invoke("foo", Void.class); + invokeExact("foo", Void.class); }); } @@ -1686,195 +1688,195 @@ public class VarHandleTestMethodTypeString extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null array - String x = (String) hs.get(am, methodType(String.class, Void.class, int.class)). - invoke(null, 0); + String x = (String) hs.get(am, methodType(String.class, String[].class, int.class)). + invokeExact((String[]) null, 0); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class String x = (String) hs.get(am, methodType(String.class, Class.class, int.class)). - invoke(Void.class, 0); + invokeExact(Void.class, 0); }); checkWMTE(() -> { // array primitive class String x = (String) hs.get(am, methodType(String.class, int.class, int.class)). - invoke(0, 0); + invokeExact(0, 0); }); checkWMTE(() -> { // index reference class String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class)). - invoke(array, Void.class); + invokeExact(array, Void.class); }); // Incorrect return type - checkCCE(() -> { // reference class + hs.checkWMTEOrCCE(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class, String[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); // Incorrect arity checkWMTE(() -> { // 0 String x = (String) hs.get(am, methodType(String.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null array - hs.get(am, methodType(void.class, Void.class, int.class, String.class)). - invoke(null, 0, "foo"); + hs.get(am, methodType(void.class, String[].class, int.class, String.class)). + invokeExact((String[]) null, 0, "foo"); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class hs.get(am, methodType(void.class, Class.class, int.class, String.class)). - invoke(Void.class, 0, "foo"); + invokeExact(Void.class, 0, "foo"); }); - checkCCE(() -> { // value reference class + hs.checkWMTEOrCCE(() -> { // value reference class hs.get(am, methodType(void.class, String[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, int.class, String.class)). - invoke(0, 0, "foo"); + invokeExact(0, 0, "foo"); }); checkWMTE(() -> { // index reference class hs.get(am, methodType(void.class, String[].class, Class.class, String.class)). - invoke(array, Void.class, "foo"); + invokeExact(array, Void.class, "foo"); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, String[].class, int.class, Class.class)). - invoke(array, 0, "foo", Void.class); + invokeExact(array, 0, "foo", Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, String.class, String.class)). - invoke(null, 0, "foo", "foo"); + boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class)). + invokeExact((String[]) null, 0, "foo", "foo"); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, String.class, String.class)). - invoke(Void.class, 0, "foo", "foo"); + invokeExact(Void.class, 0, "foo", "foo"); }); - checkCCE(() -> { // expected reference class + hs.checkWMTEOrCCE(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, Class.class, String.class)). - invoke(array, 0, Void.class, "foo"); + invokeExact(array, 0, Void.class, "foo"); }); - checkCCE(() -> { // actual reference class + hs.checkWMTEOrCCE(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, Class.class)). - invoke(array, 0, "foo", Void.class); + invokeExact(array, 0, "foo", Void.class); }); checkWMTE(() -> { // receiver primitive class boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, String.class, String.class)). - invoke(0, 0, "foo", "foo"); + invokeExact(0, 0, "foo", "foo"); }); checkWMTE(() -> { // index reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, Class.class, String.class, String.class)). - invoke(array, Void.class, "foo", "foo"); + invokeExact(array, Void.class, "foo", "foo"); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class, Class.class)). - invoke(array, 0, "foo", "foo", Void.class); + invokeExact(array, 0, "foo", "foo", Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { // Incorrect argument types checkNPE(() -> { // null receiver - String x = (String) hs.get(am, methodType(String.class, Void.class, int.class, String.class, String.class)). - invoke(null, 0, "foo", "foo"); + String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, String.class)). + invokeExact((String[]) null, 0, "foo", "foo"); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class, String.class)). - invoke(Void.class, 0, "foo", "foo"); + invokeExact(Void.class, 0, "foo", "foo"); }); - checkCCE(() -> { // expected reference class + hs.checkWMTEOrCCE(() -> { // expected reference class String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class, String.class)). - invoke(array, 0, Void.class, "foo"); + invokeExact(array, 0, Void.class, "foo"); }); - checkCCE(() -> { // actual reference class + hs.checkWMTEOrCCE(() -> { // actual reference class String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)). - invoke(array, 0, "foo", Void.class); + invokeExact(array, 0, "foo", Void.class); }); checkWMTE(() -> { // array primitive class String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class, String.class)). - invoke(0, 0, "foo", "foo"); + invokeExact(0, 0, "foo", "foo"); }); checkWMTE(() -> { // index reference class String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class, String.class)). - invoke(array, Void.class, "foo", "foo"); + invokeExact(array, Void.class, "foo", "foo"); }); // Incorrect return type - checkCCE(() -> { // reference class + hs.checkWMTEOrCCE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class, String.class)). - invoke(array, 0, "foo", "foo"); + invokeExact(array, 0, "foo", "foo"); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class, String.class)). - invoke(array, 0, "foo", "foo"); + invokeExact(array, 0, "foo", "foo"); }); // Incorrect arity checkWMTE(() -> { // 0 String x = (String) hs.get(am, methodType(String.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, String.class, Class.class)). - invoke(array, 0, "foo", "foo", Void.class); + invokeExact(array, 0, "foo", "foo", Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null array - String x = (String) hs.get(am, methodType(String.class, Void.class, int.class, String.class)). - invoke(null, 0, "foo"); + String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class)). + invokeExact((String[]) null, 0, "foo"); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class String x = (String) hs.get(am, methodType(String.class, Class.class, int.class, String.class)). - invoke(Void.class, 0, "foo"); + invokeExact(Void.class, 0, "foo"); }); - checkCCE(() -> { // value reference class + hs.checkWMTEOrCCE(() -> { // value reference class String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // array primitive class String x = (String) hs.get(am, methodType(String.class, int.class, int.class, String.class)). - invoke(0, 0, "foo"); + invokeExact(0, 0, "foo"); }); checkWMTE(() -> { // index reference class String x = (String) hs.get(am, methodType(String.class, String[].class, Class.class, String.class)). - invoke(array, Void.class, "foo"); + invokeExact(array, Void.class, "foo"); }); // Incorrect return type - checkCCE(() -> { // reference class + hs.checkWMTEOrCCE(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, String[].class, int.class, String.class)). - invoke(array, 0, "foo"); + invokeExact(array, 0, "foo"); }); checkWMTE(() -> { // primitive class boolean x = (boolean) hs.get(am, methodType(boolean.class, String[].class, int.class, String.class)). - invoke(array, 0, "foo"); + invokeExact(array, 0, "foo"); }); // Incorrect arity checkWMTE(() -> { // 0 String x = (String) hs.get(am, methodType(String.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > String x = (String) hs.get(am, methodType(String.class, String[].class, int.class, String.class, Class.class)). - invoke(array, 0, "foo", Void.class); + invokeExact(array, 0, "foo", Void.class); }); } diff --git a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template index 391dc1a5197..cb33f8ff070 100644 --- a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template +++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccess$Type$ * @run testng/othervm -Diters=20000 VarHandleTestAccess$Type$ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccess$Type$ + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestAccess$Type$ */ import org.testng.annotations.BeforeClass; @@ -309,6 +310,10 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { checkUOE(() -> { boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); }); + + checkUOE(() -> { + $type$ r = ($type$) vh.getAndSet(recv, $value1$); + }); #end[CAS] #if[!AtomicAdd] @@ -399,6 +404,10 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { checkUOE(() -> { boolean r = vh.weakCompareAndSetRelease($value1$, $value2$); }); + + checkUOE(() -> { + $type$ r = ($type$) vh.getAndSet($value1$); + }); #end[CAS] #if[!AtomicAdd] @@ -504,29 +513,41 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } { - boolean r = vh.weakCompareAndSet(recv, $value1$, $value2$); - assertEquals(r, true, "weakCompareAndSet $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(recv, $value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(recv); assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); } { - boolean r = vh.weakCompareAndSetAcquire(recv, $value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(recv, $value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(recv); assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); } { - boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); - assertEquals(r, true, "weakCompareAndSetRelease $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(recv); assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); } { - boolean r = vh.weakCompareAndSetVolatile(recv, $value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetVolatile $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetVolatile(recv, $value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetVolatile $type$"); $type$ x = ($type$) vh.get(recv); assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value"); } @@ -586,6 +607,10 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { checkUOE(() -> { boolean r = vh.weakCompareAndSetRelease(recv, $value1$, $value2$); }); + + checkUOE(() -> { + $type$ r = ($type$) vh.getAndSet(recv, $value1$); + }); #end[CAS] #if[!AtomicAdd] @@ -691,36 +716,48 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } { - boolean r = (boolean) vh.weakCompareAndSet($value1$, $value2$); - assertEquals(r, true, "weakCompareAndSet $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet($value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(); assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); } { - boolean r = (boolean) vh.weakCompareAndSetAcquire($value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire($value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(); assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); } { - boolean r = (boolean) vh.weakCompareAndSetRelease($value1$, $value2$); - assertEquals(r, true, "weakCompareAndSetRelease $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease($value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(); assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); } { - boolean r = (boolean) vh.weakCompareAndSetVolatile($value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetVolatile $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease($value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetVolatile $type$"); $type$ x = ($type$) vh.get(); - assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value"); + assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$"); } // Compare set and get { - $type$ o = ($type$) vh.getAndSet( $value2$); + $type$ o = ($type$) vh.getAndSet($value2$); assertEquals(o, $value1$, "getAndSet $type$"); $type$ x = ($type$) vh.get(); assertEquals(x, $value2$, "getAndSet $type$ value"); @@ -773,6 +810,10 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { checkUOE(() -> { boolean r = vh.weakCompareAndSetRelease($value1$, $value2$); }); + + checkUOE(() -> { + $type$ r = ($type$) vh.getAndSet($value1$); + }); #end[CAS] #if[!AtomicAdd] @@ -881,31 +922,43 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { } { - boolean r = vh.weakCompareAndSet(array, i, $value1$, $value2$); - assertEquals(r, true, "weakCompareAndSet $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, $value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, $value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, $value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$); - assertEquals(r, true, "weakCompareAndSetRelease $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); } { - boolean r = vh.weakCompareAndSetVolatile(array, i, $value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetVolatile $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetVolatile(array, i, $value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetVolatile $type$"); $type$ x = ($type$) vh.get(array, i); - assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value"); + assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$"); } // Compare set and get @@ -967,6 +1020,10 @@ public class VarHandleTestAccess$Type$ extends VarHandleBaseTest { checkUOE(() -> { boolean r = vh.weakCompareAndSetRelease(array, i, $value1$, $value2$); }); + + checkUOE(() -> { + $type$ r = ($type$) vh.getAndSet(array, i, $value1$); + }); #end[CAS] #if[!AtomicAdd] diff --git a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template index e433789f8cd..1cb19b7893e 100644 --- a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template +++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestByteArrayView.java.template @@ -27,6 +27,7 @@ * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestByteArrayAs$Type$ * @run testng/othervm -Diters=20000 VarHandleTestByteArrayAs$Type$ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestByteArrayAs$Type$ + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestByteArrayAs$Type$ */ import org.testng.annotations.DataProvider; @@ -311,10 +312,12 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { checkROBE(() -> { $type$ o = ($type$) vh.getAndSet(array, ci, VALUE_1); }); + +#else[CAS] checkUOE(() -> { boolean r = vh.compareAndSet(array, ci, VALUE_1, VALUE_2); }); -#else[CAS] + checkUOE(() -> { $type$ r = ($type$) vh.compareAndExchangeVolatile(array, ci, VALUE_2, VALUE_1); }); @@ -884,22 +887,31 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { } { - boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSet $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); - assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + } + assertEquals(success, true, "weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSetRelease $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); } @@ -1037,22 +1049,31 @@ public class VarHandleTestByteArrayAs$Type$ extends VarHandleBaseByteArrayTest { } { - boolean r = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSet $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSet(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSet $type$"); $type$ x = ($type$) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSet $type$ value"); } { - boolean r = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); - assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetAcquire(array, i, VALUE_2, VALUE_1); + } + assertEquals(success, true, "weakCompareAndSetAcquire $type$"); $type$ x = ($type$) vh.get(array, i); assertEquals(x, VALUE_1, "weakCompareAndSetAcquire $type$"); } { - boolean r = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); - assertEquals(r, true, "weakCompareAndSetRelease $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = vh.weakCompareAndSetRelease(array, i, VALUE_1, VALUE_2); + } + assertEquals(success, true, "weakCompareAndSetRelease $type$"); $type$ x = ($type$) vh.get(array, i); assertEquals(x, VALUE_2, "weakCompareAndSetRelease $type$"); } diff --git a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template index f56d9a641a7..f943bf2611b 100644 --- a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template +++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodHandleAccess.java.template @@ -24,6 +24,7 @@ /* * @test * @run testng/othervm -Diters=20000 VarHandleTestMethodHandleAccess$Type$ + * @run testng/othervm -Diters=20000 -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodHandleAccess$Type$ */ import org.testng.annotations.BeforeClass; @@ -209,31 +210,43 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, $value1$, $value2$); - assertEquals(r, true, "weakCompareAndSet $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(recv, $value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, $value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(recv, $value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, $value1$, $value2$); - assertEquals(r, true, "weakCompareAndSetRelease $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(recv, $value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, $value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetVolatile $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(recv, $value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetVolatile $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(recv); - assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value"); + assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$"); } // Compare set and get @@ -380,36 +393,48 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact($value1$, $value2$); - assertEquals(r, true, "weakCompareAndSet $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact($value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact($value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact($value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact($value1$, $value2$); - assertEquals(r, true, "weakCompareAndSetRelease $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact($value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact($value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetVolatile $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact($value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetVolatile $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); - assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value"); + assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$"); } // Compare set and get { - $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact($value2$); + $type$ o = ($type$) hs.get(TestAccessMode.GET_AND_SET).invokeExact( $value2$); assertEquals(o, $value1$, "getAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(); assertEquals(x, $value2$, "getAndSet $type$ value"); @@ -554,31 +579,43 @@ public class VarHandleTestMethodHandleAccess$Type$ extends VarHandleBaseTest { } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, $value1$, $value2$); - assertEquals(r, true, "weakCompareAndSet $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET).invokeExact(array, i, $value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSet $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, $value2$, "weakCompareAndSet $type$ value"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, $value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetAcquire $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_ACQUIRE).invokeExact(array, i, $value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetAcquire $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, $value1$, "weakCompareAndSetAcquire $type$"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, $value1$, $value2$); - assertEquals(r, true, "weakCompareAndSetRelease $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_RELEASE).invokeExact(array, i, $value1$, $value2$); + } + assertEquals(success, true, "weakCompareAndSetRelease $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); assertEquals(x, $value2$, "weakCompareAndSetRelease $type$"); } { - boolean r = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, $value2$, $value1$); - assertEquals(r, true, "weakCompareAndSetVolatile $type$"); + boolean success = false; + for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { + success = (boolean) hs.get(TestAccessMode.WEAK_COMPARE_AND_SET_VOLATILE).invokeExact(array, i, $value2$, $value1$); + } + assertEquals(success, true, "weakCompareAndSetVolatile $type$"); $type$ x = ($type$) hs.get(TestAccessMode.GET).invokeExact(array, i); - assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$ value"); + assertEquals(x, $value1$, "weakCompareAndSetVolatile $type$"); } // Compare set and get diff --git a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template index fe504902f10..5bec8b46a10 100644 --- a/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template +++ b/jdk/test/java/lang/invoke/VarHandles/X-VarHandleTestMethodType.java.template @@ -23,6 +23,7 @@ /* * @test + * @bug 8156486 * @run testng/othervm VarHandleTestMethodType$Type$ * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false VarHandleTestMethodType$Type$ */ @@ -81,27 +82,28 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { public Object[][] accessTestCaseProvider() throws Exception { List<AccessTestCase<?>> cases = new ArrayList<>(); - cases.add(new VarHandleAccessTestCase("Instance field wrong method type", + cases.add(new VarHandleAccessTestCase("Instance field", vhField, vh -> testInstanceFieldWrongMethodType(this, vh), false)); - cases.add(new VarHandleAccessTestCase("Static field wrong method type", + cases.add(new VarHandleAccessTestCase("Static field", vhStaticField, VarHandleTestMethodType$Type$::testStaticFieldWrongMethodType, false)); - cases.add(new VarHandleAccessTestCase("Array wrong method type", + cases.add(new VarHandleAccessTestCase("Array", vhArray, VarHandleTestMethodType$Type$::testArrayWrongMethodType, false)); + for (VarHandleToMethodHandle f : VarHandleToMethodHandle.values()) { - cases.add(new MethodHandleAccessTestCase("Instance field wrong method type", + cases.add(new MethodHandleAccessTestCase("Instance field", vhField, f, hs -> testInstanceFieldWrongMethodType(this, hs), false)); - cases.add(new MethodHandleAccessTestCase("Static field wrong method type", + cases.add(new MethodHandleAccessTestCase("Static field", vhStaticField, f, VarHandleTestMethodType$Type$::testStaticFieldWrongMethodType, false)); - cases.add(new MethodHandleAccessTestCase("Array wrong method type", + cases.add(new MethodHandleAccessTestCase("Array", vhArray, f, VarHandleTestMethodType$Type$::testArrayWrongMethodType, false)); } @@ -648,63 +650,63 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null receiver - $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class)). - invoke(null); + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class)). + invokeExact((VarHandleTestMethodType$Type$) null); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); checkWMTE(() -> { // receiver primitive class $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class)). - invoke(0); + invokeExact(0); }); // Incorrect return type - check{#if[String]?CCE:WMTE}(() -> { // reference class - Void x = (Void) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class)). - invoke(recv); + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // reference class + Void x = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class)). + invokeExact(recv); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class)). - invoke(recv); + invokeExact(recv); }); // Incorrect arity checkWMTE(() -> { // 0 $type$ x = ($type$) hs.get(am, methodType($type$.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - hs.get(am, methodType(void.class, Void.class, $type$.class)). - invoke(null, $value1$); + hs.get(am, methodType(void.class, VarHandleTestMethodType$Type$.class, $type$.class)). + invokeExact((VarHandleTestMethodType$Type$) null, $value1$); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class hs.get(am, methodType(void.class, Class.class, $type$.class)). - invoke(Void.class, $value1$); + invokeExact(Void.class, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // value reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // value reference class hs.get(am, methodType(void.class, VarHandleTestMethodType$Type$.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, $type$.class)). - invoke(0, $value1$); + invokeExact(0, $value1$); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)). - invoke(recv, $value1$, Void.class); + invokeExact(recv, $value1$, Void.class); }); } @@ -712,111 +714,111 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, $type$.class, $type$.class)). - invoke(null, $value1$, $value1$); + boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, $type$.class, $type$.class)). + invokeExact((VarHandleTestMethodType$Type$) null, $value1$, $value1$); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, $type$.class, $type$.class)). - invoke(Void.class, $value1$, $value1$); + invokeExact(Void.class, $value1$, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // expected reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, Class.class, $type$.class)). - invoke(recv, Void.class, $value1$); + invokeExact(recv, Void.class, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // actual reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)). - invoke(recv, $value1$, Void.class); + invokeExact(recv, $value1$, Void.class); }); checkWMTE(() -> { // receiver primitive class boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class , $type$.class, $type$.class)). - invoke(0, $value1$, $value1$); + invokeExact(0, $value1$, $value1$); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, VarHandleTestMethodType$Type$.class, $type$.class, $type$.class, Class.class)). - invoke(recv, $value1$, $value1$, Void.class); + invokeExact(recv, $value1$, $value1$, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { checkNPE(() -> { // null receiver - $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class, $type$.class)). - invoke(null, $value1$, $value1$); + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class, $type$.class)). + invokeExact((VarHandleTestMethodType$Type$) null, $value1$, $value1$); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class, $type$.class)). - invoke(Void.class, $value1$, $value1$); + invokeExact(Void.class, $value1$, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // expected reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // expected reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class, $type$.class)). - invoke(recv, Void.class, $value1$); + invokeExact(recv, Void.class, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // actual reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // actual reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class, Class.class)). - invoke(recv, $value1$, Void.class); + invokeExact(recv, $value1$, Void.class); }); checkWMTE(() -> { // reciever primitive class $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class , $type$.class, $type$.class)). - invoke(0, $value1$, $value1$); + invokeExact(0, $value1$, $value1$); }); // Incorrect return type - check{#if[String]?CCE:WMTE}(() -> { // reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class , $type$.class, $type$.class)). - invoke(recv, $value1$, $value1$); + invokeExact(recv, $value1$, $value1$); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class , $type$.class, $type$.class)). - invoke(recv, $value1$, $value1$); + invokeExact(recv, $value1$, $value1$); }); // Incorrect arity checkWMTE(() -> { // 0 $type$ x = ($type$) hs.get(am, methodType($type$.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class, $type$.class, Class.class)). - invoke(recv, $value1$, $value1$, Void.class); + invokeExact(recv, $value1$, $value1$, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) { checkNPE(() -> { // null receiver - $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class)). - invoke(null, $value1$); + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class)). + invokeExact((VarHandleTestMethodType$Type$) null, $value1$); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)). - invoke(Void.class, $value1$); + invokeExact(Void.class, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // value reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // value reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // reciever primitive class $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, $type$.class)). - invoke(0, $value1$); + invokeExact(0, $value1$); }); // Incorrect return type - check{#if[String]?CCE:WMTE}(() -> { // reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class, $type$.class)). - invoke(recv, $value1$); + invokeExact(recv, $value1$); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class, $type$.class)). - invoke(recv, $value1$); + invokeExact(recv, $value1$); }); // Incorrect arity checkWMTE(() -> { // 0 $type$ x = ($type$) hs.get(am, methodType($type$.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class)). - invoke(recv, $value1$, Void.class); + invokeExact(recv, $value1$, Void.class); }); } #end[CAS] @@ -824,38 +826,38 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { #if[AtomicAdd] for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) { checkNPE(() -> { // null receiver - $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, $type$.class)). - invoke(null, $value1$); + $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class)). + invokeExact((VarHandleTestMethodType$Type$) null, $value1$); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)). - invoke(Void.class, $value1$); + invokeExact(Void.class, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // value reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // value reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, Class.class)). - invoke(recv, Void.class); + invokeExact(recv, Void.class); }); checkWMTE(() -> { // reciever primitive class $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, $type$.class)). - invoke(0, $value1$); + invokeExact(0, $value1$); }); // Incorrect return type - check{#if[String]?CCE:WMTE}(() -> { // reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, VarHandleTestMethodType$Type$.class, $type$.class)). - invoke(recv, $value1$); + invokeExact(recv, $value1$); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, VarHandleTestMethodType$Type$.class, $type$.class)). - invoke(recv, $value1$); + invokeExact(recv, $value1$); }); // Incorrect arity checkWMTE(() -> { // 0 $type$ x = ($type$) hs.get(am, methodType($type$.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType($type$.class, VarHandleTestMethodType$Type$.class, $type$.class)). - invoke(recv, $value1$, Void.class); + invokeExact(recv, $value1$, Void.class); }); } #end[AtomicAdd] @@ -1200,111 +1202,111 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect return type - check{#if[String]?CCE:WMTE}(() -> { // reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class)). - invoke(); + invokeExact(); }); // Incorrect arity checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType(Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { - check{#if[String]?CCE:WMTE}(() -> { // value reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // value reference class hs.get(am, methodType(void.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, $type$.class, Class.class)). - invoke($value1$, Void.class); + invokeExact($value1$, Void.class); }); } #if[CAS] for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types - check{#if[String]?CCE:WMTE}(() -> { // expected reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, $type$.class)). - invoke(Void.class, $value1$); + invokeExact(Void.class, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // actual reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$.class, Class.class)). - invoke($value1$, Void.class); + invokeExact($value1$, Void.class); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$.class, $type$.class, Class.class)). - invoke($value1$, $value1$, Void.class); + invokeExact($value1$, $value1$, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { // Incorrect argument types - check{#if[String]?CCE:WMTE}(() -> { // expected reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // expected reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, $type$.class)). - invoke(Void.class, $value1$); + invokeExact(Void.class, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // actual reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // actual reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)). - invoke($value1$, Void.class); + invokeExact($value1$, Void.class); }); // Incorrect return type - check{#if[String]?CCE:WMTE}(() -> { // reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, $type$.class, $type$.class)). - invoke($value1$, $value1$); + invokeExact($value1$, $value1$); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class, $type$.class)). - invoke($value1$, $value1$); + invokeExact($value1$, $value1$); }); // Incorrect arity checkWMTE(() -> { // 0 $type$ x = ($type$) hs.get(am, methodType($type$.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, $type$.class, Class.class)). - invoke($value1$, $value1$, Void.class); + invokeExact($value1$, $value1$, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) { // Incorrect argument types - check{#if[String]?CCE:WMTE}(() -> { // value reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // value reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect return type - check{#if[String]?CCE:WMTE}(() -> { // reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, $type$.class)). - invoke($value1$); + invokeExact($value1$); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class)). - invoke($value1$); + invokeExact($value1$); }); // Incorrect arity checkWMTE(() -> { // 0 $type$ x = ($type$) hs.get(am, methodType($type$.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)). - invoke($value1$, Void.class); + invokeExact($value1$, Void.class); }); } #end[CAS] @@ -1314,25 +1316,25 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { // Incorrect argument types check{#if[String]?CCE:WMTE}(() -> { // value reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class)). - invoke(Void.class); + invokeExact(Void.class); }); // Incorrect return type check{#if[String]?CCE:WMTE}(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, $type$.class)). - invoke($value1$); + invokeExact($value1$); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$.class)). - invoke($value1$); + invokeExact($value1$); }); // Incorrect arity checkWMTE(() -> { // 0 $type$ x = ($type$) hs.get(am, methodType($type$.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$.class, Class.class)). - invoke($value1$, Void.class); + invokeExact($value1$, Void.class); }); } #end[AtomicAdd] @@ -1929,196 +1931,196 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET)) { // Incorrect argument types checkNPE(() -> { // null array - $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class)). - invoke(null, 0); + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class)). + invokeExact(($type$[]) null, 0); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class)). - invoke(Void.class, 0); + invokeExact(Void.class, 0); }); checkWMTE(() -> { // array primitive class $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class)). - invoke(0, 0); + invokeExact(0, 0); }); checkWMTE(() -> { // index reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class)). - invoke(array, Void.class); + invokeExact(array, Void.class); }); // Incorrect return type - check{#if[String]?CCE:WMTE}(() -> { // reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // reference class Void x = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class)). - invoke(array, 0); + invokeExact(array, 0); }); // Incorrect arity checkWMTE(() -> { // 0 $type$ x = ($type$) hs.get(am, methodType($type$.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.SET)) { // Incorrect argument types checkNPE(() -> { // null array - hs.get(am, methodType(void.class, Void.class, int.class, $type$.class)). - invoke(null, 0, $value1$); + hs.get(am, methodType(void.class, $type$[].class, int.class, $type$.class)). + invokeExact(($type$[]) null, 0, $value1$); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class hs.get(am, methodType(void.class, Class.class, int.class, $type$.class)). - invoke(Void.class, 0, $value1$); + invokeExact(Void.class, 0, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // value reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // value reference class hs.get(am, methodType(void.class, $type$[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // receiver primitive class hs.get(am, methodType(void.class, int.class, int.class, $type$.class)). - invoke(0, 0, $value1$); + invokeExact(0, 0, $value1$); }); checkWMTE(() -> { // index reference class hs.get(am, methodType(void.class, $type$[].class, Class.class, $type$.class)). - invoke(array, Void.class, $value1$); + invokeExact(array, Void.class, $value1$); }); // Incorrect arity checkWMTE(() -> { // 0 hs.get(am, methodType(void.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > hs.get(am, methodType(void.class, $type$[].class, int.class, Class.class)). - invoke(array, 0, $value1$, Void.class); + invokeExact(array, 0, $value1$, Void.class); }); } #if[CAS] for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null receiver - boolean r = (boolean) hs.get(am, methodType(boolean.class, Void.class, int.class, $type$.class, $type$.class)). - invoke(null, 0, $value1$, $value1$); + boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, $type$.class, $type$.class)). + invokeExact(($type$[]) null, 0, $value1$, $value1$); }); - checkCCE(() -> { // receiver reference class + hs.checkWMTEOrCCE(() -> { // receiver reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, Class.class, int.class, $type$.class, $type$.class)). - invoke(Void.class, 0, $value1$, $value1$); + invokeExact(Void.class, 0, $value1$, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // expected reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // expected reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, Class.class, $type$.class)). - invoke(array, 0, Void.class, $value1$); + invokeExact(array, 0, Void.class, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // actual reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // actual reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, $type$.class, Class.class)). - invoke(array, 0, $value1$, Void.class); + invokeExact(array, 0, $value1$, Void.class); }); checkWMTE(() -> { // receiver primitive class boolean r = (boolean) hs.get(am, methodType(boolean.class, int.class, int.class, $type$.class, $type$.class)). - invoke(0, 0, $value1$, $value1$); + invokeExact(0, 0, $value1$, $value1$); }); checkWMTE(() -> { // index reference class boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, Class.class, $type$.class, $type$.class)). - invoke(array, Void.class, $value1$, $value1$); + invokeExact(array, Void.class, $value1$, $value1$); }); // Incorrect arity checkWMTE(() -> { // 0 boolean r = (boolean) hs.get(am, methodType(boolean.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > boolean r = (boolean) hs.get(am, methodType(boolean.class, $type$[].class, int.class, $type$.class, $type$.class, Class.class)). - invoke(array, 0, $value1$, $value1$, Void.class); + invokeExact(array, 0, $value1$, $value1$, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.COMPARE_AND_EXCHANGE)) { // Incorrect argument types checkNPE(() -> { // null receiver - $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class, $type$.class)). - invoke(null, 0, $value1$, $value1$); + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, $type$.class)). + invokeExact(($type$[]) null, 0, $value1$, $value1$); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class, $type$.class)). - invoke(Void.class, 0, $value1$, $value1$); + invokeExact(Void.class, 0, $value1$, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // expected reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // expected reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class, $type$.class)). - invoke(array, 0, Void.class, $value1$); + invokeExact(array, 0, Void.class, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // actual reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // actual reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)). - invoke(array, 0, $value1$, Void.class); + invokeExact(array, 0, $value1$, Void.class); }); checkWMTE(() -> { // array primitive class $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class, $type$.class)). - invoke(0, 0, $value1$, $value1$); + invokeExact(0, 0, $value1$, $value1$); }); checkWMTE(() -> { // index reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class, $type$.class)). - invoke(array, Void.class, $value1$, $value1$); + invokeExact(array, Void.class, $value1$, $value1$); }); // Incorrect return type - check{#if[String]?CCE:WMTE}(() -> { // reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class, $type$.class)). - invoke(array, 0, $value1$, $value1$); + invokeExact(array, 0, $value1$, $value1$); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class, $type$.class)). - invoke(array, 0, $value1$, $value1$); + invokeExact(array, 0, $value1$, $value1$); }); // Incorrect arity checkWMTE(() -> { // 0 $type$ x = ($type$) hs.get(am, methodType($type$.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, $type$.class, Class.class)). - invoke(array, 0, $value1$, $value1$, Void.class); + invokeExact(array, 0, $value1$, $value1$, Void.class); }); } for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_SET)) { // Incorrect argument types checkNPE(() -> { // null array - $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class)). - invoke(null, 0, $value1$); + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class)). + invokeExact(($type$[]) null, 0, $value1$); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class)). - invoke(Void.class, 0, $value1$); + invokeExact(Void.class, 0, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // value reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // value reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // array primitive class $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class)). - invoke(0, 0, $value1$); + invokeExact(0, 0, $value1$); }); checkWMTE(() -> { // index reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class)). - invoke(array, Void.class, $value1$); + invokeExact(array, Void.class, $value1$); }); // Incorrect return type - check{#if[String]?CCE:WMTE}(() -> { // reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class)). - invoke(array, 0, $value1$); + invokeExact(array, 0, $value1$); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class)). - invoke(array, 0, $value1$); + invokeExact(array, 0, $value1$); }); // Incorrect arity checkWMTE(() -> { // 0 $type$ x = ($type$) hs.get(am, methodType($type$.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)). - invoke(array, 0, $value1$, Void.class); + invokeExact(array, 0, $value1$, Void.class); }); } #end[CAS] @@ -2127,42 +2129,42 @@ public class VarHandleTestMethodType$Type$ extends VarHandleBaseTest { for (TestAccessMode am : testAccessModesOfType(TestAccessType.GET_AND_ADD)) { // Incorrect argument types checkNPE(() -> { // null array - $type$ x = ($type$) hs.get(am, methodType($type$.class, Void.class, int.class, $type$.class)). - invoke(null, 0, $value1$); + $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class)). + invokeExact(($type$[]) null, 0, $value1$); }); - checkCCE(() -> { // array reference class + hs.checkWMTEOrCCE(() -> { // array reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, Class.class, int.class, $type$.class)). - invoke(Void.class, 0, $value1$); + invokeExact(Void.class, 0, $value1$); }); - check{#if[String]?CCE:WMTE}(() -> { // value reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // value reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, Class.class)). - invoke(array, 0, Void.class); + invokeExact(array, 0, Void.class); }); checkWMTE(() -> { // array primitive class $type$ x = ($type$) hs.get(am, methodType($type$.class, int.class, int.class, $type$.class)). - invoke(0, 0, $value1$); + invokeExact(0, 0, $value1$); }); checkWMTE(() -> { // index reference class $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, Class.class, $type$.class)). - invoke(array, Void.class, $value1$); + invokeExact(array, Void.class, $value1$); }); // Incorrect return type - check{#if[String]?CCE:WMTE}(() -> { // reference class + {#if[String]?hs.checkWMTEOrCCE:checkWMTE}(() -> { // reference class Void r = (Void) hs.get(am, methodType(Void.class, $type$[].class, int.class, $type$.class)). - invoke(array, 0, $value1$); + invokeExact(array, 0, $value1$); }); checkWMTE(() -> { // primitive class $wrong_primitive_type$ x = ($wrong_primitive_type$) hs.get(am, methodType($wrong_primitive_type$.class, $type$[].class, int.class, $type$.class)). - invoke(array, 0, $value1$); + invokeExact(array, 0, $value1$); }); // Incorrect arity checkWMTE(() -> { // 0 $type$ x = ($type$) hs.get(am, methodType($type$.class)). - invoke(); + invokeExact(); }); checkWMTE(() -> { // > $type$ x = ($type$) hs.get(am, methodType($type$.class, $type$[].class, int.class, $type$.class, Class.class)). - invoke(array, 0, $value1$, Void.class); + invokeExact(array, 0, $value1$, Void.class); }); } #end[AtomicAdd] diff --git a/jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh b/jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh index 7d6afc7b206..436d2d371d9 100644 --- a/jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh +++ b/jdk/test/java/lang/invoke/VarHandles/generate-vh-tests.sh @@ -113,36 +113,40 @@ do ;; esac + # The value of `value3` is chosen such that when added to `value1` or `value2` + # it will result in carrying of bits over to the next byte, thereby detecting + # possible errors in endianness conversion e.g. if say for atomic addition the + # augend is incorrectly processed case $type in short) value1=(short)0x0102 value2=(short)0x1112 - value3=(short)0x2122 + value3=(short)0xFFFE ;; char) value1=(char)0x0102 value2=(char)0x1112 - value3=(char)0x2122 + value3=(char)0xFFFE ;; int) value1=0x01020304 value2=0x11121314 - value3=0x21222324 + value3=0xFFFEFDFC ;; long) value1=0x0102030405060708L value2=0x1112131415161718L - value3=0x2122232425262728L + value3=0xFFFEFDFCFBFAF9F8L ;; float) value1=0x01020304 value2=0x11121314 - value3=0x21222324 + value3=0xFFFEFDFC ;; double) value1=0x0102030405060708L value2=0x1112131415161718L - value3=0x2122232425262728L + value3=0xFFFEFDFCFBFAF9F8L ;; esac diff --git a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java index 195cb3a2fd8..2d52eeb4299 100644 --- a/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java +++ b/jdk/test/java/lang/management/MemoryMXBean/ResetPeakMemoryUsage.java @@ -36,9 +36,13 @@ * @modules jdk.management * @build jdk.testlibrary.* ResetPeakMemoryUsage MemoryUtil RunUtil * @run main ResetPeakMemoryUsage + * @requires vm.opt.ExplicitGCInvokesConcurrent != "true" + * @requires vm.opt.ExplicitGCInvokesConcurrentAndUnloadsClasses != "true" + * @requires vm.opt.DisableExplicitGC != "true" */ import java.lang.management.*; +import java.lang.ref.WeakReference; import java.util.*; public class ResetPeakMemoryUsage { @@ -100,6 +104,7 @@ public class ResetPeakMemoryUsage { printMemoryUsage(usage0, peak0); obj = new Object[largeArraySize]; + WeakReference<Object> weakRef = new WeakReference<>(obj); MemoryUsage usage1 = mpool.getUsage(); MemoryUsage peak1 = mpool.getPeakUsage(); @@ -124,7 +129,11 @@ public class ResetPeakMemoryUsage { // The object is now garbage and do a GC // memory usage should drop obj = null; - mbean.gc(); + + //This will cause sure shot GC unlike Runtime.gc() invoked by mbean.gc() + while(weakRef.get() != null) { + mbean.gc(); + } MemoryUsage usage2 = mpool.getUsage(); MemoryUsage peak2 = mpool.getPeakUsage(); diff --git a/jdk/test/java/lang/management/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java b/jdk/test/java/lang/management/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java index ac0bc89f98c..63f5c5fbc31 100644 --- a/jdk/test/java/lang/management/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java +++ b/jdk/test/java/lang/management/PlatformLoggingMXBean/PlatformLoggingMXBeanTest.java @@ -270,8 +270,7 @@ public class PlatformLoggingMXBeanTest // Calling getMBeanInfo will throw exception if not found. platformMBS.getMBeanInfo(objName); - if (!platformMBS.isInstanceOf(objName, "java.lang.management.PlatformLoggingMXBean") || - !platformMBS.isInstanceOf(objName, "java.util.logging.LoggingMXBean")) { + if (!platformMBS.isInstanceOf(objName, "java.lang.management.PlatformLoggingMXBean")) { throw new RuntimeException(objName + " is of unexpected type"); } diff --git a/jdk/test/java/lang/reflect/Layer/LayerAndLoadersTest.java b/jdk/test/java/lang/reflect/Layer/LayerAndLoadersTest.java index b37813fd290..6a0cd78a241 100644 --- a/jdk/test/java/lang/reflect/Layer/LayerAndLoadersTest.java +++ b/jdk/test/java/lang/reflect/Layer/LayerAndLoadersTest.java @@ -24,6 +24,7 @@ /** * @test * @library /lib/testlibrary + * @modules jdk.compiler * @build LayerAndLoadersTest CompilerUtils ModuleUtils * @run testng LayerAndLoadersTest * @summary Tests for java.lang.reflect.Layer@createWithXXX methods diff --git a/jdk/test/java/net/httpclient/http2/TLSConnection.java b/jdk/test/java/net/httpclient/http2/TLSConnection.java new file mode 100644 index 00000000000..f2721eb268e --- /dev/null +++ b/jdk/test/java/net/httpclient/http2/TLSConnection.java @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.http.Http2Handler; +import java.net.http.Http2TestExchange; +import java.net.http.Http2TestServer; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.SSLSession; + +/* + * @test + * @bug 8150769 8157107 + * @summary Checks that SSL parameters can be set for HTTP/2 connection + * @modules java.httpclient + * @compile/module=java.httpclient java/net/http/Http2Handler.java + * @compile/module=java.httpclient java/net/http/Http2TestExchange.java + * @compile/module=java.httpclient java/net/http/Http2TestServer.java + * @run main/othervm TLSConnection + */ +public class TLSConnection { + + private static final String KEYSTORE = System.getProperty("test.src") + + File.separator + "keystore.p12"; + private static final String PASSWORD = "password"; + + public static void main(String[] args) throws Exception { + + // enable all logging + System.setProperty("java.net.http.HttpClient.log", "all,frames:all"); + + // initialize JSSE + System.setProperty("javax.net.ssl.keyStore", KEYSTORE); + System.setProperty("javax.net.ssl.keyStorePassword", PASSWORD); + System.setProperty("javax.net.ssl.trustStore", KEYSTORE); + System.setProperty("javax.net.ssl.trustStorePassword", PASSWORD); + + Handler handler = new Handler(); + + try (Http2TestServer server = new Http2TestServer(true, 0, handler)) { + server.start(); + + int port = server.getAddress().getPort(); + String uriString = "https://127.0.0.1:" + Integer.toString(port); + + // run test cases + boolean success = true; + + SSLParameters parameters = null; + success &= expectFailure( + "Test #1: SSL parameters is null, expect NPE", + () -> connect(uriString, parameters), + NullPointerException.class); + + success &= expectSuccess( + "Test #2: default SSL parameters, " + + "expect successful connection", + () -> connect(uriString, new SSLParameters())); + success &= checkProtocol(handler.getSSLSession(), "TLSv1.2"); + + // set SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA cipher suite + // which has less priority in default cipher suite list + success &= expectSuccess( + "Test #3: SSL parameters with " + + "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA cipher suite, " + + "expect successful connection", + () -> connect(uriString, new SSLParameters( + new String[] { "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA" }))); + success &= checkProtocol(handler.getSSLSession(), "TLSv1.2"); + success &= checkCipherSuite(handler.getSSLSession(), + "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA"); + + // set TLS_RSA_WITH_AES_128_CBC_SHA cipher suite + // which has less priority in default cipher suite list + // also set TLSv11 protocol + success &= expectSuccess( + "Test #4: SSL parameters with " + + "TLS_RSA_WITH_AES_128_CBC_SHA cipher suite," + + " expect successful connection", + () -> connect(uriString, new SSLParameters( + new String[] { "TLS_RSA_WITH_AES_128_CBC_SHA" }, + new String[] { "TLSv1.1" }))); + success &= checkProtocol(handler.getSSLSession(), "TLSv1.1"); + success &= checkCipherSuite(handler.getSSLSession(), + "TLS_RSA_WITH_AES_128_CBC_SHA"); + + if (success) { + System.out.println("Test passed"); + } else { + throw new RuntimeException("At least one test case failed"); + } + } + } + + private static interface Test { + + public void run() throws Exception; + } + + private static class Handler implements Http2Handler { + + private static final byte[] BODY = "Test response".getBytes(); + + private volatile SSLSession sslSession; + + @Override + public void handle(Http2TestExchange t) throws IOException { + System.out.println("Handler: received request to " + + t.getRequestURI()); + + try (InputStream is = t.getRequestBody()) { + byte[] body = is.readAllBytes(); + System.out.println("Handler: read " + body.length + + " bytes of body: "); + System.out.println(new String(body)); + } + + try (OutputStream os = t.getResponseBody()) { + t.sendResponseHeaders(200, BODY.length); + os.write(BODY); + } + + sslSession = t.getSSLSession(); + } + + SSLSession getSSLSession() { + return sslSession; + } + } + + private static void connect(String uriString, SSLParameters sslParameters) + throws URISyntaxException, IOException, InterruptedException { + + String body = HttpClient.create() + .sslParameters(sslParameters) + .version(HttpClient.Version.HTTP_2) + .build() + .request(new URI(uriString)) + .body(HttpRequest.fromString("body")) + .GET() + .response() + .body(HttpResponse.asString()); + + System.out.println("Response: " + body); + } + + private static boolean checkProtocol(SSLSession session, String protocol) { + if (session == null) { + System.out.println("Check protocol: no session provided"); + return false; + } + + System.out.println("Check protocol: negotiated protocol: " + + session.getProtocol()); + System.out.println("Check protocol: expected protocol: " + + protocol); + if (!protocol.equals(session.getProtocol())) { + System.out.println("Check protocol: unexpected negotiated protocol"); + return false; + } + + return true; + } + + private static boolean checkCipherSuite(SSLSession session, String ciphersuite) { + if (session == null) { + System.out.println("Check protocol: no session provided"); + return false; + } + + System.out.println("Check protocol: negotiated ciphersuite: " + + session.getCipherSuite()); + System.out.println("Check protocol: expected ciphersuite: " + + ciphersuite); + if (!ciphersuite.equals(session.getCipherSuite())) { + System.out.println("Check protocol: unexpected negotiated ciphersuite"); + return false; + } + + return true; + } + + private static boolean expectSuccess(String message, Test test) { + System.out.println(message); + try { + test.run(); + System.out.println("Passed"); + return true; + } catch (Exception e) { + System.out.println("Failed: unexpected exception:"); + e.printStackTrace(System.out); + return false; + } + } + + private static boolean expectFailure(String message, Test test, + Class<? extends Throwable> expectedException) { + + System.out.println(message); + try { + test.run(); + System.out.println("Failed: unexpected successful connection"); + return false; + } catch (Exception e) { + System.out.println("Got an exception:"); + e.printStackTrace(System.out); + if (expectedException != null + && !expectedException.isAssignableFrom(e.getClass())) { + System.out.printf("Failed: expected %s, but got %s%n", + expectedException.getName(), + e.getClass().getName()); + return false; + } + System.out.println("Passed: expected exception"); + return true; + } + } + +} diff --git a/jdk/test/java/net/httpclient/http2/Timeout.java b/jdk/test/java/net/httpclient/http2/Timeout.java new file mode 100644 index 00000000000..5418d127a97 --- /dev/null +++ b/jdk/test/java/net/httpclient/http2/Timeout.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.net.http.HttpTimeoutException; +import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLServerSocket; +import javax.net.ssl.SSLServerSocketFactory; +import javax.net.ssl.SSLSocket; + +/* + * @test + * @bug 8156710 + * @summary Check if HttpTimeoutException is thrown if a server doesn't reply + * @run main/othervm Timeout + */ +public class Timeout { + + private static final int RANDOM_PORT = 0; + private static final int TIMEOUT = 3 * 1000; // in millis + private static final String KEYSTORE = System.getProperty("test.src") + + File.separator + "keystore.p12"; + private static final String PASSWORD = "password"; + + // indicates if server is ready to accept connections + private static volatile boolean ready = false; + + public static void main(String[] args) throws Exception { + System.setProperty("javax.net.ssl.keyStore", KEYSTORE); + System.setProperty("javax.net.ssl.keyStorePassword", PASSWORD); + System.setProperty("javax.net.ssl.trustStore", KEYSTORE); + System.setProperty("javax.net.ssl.trustStorePassword", PASSWORD); + + SSLServerSocketFactory factory = + (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); + + try (SSLServerSocket ssocket = + (SSLServerSocket) factory.createServerSocket(RANDOM_PORT)) { + + // start server + Thread server = new Thread(() -> { + while (true) { + System.out.println("server: ready"); + ready = true; + try (SSLSocket socket = (SSLSocket) ssocket.accept()) { + + // just read forever + System.out.println("server: accepted"); + while (true) { + socket.getInputStream().read(); + } + } catch (IOException e) { + // ignore exceptions on server side + System.out.println("server: exception: " + e); + } + } + }); + server.setDaemon(true); + server.start(); + + // wait for server is ready + do { + Thread.sleep(1000); + } while (!ready); + + String uri = "https://localhost:" + ssocket.getLocalPort(); + connect(uri); + } + } + + private static void connect(String server) throws Exception { + try { + HttpClient.create() + .version(HttpClient.Version.HTTP_2) + .build() + .request(new URI(server)) + .timeout(TimeUnit.MILLISECONDS, TIMEOUT) + .body(HttpRequest.fromString("body")) + .GET() + .response() + .body(HttpResponse.asString()); + + throw new RuntimeException("unexpected successful connection"); + } catch (HttpTimeoutException e) { + System.out.println("expected exception: " + e); + } + } + +} diff --git a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestServer.java b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestServer.java index 667a1d6ec55..3baefe142bb 100644 --- a/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestServer.java +++ b/jdk/test/java/net/httpclient/http2/java.httpclient/java/net/http/Http2TestServer.java @@ -42,7 +42,7 @@ import javax.net.ssl.SSLServerSocketFactory; * Http2Handler on additional threads. All threads * obtained from the supplied ExecutorService. */ -public class Http2TestServer { +public class Http2TestServer implements AutoCloseable { final ServerSocket server; boolean secure; SettingsFrame serverSettings, clientSettings; @@ -156,4 +156,9 @@ public class Http2TestServer { }); } + @Override + public void close() throws Exception { + stop(); + } + } diff --git a/jdk/test/java/net/httpclient/http2/keystore.p12 b/jdk/test/java/net/httpclient/http2/keystore.p12 new file mode 100644 index 00000000000..a635533d086 Binary files /dev/null and b/jdk/test/java/net/httpclient/http2/keystore.p12 differ diff --git a/jdk/test/java/nio/Buffer/Basic-X.java.template b/jdk/test/java/nio/Buffer/Basic-X.java.template index 5e96b454b1b..d578b1366d3 100644 --- a/jdk/test/java/nio/Buffer/Basic-X.java.template +++ b/jdk/test/java/nio/Buffer/Basic-X.java.template @@ -31,7 +31,6 @@ #warn This file is preprocessed before being compiled import java.nio.*; -import java.lang.reflect.Method; public class Basic$Type$ @@ -60,7 +59,6 @@ public class Basic$Type$ private static void relGet($Type$Buffer b) { int n = b.capacity(); - $type$ v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)(($type$)ic(i))); b.rewind(); @@ -68,7 +66,6 @@ public class Basic$Type$ private static void relGet($Type$Buffer b, int start) { int n = b.remaining(); - $type$ v; for (int i = start; i < n; i++) ck(b, (long)b.get(), (long)(($type$)ic(i))); b.rewind(); @@ -76,7 +73,6 @@ public class Basic$Type$ private static void absGet($Type$Buffer b) { int n = b.capacity(); - $type$ v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)(($type$)ic(i))); b.rewind(); @@ -86,8 +82,9 @@ public class Basic$Type$ int n = b.capacity(); $type$[] a = new $type$[n + 7]; b.get(a, 7, n); - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { ck(b, (long)a[i + 7], (long)(($type$)ic(i))); + } } private static void relPut($Type$Buffer b) { @@ -178,7 +175,7 @@ public class Basic$Type$ private static void bulkPutString($Type$Buffer b) { int n = b.capacity(); b.clear(); - StringBuffer sb = new StringBuffer(n + 7); + StringBuilder sb = new StringBuilder(n + 7); sb.append("1234567"); for (int i = 0; i < n; i++) sb.append((char)ic(i)); @@ -203,13 +200,14 @@ public class Basic$Type$ private static void checkBytes(ByteBuffer b, byte[] bs) { int n = bs.length; int p = b.position(); - byte v; if (b.order() == ByteOrder.BIG_ENDIAN) { - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { ck(b, b.get(), bs[i]); + } } else { - for (int i = n - 1; i >= 0; i--) + for (int i = n - 1; i >= 0; i--) { ck(b, b.get(), bs[i]); + } } b.position(p); } @@ -217,7 +215,7 @@ public class Basic$Type$ private static void compact(Buffer b) { try { Class<?> cl = b.getClass(); - Method m = cl.getDeclaredMethod("compact"); + java.lang.reflect.Method m = cl.getDeclaredMethod("compact"); m.setAccessible(true); m.invoke(b); } catch (Exception e) { @@ -226,12 +224,11 @@ public class Basic$Type$ } private static void checkInvalidMarkException(final Buffer b) { - tryCatch(b, InvalidMarkException.class, new Runnable() { - public void run() { + tryCatch(b, InvalidMarkException.class, () -> { b.mark(); compact(b); b.reset(); - }}); + }); } private static void testViews(int level, ByteBuffer b, boolean direct) { @@ -338,41 +335,50 @@ public class Basic$Type$ private static void testAlign(final ByteBuffer b, boolean direct) { // index out-of bounds - tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(-1, (short) 1)); + catchIllegalArgument(b, () -> b.alignmentOffset(-1, (short) 1)); // unit size values - tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, (short) 0)); + catchIllegalArgument(b, () -> b.alignmentOffset(0, (short) 0)); for (int us = 1; us < 65; us++) { int _us = us; if ((us & (us - 1)) != 0) { // unit size not a power of two - tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, _us)); + catchIllegalArgument(b, () -> b.alignmentOffset(0, _us)); } else { if (direct || us <= 8) { b.alignmentOffset(0, us); } else { // unit size > 8 with non-direct buffer - tryCatch(b, UnsupportedOperationException.class, () -> b.alignmentOffset(0, _us)); + tryCatch(b, UnsupportedOperationException.class, + () -> b.alignmentOffset(0, _us)); } } } // Probe for long misalignment at index zero for a newly created buffer - ByteBuffer empty = direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0); + ByteBuffer empty = + direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0); int longMisalignmentAtZero = empty.alignmentOffset(0, 8); if (direct) { // Freshly created direct byte buffers should be aligned at index 0 // for ref and primitive values (see Unsafe.allocateMemory) - if (longMisalignmentAtZero != 0) - fail("Direct byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero); + if (longMisalignmentAtZero != 0) { + fail("Direct byte buffer misaligned at index 0" + + " for ref and primitive values " + + longMisalignmentAtZero); + } } else { // For heap byte buffers misalignment may occur on 32-bit systems // where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0 // Note the GC will preserve alignment of the base address of the // array - if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 != longMisalignmentAtZero) - fail("Heap byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero); + if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 + != longMisalignmentAtZero) { + fail("Heap byte buffer misaligned at index 0" + + " for ref and primitive values " + + longMisalignmentAtZero); + } } // Ensure test buffer is correctly aligned at index 0 @@ -385,8 +391,10 @@ public class Basic$Type$ int am = b.alignmentOffset(i, us); int expectedAm = (longMisalignmentAtZero + i) % us; - if (am != expectedAm) - fail(String.format("b.alignmentOffset(%d, %d) == %d incorrect, expected %d", i, us, am, expectedAm)); + if (am != expectedAm) { + String f = "b.alignmentOffset(%d, %d) == %d incorrect, expected %d"; + fail(String.format(f, i, us, am, expectedAm)); + } } } @@ -395,8 +403,10 @@ public class Basic$Type$ int al = b.limit() - b.alignmentOffset(b.limit(), 8); ByteBuffer ab = b.position(ap).limit(al). slice(); - if (ab.limit() == 0) - fail("Test input buffer not sufficiently sized to cover an aligned region for all values", b); + if (ab.limit() == 0) { + fail("Test input buffer not sufficiently sized to cover" + + " an aligned region for all values", b); + } if (ab.alignmentOffset(0, 8) != 0) fail("Aligned test input buffer not correctly aligned at index 0", ab); @@ -428,8 +438,9 @@ public class Basic$Type$ l = l - l_mod; int ec = l - p; - if (as.limit() != ec) + if (as.limit() != ec) { fail("Buffer capacity incorrect, expected: " + ec, as); + } } } } @@ -441,6 +452,22 @@ public class Basic$Type$ fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { + tryCatch(b, IllegalArgumentException.class, thunk); + } + + private static void catchReadOnlyBuffer(Buffer b, Runnable thunk) { + tryCatch(b, ReadOnlyBufferException.class, thunk); + } + + private static void catchIndexOutOfBounds(Buffer b, Runnable thunk) { + tryCatch(b, IndexOutOfBoundsException.class, thunk); + } + + private static void catchIndexOutOfBounds($type$[] t, Runnable thunk) { + tryCatch(t, IndexOutOfBoundsException.class, thunk); + } + private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) { boolean caught = false; try { @@ -452,11 +479,12 @@ public class Basic$Type$ fail(x.getMessage() + " not expected"); } } - if (!caught) + if (!caught) { fail(ex.getName() + " not thrown", b); + } } - private static void tryCatch($type$ [] t, Class<?> ex, Runnable thunk) { + private static void tryCatch($type$[] t, Class<?> ex, Runnable thunk) { tryCatch($Type$Buffer.wrap(t), ex, thunk); } @@ -513,11 +541,9 @@ public class Basic$Type$ // 7190219 b.clear(); int pos = b.position(); - tryCatch(b, BufferOverflowException.class, new Runnable() { - public void run() { - b.put(String.valueOf(new char[b.capacity() + 1]), 0, - b.capacity() + 1); - }}); + tryCatch(b, BufferOverflowException.class, () -> + b.put(String.valueOf(new char[b.capacity() + 1]), 0, b.capacity() + 1) + ); ck(b, b.position(), pos); relGet(b); @@ -537,38 +563,14 @@ public class Basic$Type$ b.limit(b.capacity() / 2); b.position(b.limit()); - tryCatch(b, BufferUnderflowException.class, new Runnable() { - public void run() { - b.get(); - }}); - - tryCatch(b, BufferOverflowException.class, new Runnable() { - public void run() { - b.put(($type$)42); - }}); - - // The index must be non-negative and lesss than the buffer's limit. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(b.limit()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(-1); - }}); - - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.put(b.limit(), ($type$)42); - }}); - - tryCatch(b, InvalidMarkException.class, new Runnable() { - public void run() { - b.position(0); - b.mark(); - b.compact(); - b.reset(); - }}); + tryCatch(b, BufferUnderflowException.class, () -> b.get()); + tryCatch(b, BufferOverflowException.class, () -> b.put(($type$)42)); + // The index must be non-negative and less than the buffer's limit. + catchIndexOutOfBounds(b, () -> b.get(b.limit())); + catchIndexOutOfBounds(b, () -> b.get(-1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), ($type$)42)); + tryCatch(b, InvalidMarkException.class, + () -> b.position(0).mark().compact().reset()); try { b.position(b.limit() + 1); @@ -635,7 +637,6 @@ public class Basic$Type$ b.put(0.5121609353879392); // Changes value if incorrectly swapped #end[double] - $type$ v; b.flip(); ck(b, b.get(), 0); ck(b, b.get(), ($type$)-1); @@ -644,23 +645,27 @@ public class Basic$Type$ ck(b, b.get(), $Fulltype$.MIN_VALUE); #if[float] + $type$ v; ck(b, b.get(), -Float.MAX_VALUE); ck(b, b.get(), -Float.MIN_VALUE); ck(b, b.get(), Float.NEGATIVE_INFINITY); ck(b, b.get(), Float.POSITIVE_INFINITY); if (Float.floatToRawIntBits(v = b.get()) != - Float.floatToRawIntBits(Float.NaN)) + Float.floatToRawIntBits(Float.NaN)) { fail(b, (long)Float.NaN, (long)v); + } ck(b, b.get(), 0.91697687f); #end[float] #if[double] + $type$ v; ck(b, b.get(), -Double.MAX_VALUE); ck(b, b.get(), -Double.MIN_VALUE); ck(b, b.get(), Double.NEGATIVE_INFINITY); ck(b, b.get(), Double.POSITIVE_INFINITY); if (Double.doubleToRawLongBits(v = b.get()) - != Double.doubleToRawLongBits(Double.NaN)) + != Double.doubleToRawLongBits(Double.NaN)) { fail(b, (long)Double.NaN, (long)v); + } ck(b, b.get(), 0.5121609353879392); #end[double] @@ -683,14 +688,15 @@ public class Basic$Type$ #if[float] || Float.compare(x, y) != 0 #end[float] - ) + ) { out.println("[" + i + "] " + x + " != " + y); + } } fail("Identical buffers not equal", b, b2); } - if (b.compareTo(b2) != 0) + if (b.compareTo(b2) != 0) { fail("Comparison to identical buffer != 0", b, b2); - + } b.limit(b.limit() + 1); b.position(b.limit() - 1); b.put(($type$)99); @@ -714,7 +720,7 @@ public class Basic$Type$ if (xb.compareTo(xb) != 0) { fail("compareTo not reflexive", xb, xb, x, x); } - if (! xb.equals(xb)) { + if (!xb.equals(xb)) { fail("equals not reflexive", xb, xb, x, x); } for ($type$ y : VALUES) { @@ -765,9 +771,10 @@ public class Basic$Type$ if (!sb.equals(sb2)) fail("Sliced slices do not match", sb, sb2); - if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) + if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) { fail("Array offsets do not match: " + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); + } #if[byte] @@ -808,129 +815,49 @@ public class Basic$Type$ fail("Buffer not equal to read-only view", b, rb); show(level + 1, rb); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - relPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - absPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutArray(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutBuffer(rb); - }}); + catchReadOnlyBuffer(b, () -> relPut(rb)); + catchReadOnlyBuffer(b, () -> absPut(rb)); + catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); // put($Type$Buffer) should not change source position final $Type$Buffer src = $Type$Buffer.allocate(1); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.put(src); - }}); + catchReadOnlyBuffer(b, () -> rb.put(src)); ck(src, src.position(), 0); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.compact(); - }}); + catchReadOnlyBuffer(b, () -> rb.compact()); #if[byte] - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putChar((char)1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putChar(0, (char)1); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putShort((short)1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putShort(0, (short)1); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putInt(1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putInt(0, 1); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putLong((long)1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putLong(0, (long)1); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putFloat((float)1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putFloat(0, (float)1); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putDouble((double)1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putDouble(0, (double)1); - }}); + catchReadOnlyBuffer(b, () -> rb.putChar((char)1)); + catchReadOnlyBuffer(b, () -> rb.putChar(0, (char)1)); + catchReadOnlyBuffer(b, () -> rb.putShort((short)1)); + catchReadOnlyBuffer(b, () -> rb.putShort(0, (short)1)); + catchReadOnlyBuffer(b, () -> rb.putInt(1)); + catchReadOnlyBuffer(b, () -> rb.putInt(0, 1)); + catchReadOnlyBuffer(b, () -> rb.putLong((long)1)); + catchReadOnlyBuffer(b, () -> rb.putLong(0, (long)1)); + catchReadOnlyBuffer(b, () -> rb.putFloat((float)1)); + catchReadOnlyBuffer(b, () -> rb.putFloat(0, (float)1)); + catchReadOnlyBuffer(b, () -> rb.putDouble((double)1)); + catchReadOnlyBuffer(b, () -> rb.putDouble(0, (double)1)); #end[byte] #if[char] // 7199551 - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - String s = new String(new char[rb.remaining() + 1]); - rb.put(s); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - String s = new String(new char[rb.remaining() + 1]); - rb.append(s); - }}); + catchReadOnlyBuffer(b, () -> rb.put(new String(new char[rb.remaining() + 1]))); + catchReadOnlyBuffer(b, () -> rb.append(new String(new char[rb.remaining() + 1]))); #end[char] if (rb.getClass().getName().startsWith("java.nio.Heap")) { - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.array(); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.arrayOffset(); - }}); - - if (rb.hasArray()) - fail("Read-only heap buffer's backing array is accessible", - rb); - + catchReadOnlyBuffer(b, () -> rb.array()); + catchReadOnlyBuffer(b, () -> rb.arrayOffset()); + if (rb.hasArray()) { + fail("Read-only heap buffer's backing array is accessible", rb); + } } // Bulk puts from read-only buffers @@ -969,10 +896,7 @@ public class Basic$Type$ ck(b, b.toString().equals(s.substring(start, end))); ck(b, b.toString().equals("defghi")); ck(b, b.isReadOnly()); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - b.put('x'); - }}); + catchReadOnlyBuffer(b, () -> b.put('x')); ck(b, start, b.position()); ck(b, end, b.limit()); ck(b, s.length(), b.capacity()); @@ -981,63 +905,25 @@ public class Basic$Type$ // The index, relative to the position, must be non-negative and // smaller than remaining(). - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.charAt(-1); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.charAt(b.remaining()); - }}); - + catchIndexOutOfBounds(b, () -> b.charAt(-1)); + catchIndexOutOfBounds(b, () -> b.charAt(b.remaining())); // The index must be non-negative and less than the buffer's limit. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(b.limit()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(-1); - }}); - + catchIndexOutOfBounds(b, () -> b.get(b.limit())); + catchIndexOutOfBounds(b, () -> b.get(-1)); // The start must be non-negative and no larger than remaining(). - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.subSequence(-1, b.remaining()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.subSequence(b.remaining() + 1, b.remaining()); - }}); + catchIndexOutOfBounds(b, () -> b.subSequence(-1, b.remaining())); + catchIndexOutOfBounds(b, () -> b.subSequence(b.remaining() + 1, b.remaining())); // The end must be no smaller than start and no larger than // remaining(). - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.subSequence(2, 1); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.subSequence(0, b.remaining() + 1); - }}); + catchIndexOutOfBounds(b, () -> b.subSequence(2, 1)); + catchIndexOutOfBounds(b, () -> b.subSequence(0, b.remaining() + 1)); // The offset must be non-negative and no larger than <array.length>. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - $Type$Buffer.wrap(s, -1, s.length()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - $Type$Buffer.wrap(s, s.length() + 1, s.length()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - $Type$Buffer.wrap(s, 1, 0); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - $Type$Buffer.wrap(s, 0, s.length() + 1); - }}); + catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, -1, s.length())); + catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, s.length() + 1, s.length())); + catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, 1, 0)); + catchIndexOutOfBounds(b, () -> $Type$Buffer.wrap(s, 0, s.length() + 1)); } #end[char] @@ -1052,40 +938,21 @@ public class Basic$Type$ ck(b, b.limit(), offset + length); // The offset must be non-negative and no larger than <array.length>. - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - $Type$Buffer.wrap(ba, -1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - $Type$Buffer.wrap(ba, ba.length + 1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - $Type$Buffer.wrap(ba, 0, -1); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - $Type$Buffer.wrap(ba, 0, ba.length + 1); - }}); + catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, -1, ba.length)); + catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, ba.length + 1, ba.length)); + catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, 0, -1)); + catchIndexOutOfBounds(ba, () -> $Type$Buffer.wrap(ba, 0, ba.length + 1)); // A NullPointerException will be thrown if the array is null. - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - $Type$Buffer.wrap(($type$ []) null, 0, 5); - }}); - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - $Type$Buffer.wrap(($type$ []) null); - }}); + tryCatch(ba, NullPointerException.class, + () -> $Type$Buffer.wrap(($type$ []) null, 0, 5)); + tryCatch(ba, NullPointerException.class, + () -> $Type$Buffer.wrap(($type$ []) null)); } private static void testAllocate() { // An IllegalArgumentException will be thrown for negative capacities. - tryCatch((Buffer) null, IllegalArgumentException.class, new Runnable() { - public void run() { - $Type$Buffer.allocate(-1); - }}); + catchIllegalArgument((Buffer) null, () -> $Type$Buffer.allocate(-1)); try { $Type$Buffer.allocate(-1); } catch (IllegalArgumentException e) { @@ -1095,10 +962,7 @@ public class Basic$Type$ } } #if[byte] - tryCatch((Buffer) null, IllegalArgumentException.class, new Runnable() { - public void run() { - $Type$Buffer.allocateDirect(-1); - }}); + catchIllegalArgument((Buffer) null, () -> $Type$Buffer.allocateDirect(-1)); try { $Type$Buffer.allocateDirect(-1); } catch (IllegalArgumentException e) { diff --git a/jdk/test/java/nio/Buffer/BasicByte.java b/jdk/test/java/nio/Buffer/BasicByte.java index 2d165449fa6..039dde39eb0 100644 --- a/jdk/test/java/nio/Buffer/BasicByte.java +++ b/jdk/test/java/nio/Buffer/BasicByte.java @@ -31,7 +31,6 @@ // -- This file was mechanically generated: Do not edit! -- // import java.nio.*; -import java.lang.reflect.Method; public class BasicByte @@ -60,7 +59,6 @@ public class BasicByte private static void relGet(ByteBuffer b) { int n = b.capacity(); - byte v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((byte)ic(i))); b.rewind(); @@ -68,7 +66,6 @@ public class BasicByte private static void relGet(ByteBuffer b, int start) { int n = b.remaining(); - byte v; for (int i = start; i < n; i++) ck(b, (long)b.get(), (long)((byte)ic(i))); b.rewind(); @@ -76,7 +73,6 @@ public class BasicByte private static void absGet(ByteBuffer b) { int n = b.capacity(); - byte v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((byte)ic(i))); b.rewind(); @@ -86,8 +82,9 @@ public class BasicByte int n = b.capacity(); byte[] a = new byte[n + 7]; b.get(a, 7, n); - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { ck(b, (long)a[i + 7], (long)((byte)ic(i))); + } } private static void relPut(ByteBuffer b) { @@ -203,13 +200,14 @@ public class BasicByte private static void checkBytes(ByteBuffer b, byte[] bs) { int n = bs.length; int p = b.position(); - byte v; if (b.order() == ByteOrder.BIG_ENDIAN) { - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { ck(b, b.get(), bs[i]); + } } else { - for (int i = n - 1; i >= 0; i--) + for (int i = n - 1; i >= 0; i--) { ck(b, b.get(), bs[i]); + } } b.position(p); } @@ -217,7 +215,7 @@ public class BasicByte private static void compact(Buffer b) { try { Class<?> cl = b.getClass(); - Method m = cl.getDeclaredMethod("compact"); + java.lang.reflect.Method m = cl.getDeclaredMethod("compact"); m.setAccessible(true); m.invoke(b); } catch (Exception e) { @@ -226,12 +224,11 @@ public class BasicByte } private static void checkInvalidMarkException(final Buffer b) { - tryCatch(b, InvalidMarkException.class, new Runnable() { - public void run() { + tryCatch(b, InvalidMarkException.class, () -> { b.mark(); compact(b); b.reset(); - }}); + }); } private static void testViews(int level, ByteBuffer b, boolean direct) { @@ -338,41 +335,50 @@ public class BasicByte private static void testAlign(final ByteBuffer b, boolean direct) { // index out-of bounds - tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(-1, (short) 1)); + catchIllegalArgument(b, () -> b.alignmentOffset(-1, (short) 1)); // unit size values - tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, (short) 0)); + catchIllegalArgument(b, () -> b.alignmentOffset(0, (short) 0)); for (int us = 1; us < 65; us++) { int _us = us; if ((us & (us - 1)) != 0) { // unit size not a power of two - tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, _us)); + catchIllegalArgument(b, () -> b.alignmentOffset(0, _us)); } else { if (direct || us <= 8) { b.alignmentOffset(0, us); } else { // unit size > 8 with non-direct buffer - tryCatch(b, UnsupportedOperationException.class, () -> b.alignmentOffset(0, _us)); + tryCatch(b, UnsupportedOperationException.class, + () -> b.alignmentOffset(0, _us)); } } } // Probe for long misalignment at index zero for a newly created buffer - ByteBuffer empty = direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0); + ByteBuffer empty = + direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0); int longMisalignmentAtZero = empty.alignmentOffset(0, 8); if (direct) { // Freshly created direct byte buffers should be aligned at index 0 // for ref and primitive values (see Unsafe.allocateMemory) - if (longMisalignmentAtZero != 0) - fail("Direct byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero); + if (longMisalignmentAtZero != 0) { + fail("Direct byte buffer misaligned at index 0" + + " for ref and primitive values " + + longMisalignmentAtZero); + } } else { // For heap byte buffers misalignment may occur on 32-bit systems // where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0 // Note the GC will preserve alignment of the base address of the // array - if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 != longMisalignmentAtZero) - fail("Heap byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero); + if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 + != longMisalignmentAtZero) { + fail("Heap byte buffer misaligned at index 0" + + " for ref and primitive values " + + longMisalignmentAtZero); + } } // Ensure test buffer is correctly aligned at index 0 @@ -385,8 +391,10 @@ public class BasicByte int am = b.alignmentOffset(i, us); int expectedAm = (longMisalignmentAtZero + i) % us; - if (am != expectedAm) - fail(String.format("b.alignmentOffset(%d, %d) == %d incorrect, expected %d", i, us, am, expectedAm)); + if (am != expectedAm) { + String f = "b.alignmentOffset(%d, %d) == %d incorrect, expected %d"; + fail(String.format(f, i, us, am, expectedAm)); + } } } @@ -395,8 +403,10 @@ public class BasicByte int al = b.limit() - b.alignmentOffset(b.limit(), 8); ByteBuffer ab = b.position(ap).limit(al). slice(); - if (ab.limit() == 0) - fail("Test input buffer not sufficiently sized to cover an aligned region for all values", b); + if (ab.limit() == 0) { + fail("Test input buffer not sufficiently sized to cover" + + " an aligned region for all values", b); + } if (ab.alignmentOffset(0, 8) != 0) fail("Aligned test input buffer not correctly aligned at index 0", ab); @@ -428,8 +438,9 @@ public class BasicByte l = l - l_mod; int ec = l - p; - if (as.limit() != ec) + if (as.limit() != ec) { fail("Buffer capacity incorrect, expected: " + ec, as); + } } } } @@ -441,6 +452,22 @@ public class BasicByte fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { + tryCatch(b, IllegalArgumentException.class, thunk); + } + + private static void catchReadOnlyBuffer(Buffer b, Runnable thunk) { + tryCatch(b, ReadOnlyBufferException.class, thunk); + } + + private static void catchIndexOutOfBounds(Buffer b, Runnable thunk) { + tryCatch(b, IndexOutOfBoundsException.class, thunk); + } + + private static void catchIndexOutOfBounds(byte[] t, Runnable thunk) { + tryCatch(t, IndexOutOfBoundsException.class, thunk); + } + private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) { boolean caught = false; try { @@ -452,11 +479,12 @@ public class BasicByte fail(x.getMessage() + " not expected"); } } - if (!caught) + if (!caught) { fail(ex.getName() + " not thrown", b); + } } - private static void tryCatch(byte [] t, Class<?> ex, Runnable thunk) { + private static void tryCatch(byte[] t, Class<?> ex, Runnable thunk) { tryCatch(ByteBuffer.wrap(t), ex, thunk); } @@ -518,8 +546,6 @@ public class BasicByte - - @@ -537,38 +563,14 @@ public class BasicByte b.limit(b.capacity() / 2); b.position(b.limit()); - tryCatch(b, BufferUnderflowException.class, new Runnable() { - public void run() { - b.get(); - }}); - - tryCatch(b, BufferOverflowException.class, new Runnable() { - public void run() { - b.put((byte)42); - }}); - - // The index must be non-negative and lesss than the buffer's limit. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(b.limit()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(-1); - }}); - - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.put(b.limit(), (byte)42); - }}); - - tryCatch(b, InvalidMarkException.class, new Runnable() { - public void run() { - b.position(0); - b.mark(); - b.compact(); - b.reset(); - }}); + tryCatch(b, BufferUnderflowException.class, () -> b.get()); + tryCatch(b, BufferOverflowException.class, () -> b.put((byte)42)); + // The index must be non-negative and less than the buffer's limit. + catchIndexOutOfBounds(b, () -> b.get(b.limit())); + catchIndexOutOfBounds(b, () -> b.get(-1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), (byte)42)); + tryCatch(b, InvalidMarkException.class, + () -> b.position(0).mark().compact().reset()); try { b.position(b.limit() + 1); @@ -635,7 +637,6 @@ public class BasicByte - byte v; b.flip(); ck(b, b.get(), 0); ck(b, b.get(), (byte)-1); @@ -660,6 +661,10 @@ public class BasicByte + + + + @@ -683,14 +688,15 @@ public class BasicByte - ) + ) { out.println("[" + i + "] " + x + " != " + y); + } } fail("Identical buffers not equal", b, b2); } - if (b.compareTo(b2) != 0) + if (b.compareTo(b2) != 0) { fail("Comparison to identical buffer != 0", b, b2); - + } b.limit(b.limit() + 1); b.position(b.limit() - 1); b.put((byte)99); @@ -714,7 +720,7 @@ public class BasicByte if (xb.compareTo(xb) != 0) { fail("compareTo not reflexive", xb, xb, x, x); } - if (! xb.equals(xb)) { + if (!xb.equals(xb)) { fail("equals not reflexive", xb, xb, x, x); } for (byte y : VALUES) { @@ -765,9 +771,10 @@ public class BasicByte if (!sb.equals(sb2)) fail("Sliced slices do not match", sb, sb2); - if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) + if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) { fail("Array offsets do not match: " + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); + } @@ -808,102 +815,32 @@ public class BasicByte fail("Buffer not equal to read-only view", b, rb); show(level + 1, rb); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - relPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - absPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutArray(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutBuffer(rb); - }}); + catchReadOnlyBuffer(b, () -> relPut(rb)); + catchReadOnlyBuffer(b, () -> absPut(rb)); + catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); // put(ByteBuffer) should not change source position final ByteBuffer src = ByteBuffer.allocate(1); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.put(src); - }}); + catchReadOnlyBuffer(b, () -> rb.put(src)); ck(src, src.position(), 0); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.compact(); - }}); - - - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putChar((char)1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putChar(0, (char)1); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putShort((short)1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putShort(0, (short)1); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putInt(1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putInt(0, 1); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putLong((long)1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putLong(0, (long)1); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putFloat((float)1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putFloat(0, (float)1); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putDouble((double)1); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.putDouble(0, (double)1); - }}); - - - - - + catchReadOnlyBuffer(b, () -> rb.compact()); + catchReadOnlyBuffer(b, () -> rb.putChar((char)1)); + catchReadOnlyBuffer(b, () -> rb.putChar(0, (char)1)); + catchReadOnlyBuffer(b, () -> rb.putShort((short)1)); + catchReadOnlyBuffer(b, () -> rb.putShort(0, (short)1)); + catchReadOnlyBuffer(b, () -> rb.putInt(1)); + catchReadOnlyBuffer(b, () -> rb.putInt(0, 1)); + catchReadOnlyBuffer(b, () -> rb.putLong((long)1)); + catchReadOnlyBuffer(b, () -> rb.putLong(0, (long)1)); + catchReadOnlyBuffer(b, () -> rb.putFloat((float)1)); + catchReadOnlyBuffer(b, () -> rb.putFloat(0, (float)1)); + catchReadOnlyBuffer(b, () -> rb.putDouble((double)1)); + catchReadOnlyBuffer(b, () -> rb.putDouble(0, (double)1)); @@ -916,21 +853,11 @@ public class BasicByte if (rb.getClass().getName().startsWith("java.nio.Heap")) { - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.array(); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.arrayOffset(); - }}); - - if (rb.hasArray()) - fail("Read-only heap buffer's backing array is accessible", - rb); - + catchReadOnlyBuffer(b, () -> rb.array()); + catchReadOnlyBuffer(b, () -> rb.arrayOffset()); + if (rb.hasArray()) { + fail("Read-only heap buffer's backing array is accessible", rb); + } } // Bulk puts from read-only buffers @@ -980,47 +907,6 @@ public class BasicByte - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1052,40 +938,21 @@ public class BasicByte ck(b, b.limit(), offset + length); // The offset must be non-negative and no larger than <array.length>. - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - ByteBuffer.wrap(ba, -1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - ByteBuffer.wrap(ba, ba.length + 1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - ByteBuffer.wrap(ba, 0, -1); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - ByteBuffer.wrap(ba, 0, ba.length + 1); - }}); + catchIndexOutOfBounds(ba, () -> ByteBuffer.wrap(ba, -1, ba.length)); + catchIndexOutOfBounds(ba, () -> ByteBuffer.wrap(ba, ba.length + 1, ba.length)); + catchIndexOutOfBounds(ba, () -> ByteBuffer.wrap(ba, 0, -1)); + catchIndexOutOfBounds(ba, () -> ByteBuffer.wrap(ba, 0, ba.length + 1)); // A NullPointerException will be thrown if the array is null. - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - ByteBuffer.wrap((byte []) null, 0, 5); - }}); - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - ByteBuffer.wrap((byte []) null); - }}); + tryCatch(ba, NullPointerException.class, + () -> ByteBuffer.wrap((byte []) null, 0, 5)); + tryCatch(ba, NullPointerException.class, + () -> ByteBuffer.wrap((byte []) null)); } private static void testAllocate() { // An IllegalArgumentException will be thrown for negative capacities. - tryCatch((Buffer) null, IllegalArgumentException.class, new Runnable() { - public void run() { - ByteBuffer.allocate(-1); - }}); + catchIllegalArgument((Buffer) null, () -> ByteBuffer.allocate(-1)); try { ByteBuffer.allocate(-1); } catch (IllegalArgumentException e) { @@ -1095,10 +962,7 @@ public class BasicByte } } - tryCatch((Buffer) null, IllegalArgumentException.class, new Runnable() { - public void run() { - ByteBuffer.allocateDirect(-1); - }}); + catchIllegalArgument((Buffer) null, () -> ByteBuffer.allocateDirect(-1)); try { ByteBuffer.allocateDirect(-1); } catch (IllegalArgumentException e) { diff --git a/jdk/test/java/nio/Buffer/BasicChar.java b/jdk/test/java/nio/Buffer/BasicChar.java index b8dc950b68c..a059aa9c3bb 100644 --- a/jdk/test/java/nio/Buffer/BasicChar.java +++ b/jdk/test/java/nio/Buffer/BasicChar.java @@ -31,7 +31,6 @@ // -- This file was mechanically generated: Do not edit! -- // import java.nio.*; -import java.lang.reflect.Method; public class BasicChar @@ -60,7 +59,6 @@ public class BasicChar private static void relGet(CharBuffer b) { int n = b.capacity(); - char v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((char)ic(i))); b.rewind(); @@ -68,7 +66,6 @@ public class BasicChar private static void relGet(CharBuffer b, int start) { int n = b.remaining(); - char v; for (int i = start; i < n; i++) ck(b, (long)b.get(), (long)((char)ic(i))); b.rewind(); @@ -76,7 +73,6 @@ public class BasicChar private static void absGet(CharBuffer b) { int n = b.capacity(); - char v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((char)ic(i))); b.rewind(); @@ -86,8 +82,9 @@ public class BasicChar int n = b.capacity(); char[] a = new char[n + 7]; b.get(a, 7, n); - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { ck(b, (long)a[i + 7], (long)((char)ic(i))); + } } private static void relPut(CharBuffer b) { @@ -178,7 +175,7 @@ public class BasicChar private static void bulkPutString(CharBuffer b) { int n = b.capacity(); b.clear(); - StringBuffer sb = new StringBuffer(n + 7); + StringBuilder sb = new StringBuilder(n + 7); sb.append("1234567"); for (int i = 0; i < n; i++) sb.append((char)ic(i)); @@ -420,6 +417,20 @@ public class BasicChar + + + + + + + + + + + + + + @@ -441,6 +452,22 @@ public class BasicChar fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { + tryCatch(b, IllegalArgumentException.class, thunk); + } + + private static void catchReadOnlyBuffer(Buffer b, Runnable thunk) { + tryCatch(b, ReadOnlyBufferException.class, thunk); + } + + private static void catchIndexOutOfBounds(Buffer b, Runnable thunk) { + tryCatch(b, IndexOutOfBoundsException.class, thunk); + } + + private static void catchIndexOutOfBounds(char[] t, Runnable thunk) { + tryCatch(t, IndexOutOfBoundsException.class, thunk); + } + private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) { boolean caught = false; try { @@ -452,11 +479,12 @@ public class BasicChar fail(x.getMessage() + " not expected"); } } - if (!caught) + if (!caught) { fail(ex.getName() + " not thrown", b); + } } - private static void tryCatch(char [] t, Class<?> ex, Runnable thunk) { + private static void tryCatch(char[] t, Class<?> ex, Runnable thunk) { tryCatch(CharBuffer.wrap(t), ex, thunk); } @@ -513,11 +541,9 @@ public class BasicChar // 7190219 b.clear(); int pos = b.position(); - tryCatch(b, BufferOverflowException.class, new Runnable() { - public void run() { - b.put(String.valueOf(new char[b.capacity() + 1]), 0, - b.capacity() + 1); - }}); + tryCatch(b, BufferOverflowException.class, () -> + b.put(String.valueOf(new char[b.capacity() + 1]), 0, b.capacity() + 1) + ); ck(b, b.position(), pos); relGet(b); @@ -537,38 +563,14 @@ public class BasicChar b.limit(b.capacity() / 2); b.position(b.limit()); - tryCatch(b, BufferUnderflowException.class, new Runnable() { - public void run() { - b.get(); - }}); - - tryCatch(b, BufferOverflowException.class, new Runnable() { - public void run() { - b.put((char)42); - }}); - - // The index must be non-negative and lesss than the buffer's limit. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(b.limit()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(-1); - }}); - - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.put(b.limit(), (char)42); - }}); - - tryCatch(b, InvalidMarkException.class, new Runnable() { - public void run() { - b.position(0); - b.mark(); - b.compact(); - b.reset(); - }}); + tryCatch(b, BufferUnderflowException.class, () -> b.get()); + tryCatch(b, BufferOverflowException.class, () -> b.put((char)42)); + // The index must be non-negative and less than the buffer's limit. + catchIndexOutOfBounds(b, () -> b.get(b.limit())); + catchIndexOutOfBounds(b, () -> b.get(-1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), (char)42)); + tryCatch(b, InvalidMarkException.class, + () -> b.position(0).mark().compact().reset()); try { b.position(b.limit() + 1); @@ -635,7 +637,6 @@ public class BasicChar - char v; b.flip(); ck(b, b.get(), 0); ck(b, b.get(), (char)-1); @@ -660,6 +661,10 @@ public class BasicChar + + + + @@ -683,14 +688,15 @@ public class BasicChar - ) + ) { out.println("[" + i + "] " + x + " != " + y); + } } fail("Identical buffers not equal", b, b2); } - if (b.compareTo(b2) != 0) + if (b.compareTo(b2) != 0) { fail("Comparison to identical buffer != 0", b, b2); - + } b.limit(b.limit() + 1); b.position(b.limit() - 1); b.put((char)99); @@ -714,7 +720,7 @@ public class BasicChar if (xb.compareTo(xb) != 0) { fail("compareTo not reflexive", xb, xb, x, x); } - if (! xb.equals(xb)) { + if (!xb.equals(xb)) { fail("equals not reflexive", xb, xb, x, x); } for (char y : VALUES) { @@ -765,9 +771,10 @@ public class BasicChar if (!sb.equals(sb2)) fail("Sliced slices do not match", sb, sb2); - if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) + if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) { fail("Array offsets do not match: " + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); + } @@ -808,79 +815,17 @@ public class BasicChar fail("Buffer not equal to read-only view", b, rb); show(level + 1, rb); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - relPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - absPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutArray(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutBuffer(rb); - }}); + catchReadOnlyBuffer(b, () -> relPut(rb)); + catchReadOnlyBuffer(b, () -> absPut(rb)); + catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); // put(CharBuffer) should not change source position final CharBuffer src = CharBuffer.allocate(1); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.put(src); - }}); + catchReadOnlyBuffer(b, () -> rb.put(src)); ck(src, src.position(), 0); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.compact(); - }}); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + catchReadOnlyBuffer(b, () -> rb.compact()); @@ -902,35 +847,17 @@ public class BasicChar // 7199551 - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - String s = new String(new char[rb.remaining() + 1]); - rb.put(s); - }}); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - String s = new String(new char[rb.remaining() + 1]); - rb.append(s); - }}); + catchReadOnlyBuffer(b, () -> rb.put(new String(new char[rb.remaining() + 1]))); + catchReadOnlyBuffer(b, () -> rb.append(new String(new char[rb.remaining() + 1]))); if (rb.getClass().getName().startsWith("java.nio.Heap")) { - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.array(); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.arrayOffset(); - }}); - - if (rb.hasArray()) - fail("Read-only heap buffer's backing array is accessible", - rb); - + catchReadOnlyBuffer(b, () -> rb.array()); + catchReadOnlyBuffer(b, () -> rb.arrayOffset()); + if (rb.hasArray()) { + fail("Read-only heap buffer's backing array is accessible", rb); + } } // Bulk puts from read-only buffers @@ -969,10 +896,7 @@ public class BasicChar ck(b, b.toString().equals(s.substring(start, end))); ck(b, b.toString().equals("defghi")); ck(b, b.isReadOnly()); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - b.put('x'); - }}); + catchReadOnlyBuffer(b, () -> b.put('x')); ck(b, start, b.position()); ck(b, end, b.limit()); ck(b, s.length(), b.capacity()); @@ -981,63 +905,25 @@ public class BasicChar // The index, relative to the position, must be non-negative and // smaller than remaining(). - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.charAt(-1); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.charAt(b.remaining()); - }}); - + catchIndexOutOfBounds(b, () -> b.charAt(-1)); + catchIndexOutOfBounds(b, () -> b.charAt(b.remaining())); // The index must be non-negative and less than the buffer's limit. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(b.limit()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(-1); - }}); - + catchIndexOutOfBounds(b, () -> b.get(b.limit())); + catchIndexOutOfBounds(b, () -> b.get(-1)); // The start must be non-negative and no larger than remaining(). - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.subSequence(-1, b.remaining()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.subSequence(b.remaining() + 1, b.remaining()); - }}); + catchIndexOutOfBounds(b, () -> b.subSequence(-1, b.remaining())); + catchIndexOutOfBounds(b, () -> b.subSequence(b.remaining() + 1, b.remaining())); // The end must be no smaller than start and no larger than // remaining(). - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.subSequence(2, 1); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.subSequence(0, b.remaining() + 1); - }}); + catchIndexOutOfBounds(b, () -> b.subSequence(2, 1)); + catchIndexOutOfBounds(b, () -> b.subSequence(0, b.remaining() + 1)); // The offset must be non-negative and no larger than <array.length>. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - CharBuffer.wrap(s, -1, s.length()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - CharBuffer.wrap(s, s.length() + 1, s.length()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - CharBuffer.wrap(s, 1, 0); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - CharBuffer.wrap(s, 0, s.length() + 1); - }}); + catchIndexOutOfBounds(b, () -> CharBuffer.wrap(s, -1, s.length())); + catchIndexOutOfBounds(b, () -> CharBuffer.wrap(s, s.length() + 1, s.length())); + catchIndexOutOfBounds(b, () -> CharBuffer.wrap(s, 1, 0)); + catchIndexOutOfBounds(b, () -> CharBuffer.wrap(s, 0, s.length() + 1)); } @@ -1052,40 +938,21 @@ public class BasicChar ck(b, b.limit(), offset + length); // The offset must be non-negative and no larger than <array.length>. - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - CharBuffer.wrap(ba, -1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - CharBuffer.wrap(ba, ba.length + 1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - CharBuffer.wrap(ba, 0, -1); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - CharBuffer.wrap(ba, 0, ba.length + 1); - }}); + catchIndexOutOfBounds(ba, () -> CharBuffer.wrap(ba, -1, ba.length)); + catchIndexOutOfBounds(ba, () -> CharBuffer.wrap(ba, ba.length + 1, ba.length)); + catchIndexOutOfBounds(ba, () -> CharBuffer.wrap(ba, 0, -1)); + catchIndexOutOfBounds(ba, () -> CharBuffer.wrap(ba, 0, ba.length + 1)); // A NullPointerException will be thrown if the array is null. - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - CharBuffer.wrap((char []) null, 0, 5); - }}); - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - CharBuffer.wrap((char []) null); - }}); + tryCatch(ba, NullPointerException.class, + () -> CharBuffer.wrap((char []) null, 0, 5)); + tryCatch(ba, NullPointerException.class, + () -> CharBuffer.wrap((char []) null)); } private static void testAllocate() { // An IllegalArgumentException will be thrown for negative capacities. - tryCatch((Buffer) null, IllegalArgumentException.class, new Runnable() { - public void run() { - CharBuffer.allocate(-1); - }}); + catchIllegalArgument((Buffer) null, () -> CharBuffer.allocate(-1)); try { CharBuffer.allocate(-1); } catch (IllegalArgumentException e) { @@ -1105,9 +972,6 @@ public class BasicChar - - - } public static void test() { diff --git a/jdk/test/java/nio/Buffer/BasicDouble.java b/jdk/test/java/nio/Buffer/BasicDouble.java index b25fe15aa52..41dc5379057 100644 --- a/jdk/test/java/nio/Buffer/BasicDouble.java +++ b/jdk/test/java/nio/Buffer/BasicDouble.java @@ -31,7 +31,6 @@ // -- This file was mechanically generated: Do not edit! -- // import java.nio.*; -import java.lang.reflect.Method; public class BasicDouble @@ -60,7 +59,6 @@ public class BasicDouble private static void relGet(DoubleBuffer b) { int n = b.capacity(); - double v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((double)ic(i))); b.rewind(); @@ -68,7 +66,6 @@ public class BasicDouble private static void relGet(DoubleBuffer b, int start) { int n = b.remaining(); - double v; for (int i = start; i < n; i++) ck(b, (long)b.get(), (long)((double)ic(i))); b.rewind(); @@ -76,7 +73,6 @@ public class BasicDouble private static void absGet(DoubleBuffer b) { int n = b.capacity(); - double v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((double)ic(i))); b.rewind(); @@ -86,8 +82,9 @@ public class BasicDouble int n = b.capacity(); double[] a = new double[n + 7]; b.get(a, 7, n); - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { ck(b, (long)a[i + 7], (long)((double)ic(i))); + } } private static void relPut(DoubleBuffer b) { @@ -420,6 +417,20 @@ public class BasicDouble + + + + + + + + + + + + + + @@ -441,6 +452,22 @@ public class BasicDouble fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { + tryCatch(b, IllegalArgumentException.class, thunk); + } + + private static void catchReadOnlyBuffer(Buffer b, Runnable thunk) { + tryCatch(b, ReadOnlyBufferException.class, thunk); + } + + private static void catchIndexOutOfBounds(Buffer b, Runnable thunk) { + tryCatch(b, IndexOutOfBoundsException.class, thunk); + } + + private static void catchIndexOutOfBounds(double[] t, Runnable thunk) { + tryCatch(t, IndexOutOfBoundsException.class, thunk); + } + private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) { boolean caught = false; try { @@ -452,11 +479,12 @@ public class BasicDouble fail(x.getMessage() + " not expected"); } } - if (!caught) + if (!caught) { fail(ex.getName() + " not thrown", b); + } } - private static void tryCatch(double [] t, Class<?> ex, Runnable thunk) { + private static void tryCatch(double[] t, Class<?> ex, Runnable thunk) { tryCatch(DoubleBuffer.wrap(t), ex, thunk); } @@ -518,8 +546,6 @@ public class BasicDouble - - @@ -537,38 +563,14 @@ public class BasicDouble b.limit(b.capacity() / 2); b.position(b.limit()); - tryCatch(b, BufferUnderflowException.class, new Runnable() { - public void run() { - b.get(); - }}); - - tryCatch(b, BufferOverflowException.class, new Runnable() { - public void run() { - b.put((double)42); - }}); - - // The index must be non-negative and lesss than the buffer's limit. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(b.limit()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(-1); - }}); - - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.put(b.limit(), (double)42); - }}); - - tryCatch(b, InvalidMarkException.class, new Runnable() { - public void run() { - b.position(0); - b.mark(); - b.compact(); - b.reset(); - }}); + tryCatch(b, BufferUnderflowException.class, () -> b.get()); + tryCatch(b, BufferOverflowException.class, () -> b.put((double)42)); + // The index must be non-negative and less than the buffer's limit. + catchIndexOutOfBounds(b, () -> b.get(b.limit())); + catchIndexOutOfBounds(b, () -> b.get(-1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), (double)42)); + tryCatch(b, InvalidMarkException.class, + () -> b.position(0).mark().compact().reset()); try { b.position(b.limit() + 1); @@ -635,7 +637,6 @@ public class BasicDouble b.put(0.5121609353879392); // Changes value if incorrectly swapped - double v; b.flip(); ck(b, b.get(), 0); ck(b, b.get(), (double)-1); @@ -654,13 +655,17 @@ public class BasicDouble + + + double v; ck(b, b.get(), -Double.MAX_VALUE); ck(b, b.get(), -Double.MIN_VALUE); ck(b, b.get(), Double.NEGATIVE_INFINITY); ck(b, b.get(), Double.POSITIVE_INFINITY); if (Double.doubleToRawLongBits(v = b.get()) - != Double.doubleToRawLongBits(Double.NaN)) + != Double.doubleToRawLongBits(Double.NaN)) { fail(b, (long)Double.NaN, (long)v); + } ck(b, b.get(), 0.5121609353879392); @@ -683,14 +688,15 @@ public class BasicDouble - ) + ) { out.println("[" + i + "] " + x + " != " + y); + } } fail("Identical buffers not equal", b, b2); } - if (b.compareTo(b2) != 0) + if (b.compareTo(b2) != 0) { fail("Comparison to identical buffer != 0", b, b2); - + } b.limit(b.limit() + 1); b.position(b.limit() - 1); b.put((double)99); @@ -714,7 +720,7 @@ public class BasicDouble if (xb.compareTo(xb) != 0) { fail("compareTo not reflexive", xb, xb, x, x); } - if (! xb.equals(xb)) { + if (!xb.equals(xb)) { fail("equals not reflexive", xb, xb, x, x); } for (double y : VALUES) { @@ -765,9 +771,10 @@ public class BasicDouble if (!sb.equals(sb2)) fail("Sliced slices do not match", sb, sb2); - if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) + if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) { fail("Array offsets do not match: " + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); + } @@ -808,87 +815,17 @@ public class BasicDouble fail("Buffer not equal to read-only view", b, rb); show(level + 1, rb); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - relPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - absPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutArray(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutBuffer(rb); - }}); + catchReadOnlyBuffer(b, () -> relPut(rb)); + catchReadOnlyBuffer(b, () -> absPut(rb)); + catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); // put(DoubleBuffer) should not change source position final DoubleBuffer src = DoubleBuffer.allocate(1); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.put(src); - }}); + catchReadOnlyBuffer(b, () -> rb.put(src)); ck(src, src.position(), 0); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.compact(); - }}); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + catchReadOnlyBuffer(b, () -> rb.compact()); @@ -916,21 +853,11 @@ public class BasicDouble if (rb.getClass().getName().startsWith("java.nio.Heap")) { - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.array(); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.arrayOffset(); - }}); - - if (rb.hasArray()) - fail("Read-only heap buffer's backing array is accessible", - rb); - + catchReadOnlyBuffer(b, () -> rb.array()); + catchReadOnlyBuffer(b, () -> rb.arrayOffset()); + if (rb.hasArray()) { + fail("Read-only heap buffer's backing array is accessible", rb); + } } // Bulk puts from read-only buffers @@ -980,47 +907,6 @@ public class BasicDouble - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1052,40 +938,21 @@ public class BasicDouble ck(b, b.limit(), offset + length); // The offset must be non-negative and no larger than <array.length>. - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - DoubleBuffer.wrap(ba, -1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - DoubleBuffer.wrap(ba, ba.length + 1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - DoubleBuffer.wrap(ba, 0, -1); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - DoubleBuffer.wrap(ba, 0, ba.length + 1); - }}); + catchIndexOutOfBounds(ba, () -> DoubleBuffer.wrap(ba, -1, ba.length)); + catchIndexOutOfBounds(ba, () -> DoubleBuffer.wrap(ba, ba.length + 1, ba.length)); + catchIndexOutOfBounds(ba, () -> DoubleBuffer.wrap(ba, 0, -1)); + catchIndexOutOfBounds(ba, () -> DoubleBuffer.wrap(ba, 0, ba.length + 1)); // A NullPointerException will be thrown if the array is null. - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - DoubleBuffer.wrap((double []) null, 0, 5); - }}); - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - DoubleBuffer.wrap((double []) null); - }}); + tryCatch(ba, NullPointerException.class, + () -> DoubleBuffer.wrap((double []) null, 0, 5)); + tryCatch(ba, NullPointerException.class, + () -> DoubleBuffer.wrap((double []) null)); } private static void testAllocate() { // An IllegalArgumentException will be thrown for negative capacities. - tryCatch((Buffer) null, IllegalArgumentException.class, new Runnable() { - public void run() { - DoubleBuffer.allocate(-1); - }}); + catchIllegalArgument((Buffer) null, () -> DoubleBuffer.allocate(-1)); try { DoubleBuffer.allocate(-1); } catch (IllegalArgumentException e) { @@ -1105,9 +972,6 @@ public class BasicDouble - - - } public static void test() { diff --git a/jdk/test/java/nio/Buffer/BasicFloat.java b/jdk/test/java/nio/Buffer/BasicFloat.java index c4d42867b2b..8f1d950d19c 100644 --- a/jdk/test/java/nio/Buffer/BasicFloat.java +++ b/jdk/test/java/nio/Buffer/BasicFloat.java @@ -31,7 +31,6 @@ // -- This file was mechanically generated: Do not edit! -- // import java.nio.*; -import java.lang.reflect.Method; public class BasicFloat @@ -60,7 +59,6 @@ public class BasicFloat private static void relGet(FloatBuffer b) { int n = b.capacity(); - float v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((float)ic(i))); b.rewind(); @@ -68,7 +66,6 @@ public class BasicFloat private static void relGet(FloatBuffer b, int start) { int n = b.remaining(); - float v; for (int i = start; i < n; i++) ck(b, (long)b.get(), (long)((float)ic(i))); b.rewind(); @@ -76,7 +73,6 @@ public class BasicFloat private static void absGet(FloatBuffer b) { int n = b.capacity(); - float v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((float)ic(i))); b.rewind(); @@ -86,8 +82,9 @@ public class BasicFloat int n = b.capacity(); float[] a = new float[n + 7]; b.get(a, 7, n); - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { ck(b, (long)a[i + 7], (long)((float)ic(i))); + } } private static void relPut(FloatBuffer b) { @@ -420,6 +417,20 @@ public class BasicFloat + + + + + + + + + + + + + + @@ -441,6 +452,22 @@ public class BasicFloat fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { + tryCatch(b, IllegalArgumentException.class, thunk); + } + + private static void catchReadOnlyBuffer(Buffer b, Runnable thunk) { + tryCatch(b, ReadOnlyBufferException.class, thunk); + } + + private static void catchIndexOutOfBounds(Buffer b, Runnable thunk) { + tryCatch(b, IndexOutOfBoundsException.class, thunk); + } + + private static void catchIndexOutOfBounds(float[] t, Runnable thunk) { + tryCatch(t, IndexOutOfBoundsException.class, thunk); + } + private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) { boolean caught = false; try { @@ -452,11 +479,12 @@ public class BasicFloat fail(x.getMessage() + " not expected"); } } - if (!caught) + if (!caught) { fail(ex.getName() + " not thrown", b); + } } - private static void tryCatch(float [] t, Class<?> ex, Runnable thunk) { + private static void tryCatch(float[] t, Class<?> ex, Runnable thunk) { tryCatch(FloatBuffer.wrap(t), ex, thunk); } @@ -518,8 +546,6 @@ public class BasicFloat - - @@ -537,38 +563,14 @@ public class BasicFloat b.limit(b.capacity() / 2); b.position(b.limit()); - tryCatch(b, BufferUnderflowException.class, new Runnable() { - public void run() { - b.get(); - }}); - - tryCatch(b, BufferOverflowException.class, new Runnable() { - public void run() { - b.put((float)42); - }}); - - // The index must be non-negative and lesss than the buffer's limit. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(b.limit()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(-1); - }}); - - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.put(b.limit(), (float)42); - }}); - - tryCatch(b, InvalidMarkException.class, new Runnable() { - public void run() { - b.position(0); - b.mark(); - b.compact(); - b.reset(); - }}); + tryCatch(b, BufferUnderflowException.class, () -> b.get()); + tryCatch(b, BufferOverflowException.class, () -> b.put((float)42)); + // The index must be non-negative and less than the buffer's limit. + catchIndexOutOfBounds(b, () -> b.get(b.limit())); + catchIndexOutOfBounds(b, () -> b.get(-1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), (float)42)); + tryCatch(b, InvalidMarkException.class, + () -> b.position(0).mark().compact().reset()); try { b.position(b.limit() + 1); @@ -635,7 +637,6 @@ public class BasicFloat - float v; b.flip(); ck(b, b.get(), 0); ck(b, b.get(), (float)-1); @@ -644,13 +645,15 @@ public class BasicFloat ck(b, b.get(), Float.MIN_VALUE); + float v; ck(b, b.get(), -Float.MAX_VALUE); ck(b, b.get(), -Float.MIN_VALUE); ck(b, b.get(), Float.NEGATIVE_INFINITY); ck(b, b.get(), Float.POSITIVE_INFINITY); if (Float.floatToRawIntBits(v = b.get()) != - Float.floatToRawIntBits(Float.NaN)) + Float.floatToRawIntBits(Float.NaN)) { fail(b, (long)Float.NaN, (long)v); + } ck(b, b.get(), 0.91697687f); @@ -665,6 +668,8 @@ public class BasicFloat + + // Comparison b.rewind(); FloatBuffer b2 = FloatBuffer.allocate(b.capacity()); @@ -683,14 +688,15 @@ public class BasicFloat || Float.compare(x, y) != 0 - ) + ) { out.println("[" + i + "] " + x + " != " + y); + } } fail("Identical buffers not equal", b, b2); } - if (b.compareTo(b2) != 0) + if (b.compareTo(b2) != 0) { fail("Comparison to identical buffer != 0", b, b2); - + } b.limit(b.limit() + 1); b.position(b.limit() - 1); b.put((float)99); @@ -714,7 +720,7 @@ public class BasicFloat if (xb.compareTo(xb) != 0) { fail("compareTo not reflexive", xb, xb, x, x); } - if (! xb.equals(xb)) { + if (!xb.equals(xb)) { fail("equals not reflexive", xb, xb, x, x); } for (float y : VALUES) { @@ -765,9 +771,10 @@ public class BasicFloat if (!sb.equals(sb2)) fail("Sliced slices do not match", sb, sb2); - if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) + if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) { fail("Array offsets do not match: " + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); + } @@ -808,87 +815,17 @@ public class BasicFloat fail("Buffer not equal to read-only view", b, rb); show(level + 1, rb); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - relPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - absPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutArray(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutBuffer(rb); - }}); + catchReadOnlyBuffer(b, () -> relPut(rb)); + catchReadOnlyBuffer(b, () -> absPut(rb)); + catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); // put(FloatBuffer) should not change source position final FloatBuffer src = FloatBuffer.allocate(1); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.put(src); - }}); + catchReadOnlyBuffer(b, () -> rb.put(src)); ck(src, src.position(), 0); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.compact(); - }}); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + catchReadOnlyBuffer(b, () -> rb.compact()); @@ -916,21 +853,11 @@ public class BasicFloat if (rb.getClass().getName().startsWith("java.nio.Heap")) { - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.array(); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.arrayOffset(); - }}); - - if (rb.hasArray()) - fail("Read-only heap buffer's backing array is accessible", - rb); - + catchReadOnlyBuffer(b, () -> rb.array()); + catchReadOnlyBuffer(b, () -> rb.arrayOffset()); + if (rb.hasArray()) { + fail("Read-only heap buffer's backing array is accessible", rb); + } } // Bulk puts from read-only buffers @@ -980,47 +907,6 @@ public class BasicFloat - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1052,40 +938,21 @@ public class BasicFloat ck(b, b.limit(), offset + length); // The offset must be non-negative and no larger than <array.length>. - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - FloatBuffer.wrap(ba, -1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - FloatBuffer.wrap(ba, ba.length + 1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - FloatBuffer.wrap(ba, 0, -1); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - FloatBuffer.wrap(ba, 0, ba.length + 1); - }}); + catchIndexOutOfBounds(ba, () -> FloatBuffer.wrap(ba, -1, ba.length)); + catchIndexOutOfBounds(ba, () -> FloatBuffer.wrap(ba, ba.length + 1, ba.length)); + catchIndexOutOfBounds(ba, () -> FloatBuffer.wrap(ba, 0, -1)); + catchIndexOutOfBounds(ba, () -> FloatBuffer.wrap(ba, 0, ba.length + 1)); // A NullPointerException will be thrown if the array is null. - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - FloatBuffer.wrap((float []) null, 0, 5); - }}); - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - FloatBuffer.wrap((float []) null); - }}); + tryCatch(ba, NullPointerException.class, + () -> FloatBuffer.wrap((float []) null, 0, 5)); + tryCatch(ba, NullPointerException.class, + () -> FloatBuffer.wrap((float []) null)); } private static void testAllocate() { // An IllegalArgumentException will be thrown for negative capacities. - tryCatch((Buffer) null, IllegalArgumentException.class, new Runnable() { - public void run() { - FloatBuffer.allocate(-1); - }}); + catchIllegalArgument((Buffer) null, () -> FloatBuffer.allocate(-1)); try { FloatBuffer.allocate(-1); } catch (IllegalArgumentException e) { @@ -1105,9 +972,6 @@ public class BasicFloat - - - } public static void test() { diff --git a/jdk/test/java/nio/Buffer/BasicInt.java b/jdk/test/java/nio/Buffer/BasicInt.java index 46ad7578d24..71632f407ef 100644 --- a/jdk/test/java/nio/Buffer/BasicInt.java +++ b/jdk/test/java/nio/Buffer/BasicInt.java @@ -31,7 +31,6 @@ // -- This file was mechanically generated: Do not edit! -- // import java.nio.*; -import java.lang.reflect.Method; public class BasicInt @@ -60,7 +59,6 @@ public class BasicInt private static void relGet(IntBuffer b) { int n = b.capacity(); - int v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((int)ic(i))); b.rewind(); @@ -68,7 +66,6 @@ public class BasicInt private static void relGet(IntBuffer b, int start) { int n = b.remaining(); - int v; for (int i = start; i < n; i++) ck(b, (long)b.get(), (long)((int)ic(i))); b.rewind(); @@ -76,7 +73,6 @@ public class BasicInt private static void absGet(IntBuffer b) { int n = b.capacity(); - int v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((int)ic(i))); b.rewind(); @@ -86,8 +82,9 @@ public class BasicInt int n = b.capacity(); int[] a = new int[n + 7]; b.get(a, 7, n); - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { ck(b, (long)a[i + 7], (long)((int)ic(i))); + } } private static void relPut(IntBuffer b) { @@ -420,6 +417,20 @@ public class BasicInt + + + + + + + + + + + + + + @@ -441,6 +452,22 @@ public class BasicInt fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { + tryCatch(b, IllegalArgumentException.class, thunk); + } + + private static void catchReadOnlyBuffer(Buffer b, Runnable thunk) { + tryCatch(b, ReadOnlyBufferException.class, thunk); + } + + private static void catchIndexOutOfBounds(Buffer b, Runnable thunk) { + tryCatch(b, IndexOutOfBoundsException.class, thunk); + } + + private static void catchIndexOutOfBounds(int[] t, Runnable thunk) { + tryCatch(t, IndexOutOfBoundsException.class, thunk); + } + private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) { boolean caught = false; try { @@ -452,11 +479,12 @@ public class BasicInt fail(x.getMessage() + " not expected"); } } - if (!caught) + if (!caught) { fail(ex.getName() + " not thrown", b); + } } - private static void tryCatch(int [] t, Class<?> ex, Runnable thunk) { + private static void tryCatch(int[] t, Class<?> ex, Runnable thunk) { tryCatch(IntBuffer.wrap(t), ex, thunk); } @@ -518,8 +546,6 @@ public class BasicInt - - @@ -537,38 +563,14 @@ public class BasicInt b.limit(b.capacity() / 2); b.position(b.limit()); - tryCatch(b, BufferUnderflowException.class, new Runnable() { - public void run() { - b.get(); - }}); - - tryCatch(b, BufferOverflowException.class, new Runnable() { - public void run() { - b.put((int)42); - }}); - - // The index must be non-negative and lesss than the buffer's limit. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(b.limit()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(-1); - }}); - - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.put(b.limit(), (int)42); - }}); - - tryCatch(b, InvalidMarkException.class, new Runnable() { - public void run() { - b.position(0); - b.mark(); - b.compact(); - b.reset(); - }}); + tryCatch(b, BufferUnderflowException.class, () -> b.get()); + tryCatch(b, BufferOverflowException.class, () -> b.put((int)42)); + // The index must be non-negative and less than the buffer's limit. + catchIndexOutOfBounds(b, () -> b.get(b.limit())); + catchIndexOutOfBounds(b, () -> b.get(-1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), (int)42)); + tryCatch(b, InvalidMarkException.class, + () -> b.position(0).mark().compact().reset()); try { b.position(b.limit() + 1); @@ -635,7 +637,6 @@ public class BasicInt - int v; b.flip(); ck(b, b.get(), 0); ck(b, b.get(), (int)-1); @@ -660,6 +661,10 @@ public class BasicInt + + + + @@ -683,14 +688,15 @@ public class BasicInt - ) + ) { out.println("[" + i + "] " + x + " != " + y); + } } fail("Identical buffers not equal", b, b2); } - if (b.compareTo(b2) != 0) + if (b.compareTo(b2) != 0) { fail("Comparison to identical buffer != 0", b, b2); - + } b.limit(b.limit() + 1); b.position(b.limit() - 1); b.put((int)99); @@ -714,7 +720,7 @@ public class BasicInt if (xb.compareTo(xb) != 0) { fail("compareTo not reflexive", xb, xb, x, x); } - if (! xb.equals(xb)) { + if (!xb.equals(xb)) { fail("equals not reflexive", xb, xb, x, x); } for (int y : VALUES) { @@ -765,9 +771,10 @@ public class BasicInt if (!sb.equals(sb2)) fail("Sliced slices do not match", sb, sb2); - if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) + if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) { fail("Array offsets do not match: " + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); + } @@ -808,87 +815,17 @@ public class BasicInt fail("Buffer not equal to read-only view", b, rb); show(level + 1, rb); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - relPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - absPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutArray(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutBuffer(rb); - }}); + catchReadOnlyBuffer(b, () -> relPut(rb)); + catchReadOnlyBuffer(b, () -> absPut(rb)); + catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); // put(IntBuffer) should not change source position final IntBuffer src = IntBuffer.allocate(1); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.put(src); - }}); + catchReadOnlyBuffer(b, () -> rb.put(src)); ck(src, src.position(), 0); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.compact(); - }}); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + catchReadOnlyBuffer(b, () -> rb.compact()); @@ -916,21 +853,11 @@ public class BasicInt if (rb.getClass().getName().startsWith("java.nio.Heap")) { - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.array(); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.arrayOffset(); - }}); - - if (rb.hasArray()) - fail("Read-only heap buffer's backing array is accessible", - rb); - + catchReadOnlyBuffer(b, () -> rb.array()); + catchReadOnlyBuffer(b, () -> rb.arrayOffset()); + if (rb.hasArray()) { + fail("Read-only heap buffer's backing array is accessible", rb); + } } // Bulk puts from read-only buffers @@ -980,47 +907,6 @@ public class BasicInt - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1052,40 +938,21 @@ public class BasicInt ck(b, b.limit(), offset + length); // The offset must be non-negative and no larger than <array.length>. - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - IntBuffer.wrap(ba, -1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - IntBuffer.wrap(ba, ba.length + 1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - IntBuffer.wrap(ba, 0, -1); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - IntBuffer.wrap(ba, 0, ba.length + 1); - }}); + catchIndexOutOfBounds(ba, () -> IntBuffer.wrap(ba, -1, ba.length)); + catchIndexOutOfBounds(ba, () -> IntBuffer.wrap(ba, ba.length + 1, ba.length)); + catchIndexOutOfBounds(ba, () -> IntBuffer.wrap(ba, 0, -1)); + catchIndexOutOfBounds(ba, () -> IntBuffer.wrap(ba, 0, ba.length + 1)); // A NullPointerException will be thrown if the array is null. - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - IntBuffer.wrap((int []) null, 0, 5); - }}); - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - IntBuffer.wrap((int []) null); - }}); + tryCatch(ba, NullPointerException.class, + () -> IntBuffer.wrap((int []) null, 0, 5)); + tryCatch(ba, NullPointerException.class, + () -> IntBuffer.wrap((int []) null)); } private static void testAllocate() { // An IllegalArgumentException will be thrown for negative capacities. - tryCatch((Buffer) null, IllegalArgumentException.class, new Runnable() { - public void run() { - IntBuffer.allocate(-1); - }}); + catchIllegalArgument((Buffer) null, () -> IntBuffer.allocate(-1)); try { IntBuffer.allocate(-1); } catch (IllegalArgumentException e) { @@ -1105,9 +972,6 @@ public class BasicInt - - - } public static void test() { diff --git a/jdk/test/java/nio/Buffer/BasicLong.java b/jdk/test/java/nio/Buffer/BasicLong.java index d3a0ff98c10..a7310c3c66d 100644 --- a/jdk/test/java/nio/Buffer/BasicLong.java +++ b/jdk/test/java/nio/Buffer/BasicLong.java @@ -31,7 +31,6 @@ // -- This file was mechanically generated: Do not edit! -- // import java.nio.*; -import java.lang.reflect.Method; public class BasicLong @@ -60,7 +59,6 @@ public class BasicLong private static void relGet(LongBuffer b) { int n = b.capacity(); - long v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((long)ic(i))); b.rewind(); @@ -68,7 +66,6 @@ public class BasicLong private static void relGet(LongBuffer b, int start) { int n = b.remaining(); - long v; for (int i = start; i < n; i++) ck(b, (long)b.get(), (long)((long)ic(i))); b.rewind(); @@ -76,7 +73,6 @@ public class BasicLong private static void absGet(LongBuffer b) { int n = b.capacity(); - long v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((long)ic(i))); b.rewind(); @@ -86,8 +82,9 @@ public class BasicLong int n = b.capacity(); long[] a = new long[n + 7]; b.get(a, 7, n); - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { ck(b, (long)a[i + 7], (long)((long)ic(i))); + } } private static void relPut(LongBuffer b) { @@ -420,6 +417,20 @@ public class BasicLong + + + + + + + + + + + + + + @@ -441,6 +452,22 @@ public class BasicLong fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { + tryCatch(b, IllegalArgumentException.class, thunk); + } + + private static void catchReadOnlyBuffer(Buffer b, Runnable thunk) { + tryCatch(b, ReadOnlyBufferException.class, thunk); + } + + private static void catchIndexOutOfBounds(Buffer b, Runnable thunk) { + tryCatch(b, IndexOutOfBoundsException.class, thunk); + } + + private static void catchIndexOutOfBounds(long[] t, Runnable thunk) { + tryCatch(t, IndexOutOfBoundsException.class, thunk); + } + private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) { boolean caught = false; try { @@ -452,11 +479,12 @@ public class BasicLong fail(x.getMessage() + " not expected"); } } - if (!caught) + if (!caught) { fail(ex.getName() + " not thrown", b); + } } - private static void tryCatch(long [] t, Class<?> ex, Runnable thunk) { + private static void tryCatch(long[] t, Class<?> ex, Runnable thunk) { tryCatch(LongBuffer.wrap(t), ex, thunk); } @@ -518,8 +546,6 @@ public class BasicLong - - @@ -537,38 +563,14 @@ public class BasicLong b.limit(b.capacity() / 2); b.position(b.limit()); - tryCatch(b, BufferUnderflowException.class, new Runnable() { - public void run() { - b.get(); - }}); - - tryCatch(b, BufferOverflowException.class, new Runnable() { - public void run() { - b.put((long)42); - }}); - - // The index must be non-negative and lesss than the buffer's limit. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(b.limit()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(-1); - }}); - - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.put(b.limit(), (long)42); - }}); - - tryCatch(b, InvalidMarkException.class, new Runnable() { - public void run() { - b.position(0); - b.mark(); - b.compact(); - b.reset(); - }}); + tryCatch(b, BufferUnderflowException.class, () -> b.get()); + tryCatch(b, BufferOverflowException.class, () -> b.put((long)42)); + // The index must be non-negative and less than the buffer's limit. + catchIndexOutOfBounds(b, () -> b.get(b.limit())); + catchIndexOutOfBounds(b, () -> b.get(-1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), (long)42)); + tryCatch(b, InvalidMarkException.class, + () -> b.position(0).mark().compact().reset()); try { b.position(b.limit() + 1); @@ -635,7 +637,6 @@ public class BasicLong - long v; b.flip(); ck(b, b.get(), 0); ck(b, b.get(), (long)-1); @@ -660,6 +661,10 @@ public class BasicLong + + + + @@ -683,14 +688,15 @@ public class BasicLong - ) + ) { out.println("[" + i + "] " + x + " != " + y); + } } fail("Identical buffers not equal", b, b2); } - if (b.compareTo(b2) != 0) + if (b.compareTo(b2) != 0) { fail("Comparison to identical buffer != 0", b, b2); - + } b.limit(b.limit() + 1); b.position(b.limit() - 1); b.put((long)99); @@ -714,7 +720,7 @@ public class BasicLong if (xb.compareTo(xb) != 0) { fail("compareTo not reflexive", xb, xb, x, x); } - if (! xb.equals(xb)) { + if (!xb.equals(xb)) { fail("equals not reflexive", xb, xb, x, x); } for (long y : VALUES) { @@ -765,9 +771,10 @@ public class BasicLong if (!sb.equals(sb2)) fail("Sliced slices do not match", sb, sb2); - if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) + if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) { fail("Array offsets do not match: " + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); + } @@ -808,87 +815,17 @@ public class BasicLong fail("Buffer not equal to read-only view", b, rb); show(level + 1, rb); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - relPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - absPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutArray(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutBuffer(rb); - }}); + catchReadOnlyBuffer(b, () -> relPut(rb)); + catchReadOnlyBuffer(b, () -> absPut(rb)); + catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); // put(LongBuffer) should not change source position final LongBuffer src = LongBuffer.allocate(1); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.put(src); - }}); + catchReadOnlyBuffer(b, () -> rb.put(src)); ck(src, src.position(), 0); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.compact(); - }}); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + catchReadOnlyBuffer(b, () -> rb.compact()); @@ -916,21 +853,11 @@ public class BasicLong if (rb.getClass().getName().startsWith("java.nio.Heap")) { - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.array(); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.arrayOffset(); - }}); - - if (rb.hasArray()) - fail("Read-only heap buffer's backing array is accessible", - rb); - + catchReadOnlyBuffer(b, () -> rb.array()); + catchReadOnlyBuffer(b, () -> rb.arrayOffset()); + if (rb.hasArray()) { + fail("Read-only heap buffer's backing array is accessible", rb); + } } // Bulk puts from read-only buffers @@ -980,47 +907,6 @@ public class BasicLong - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1052,40 +938,21 @@ public class BasicLong ck(b, b.limit(), offset + length); // The offset must be non-negative and no larger than <array.length>. - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - LongBuffer.wrap(ba, -1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - LongBuffer.wrap(ba, ba.length + 1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - LongBuffer.wrap(ba, 0, -1); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - LongBuffer.wrap(ba, 0, ba.length + 1); - }}); + catchIndexOutOfBounds(ba, () -> LongBuffer.wrap(ba, -1, ba.length)); + catchIndexOutOfBounds(ba, () -> LongBuffer.wrap(ba, ba.length + 1, ba.length)); + catchIndexOutOfBounds(ba, () -> LongBuffer.wrap(ba, 0, -1)); + catchIndexOutOfBounds(ba, () -> LongBuffer.wrap(ba, 0, ba.length + 1)); // A NullPointerException will be thrown if the array is null. - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - LongBuffer.wrap((long []) null, 0, 5); - }}); - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - LongBuffer.wrap((long []) null); - }}); + tryCatch(ba, NullPointerException.class, + () -> LongBuffer.wrap((long []) null, 0, 5)); + tryCatch(ba, NullPointerException.class, + () -> LongBuffer.wrap((long []) null)); } private static void testAllocate() { // An IllegalArgumentException will be thrown for negative capacities. - tryCatch((Buffer) null, IllegalArgumentException.class, new Runnable() { - public void run() { - LongBuffer.allocate(-1); - }}); + catchIllegalArgument((Buffer) null, () -> LongBuffer.allocate(-1)); try { LongBuffer.allocate(-1); } catch (IllegalArgumentException e) { @@ -1105,9 +972,6 @@ public class BasicLong - - - } public static void test() { diff --git a/jdk/test/java/nio/Buffer/BasicShort.java b/jdk/test/java/nio/Buffer/BasicShort.java index eef47f23e21..5d94bf2b15f 100644 --- a/jdk/test/java/nio/Buffer/BasicShort.java +++ b/jdk/test/java/nio/Buffer/BasicShort.java @@ -31,7 +31,6 @@ // -- This file was mechanically generated: Do not edit! -- // import java.nio.*; -import java.lang.reflect.Method; public class BasicShort @@ -60,7 +59,6 @@ public class BasicShort private static void relGet(ShortBuffer b) { int n = b.capacity(); - short v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((short)ic(i))); b.rewind(); @@ -68,7 +66,6 @@ public class BasicShort private static void relGet(ShortBuffer b, int start) { int n = b.remaining(); - short v; for (int i = start; i < n; i++) ck(b, (long)b.get(), (long)((short)ic(i))); b.rewind(); @@ -76,7 +73,6 @@ public class BasicShort private static void absGet(ShortBuffer b) { int n = b.capacity(); - short v; for (int i = 0; i < n; i++) ck(b, (long)b.get(), (long)((short)ic(i))); b.rewind(); @@ -86,8 +82,9 @@ public class BasicShort int n = b.capacity(); short[] a = new short[n + 7]; b.get(a, 7, n); - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { ck(b, (long)a[i + 7], (long)((short)ic(i))); + } } private static void relPut(ShortBuffer b) { @@ -420,6 +417,20 @@ public class BasicShort + + + + + + + + + + + + + + @@ -441,6 +452,22 @@ public class BasicShort fail(problem + String.format(": x=%s y=%s", x, y), xb, yb); } + private static void catchIllegalArgument(Buffer b, Runnable thunk) { + tryCatch(b, IllegalArgumentException.class, thunk); + } + + private static void catchReadOnlyBuffer(Buffer b, Runnable thunk) { + tryCatch(b, ReadOnlyBufferException.class, thunk); + } + + private static void catchIndexOutOfBounds(Buffer b, Runnable thunk) { + tryCatch(b, IndexOutOfBoundsException.class, thunk); + } + + private static void catchIndexOutOfBounds(short[] t, Runnable thunk) { + tryCatch(t, IndexOutOfBoundsException.class, thunk); + } + private static void tryCatch(Buffer b, Class<?> ex, Runnable thunk) { boolean caught = false; try { @@ -452,11 +479,12 @@ public class BasicShort fail(x.getMessage() + " not expected"); } } - if (!caught) + if (!caught) { fail(ex.getName() + " not thrown", b); + } } - private static void tryCatch(short [] t, Class<?> ex, Runnable thunk) { + private static void tryCatch(short[] t, Class<?> ex, Runnable thunk) { tryCatch(ShortBuffer.wrap(t), ex, thunk); } @@ -518,8 +546,6 @@ public class BasicShort - - @@ -537,38 +563,14 @@ public class BasicShort b.limit(b.capacity() / 2); b.position(b.limit()); - tryCatch(b, BufferUnderflowException.class, new Runnable() { - public void run() { - b.get(); - }}); - - tryCatch(b, BufferOverflowException.class, new Runnable() { - public void run() { - b.put((short)42); - }}); - - // The index must be non-negative and lesss than the buffer's limit. - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(b.limit()); - }}); - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.get(-1); - }}); - - tryCatch(b, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - b.put(b.limit(), (short)42); - }}); - - tryCatch(b, InvalidMarkException.class, new Runnable() { - public void run() { - b.position(0); - b.mark(); - b.compact(); - b.reset(); - }}); + tryCatch(b, BufferUnderflowException.class, () -> b.get()); + tryCatch(b, BufferOverflowException.class, () -> b.put((short)42)); + // The index must be non-negative and less than the buffer's limit. + catchIndexOutOfBounds(b, () -> b.get(b.limit())); + catchIndexOutOfBounds(b, () -> b.get(-1)); + catchIndexOutOfBounds(b, () -> b.put(b.limit(), (short)42)); + tryCatch(b, InvalidMarkException.class, + () -> b.position(0).mark().compact().reset()); try { b.position(b.limit() + 1); @@ -635,7 +637,6 @@ public class BasicShort - short v; b.flip(); ck(b, b.get(), 0); ck(b, b.get(), (short)-1); @@ -660,6 +661,10 @@ public class BasicShort + + + + @@ -683,14 +688,15 @@ public class BasicShort - ) + ) { out.println("[" + i + "] " + x + " != " + y); + } } fail("Identical buffers not equal", b, b2); } - if (b.compareTo(b2) != 0) + if (b.compareTo(b2) != 0) { fail("Comparison to identical buffer != 0", b, b2); - + } b.limit(b.limit() + 1); b.position(b.limit() - 1); b.put((short)99); @@ -714,7 +720,7 @@ public class BasicShort if (xb.compareTo(xb) != 0) { fail("compareTo not reflexive", xb, xb, x, x); } - if (! xb.equals(xb)) { + if (!xb.equals(xb)) { fail("equals not reflexive", xb, xb, x, x); } for (short y : VALUES) { @@ -765,9 +771,10 @@ public class BasicShort if (!sb.equals(sb2)) fail("Sliced slices do not match", sb, sb2); - if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) + if ((sb.hasArray()) && (sb.arrayOffset() != sb2.arrayOffset())) { fail("Array offsets do not match: " + sb.arrayOffset() + " != " + sb2.arrayOffset(), sb, sb2); + } @@ -808,87 +815,17 @@ public class BasicShort fail("Buffer not equal to read-only view", b, rb); show(level + 1, rb); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - relPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - absPut(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutArray(rb); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - bulkPutBuffer(rb); - }}); + catchReadOnlyBuffer(b, () -> relPut(rb)); + catchReadOnlyBuffer(b, () -> absPut(rb)); + catchReadOnlyBuffer(b, () -> bulkPutArray(rb)); + catchReadOnlyBuffer(b, () -> bulkPutBuffer(rb)); // put(ShortBuffer) should not change source position final ShortBuffer src = ShortBuffer.allocate(1); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.put(src); - }}); + catchReadOnlyBuffer(b, () -> rb.put(src)); ck(src, src.position(), 0); - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.compact(); - }}); - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + catchReadOnlyBuffer(b, () -> rb.compact()); @@ -916,21 +853,11 @@ public class BasicShort if (rb.getClass().getName().startsWith("java.nio.Heap")) { - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.array(); - }}); - - tryCatch(b, ReadOnlyBufferException.class, new Runnable() { - public void run() { - rb.arrayOffset(); - }}); - - if (rb.hasArray()) - fail("Read-only heap buffer's backing array is accessible", - rb); - + catchReadOnlyBuffer(b, () -> rb.array()); + catchReadOnlyBuffer(b, () -> rb.arrayOffset()); + if (rb.hasArray()) { + fail("Read-only heap buffer's backing array is accessible", rb); + } } // Bulk puts from read-only buffers @@ -980,47 +907,6 @@ public class BasicShort - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -1052,40 +938,21 @@ public class BasicShort ck(b, b.limit(), offset + length); // The offset must be non-negative and no larger than <array.length>. - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - ShortBuffer.wrap(ba, -1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - ShortBuffer.wrap(ba, ba.length + 1, ba.length); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - ShortBuffer.wrap(ba, 0, -1); - }}); - tryCatch(ba, IndexOutOfBoundsException.class, new Runnable() { - public void run() { - ShortBuffer.wrap(ba, 0, ba.length + 1); - }}); + catchIndexOutOfBounds(ba, () -> ShortBuffer.wrap(ba, -1, ba.length)); + catchIndexOutOfBounds(ba, () -> ShortBuffer.wrap(ba, ba.length + 1, ba.length)); + catchIndexOutOfBounds(ba, () -> ShortBuffer.wrap(ba, 0, -1)); + catchIndexOutOfBounds(ba, () -> ShortBuffer.wrap(ba, 0, ba.length + 1)); // A NullPointerException will be thrown if the array is null. - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - ShortBuffer.wrap((short []) null, 0, 5); - }}); - tryCatch(ba, NullPointerException.class, new Runnable() { - public void run() { - ShortBuffer.wrap((short []) null); - }}); + tryCatch(ba, NullPointerException.class, + () -> ShortBuffer.wrap((short []) null, 0, 5)); + tryCatch(ba, NullPointerException.class, + () -> ShortBuffer.wrap((short []) null)); } private static void testAllocate() { // An IllegalArgumentException will be thrown for negative capacities. - tryCatch((Buffer) null, IllegalArgumentException.class, new Runnable() { - public void run() { - ShortBuffer.allocate(-1); - }}); + catchIllegalArgument((Buffer) null, () -> ShortBuffer.allocate(-1)); try { ShortBuffer.allocate(-1); } catch (IllegalArgumentException e) { @@ -1105,9 +972,6 @@ public class BasicShort - - - } public static void test() { diff --git a/jdk/test/java/nio/Buffer/LimitDirectMemory.java b/jdk/test/java/nio/Buffer/LimitDirectMemory.java index 597e4d9c093..e8a22b4b89c 100644 --- a/jdk/test/java/nio/Buffer/LimitDirectMemory.java +++ b/jdk/test/java/nio/Buffer/LimitDirectMemory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,7 @@ import java.nio.ByteBuffer; import java.util.Properties; public class LimitDirectMemory { - private static int K = 1024; + private static final int K = 1024; public static void main(String [] args) throws Exception { if (args.length < 2) @@ -83,7 +83,7 @@ public class LimitDirectMemory { int idx = 0, len = size.length(); - int result = 1; + for (int i = 0; i < len; i++) { if (Character.isDigit(size.charAt(i))) idx++; else break; @@ -92,7 +92,7 @@ public class LimitDirectMemory { if (idx == 0) throw new RuntimeException("No digits detected: " + size); - result = Integer.parseInt(size.substring(0, idx)); + int result = Integer.parseInt(size.substring(0, idx)); if (idx < len) { for (int i = idx; i < len; i++) { diff --git a/jdk/test/java/nio/Buffer/Order-X.java.template b/jdk/test/java/nio/Buffer/Order-X.java.template index a8753a5f8a9..97313a841f6 100644 --- a/jdk/test/java/nio/Buffer/Order-X.java.template +++ b/jdk/test/java/nio/Buffer/Order-X.java.template @@ -52,8 +52,5 @@ public class Order$Type$ extends Order { buf = $Type$Buffer.allocate(LENGTH); ck(buf.order(), nord); ck$Type$Buffer(buf, nord); - - ck$Type$Buffer(ByteBuffer.allocate(LENGTH).as$Type$Buffer(), be); - ck$Type$Buffer(ByteBuffer.allocateDirect(LENGTH).as$Type$Buffer(), be); } } diff --git a/jdk/test/java/nio/Buffer/Order.java b/jdk/test/java/nio/Buffer/Order.java index 768fecb8b8a..33ae418bb56 100644 --- a/jdk/test/java/nio/Buffer/Order.java +++ b/jdk/test/java/nio/Buffer/Order.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2016, 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,41 +39,49 @@ public class Order { static void ck(ByteOrder ord, ByteOrder expected) { if (ord != expected) - throw new RuntimeException("Got " + ord - + ", expected " + expected); + throw new RuntimeException("Got " + ord + ", expected " + expected); } - static void ckViews(ByteBuffer bb, ByteOrder ord) { + private static void ckViews(ByteBuffer bb) { ck(bb.asCharBuffer().order(), bb.order()); + ck(bb.asShortBuffer().order(), bb.order()); ck(bb.asIntBuffer().order(), bb.order()); ck(bb.asLongBuffer().order(), bb.order()); ck(bb.asFloatBuffer().order(), bb.order()); ck(bb.asDoubleBuffer().order(), bb.order()); } - static void ckByteBuffer(ByteBuffer bb) { - ckViews(bb, bb.order()); - bb.order(be); - ckViews(bb, be); - bb.order(le); - ckViews(bb, le); + private static void ckCopyViews(ByteBuffer bb) { + ck(bb.asReadOnlyBuffer().order(), be); + ck(bb.duplicate().order(), be); + ck(bb.slice().order(), be); + } - if (bb.hasArray()) { - byte[] array = bb.array(); - ck(ByteBuffer.wrap(array, LENGTH/2, LENGTH/2).order(), be); - ck(ByteBuffer.wrap(array).order(), be); - ck(bb.asReadOnlyBuffer().order(), be); - ck(bb.duplicate().order(), be); - ck(bb.slice().order(), be); - } + private static void ckByteBuffer(ByteBuffer bb) { + ckViews(bb); + ckCopyViews(bb); + bb.order(be); + ckViews(bb); + ckCopyViews(bb); + bb.order(le); + ckViews(bb); + ckCopyViews(bb); } public static void main(String args[]) throws Exception { + ck(ByteBuffer.wrap(new byte[LENGTH], LENGTH/2, LENGTH/2).order(), be); + ck(ByteBuffer.wrap(new byte[LENGTH]).order(), be); + ck(ByteBuffer.wrap(new byte[LENGTH], LENGTH/2, LENGTH/2).order(be).order(), be); + ck(ByteBuffer.wrap(new byte[LENGTH]).order(be).order(), be); + ck(ByteBuffer.wrap(new byte[LENGTH], LENGTH/2, LENGTH/2).order(le).order(), le); + ck(ByteBuffer.wrap(new byte[LENGTH]).order(le).order(), le); ck(ByteBuffer.allocate(LENGTH).order(), be); ck(ByteBuffer.allocateDirect(LENGTH).order(), be); ck(ByteBuffer.allocate(LENGTH).order(be).order(), be); ck(ByteBuffer.allocate(LENGTH).order(le).order(), le); + ck(ByteBuffer.allocateDirect(LENGTH).order(be).order(), be); + ck(ByteBuffer.allocateDirect(LENGTH).order(le).order(), le); ckByteBuffer(ByteBuffer.allocate(LENGTH)); ckByteBuffer(ByteBuffer.allocateDirect(LENGTH)); @@ -85,5 +93,4 @@ public class Order { OrderFloat.ckFloatBuffer(); OrderDouble.ckDoubleBuffer(); } - } diff --git a/jdk/test/java/nio/Buffer/OrderChar.java b/jdk/test/java/nio/Buffer/OrderChar.java index ebf9faad79c..f72828bd0de 100644 --- a/jdk/test/java/nio/Buffer/OrderChar.java +++ b/jdk/test/java/nio/Buffer/OrderChar.java @@ -52,8 +52,5 @@ public class OrderChar extends Order { buf = CharBuffer.allocate(LENGTH); ck(buf.order(), nord); ckCharBuffer(buf, nord); - - ckCharBuffer(ByteBuffer.allocate(LENGTH).asCharBuffer(), be); - ckCharBuffer(ByteBuffer.allocateDirect(LENGTH).asCharBuffer(), be); } } diff --git a/jdk/test/java/nio/Buffer/OrderDouble.java b/jdk/test/java/nio/Buffer/OrderDouble.java index deaa6a3eb27..4100695cab5 100644 --- a/jdk/test/java/nio/Buffer/OrderDouble.java +++ b/jdk/test/java/nio/Buffer/OrderDouble.java @@ -52,8 +52,5 @@ public class OrderDouble extends Order { buf = DoubleBuffer.allocate(LENGTH); ck(buf.order(), nord); ckDoubleBuffer(buf, nord); - - ckDoubleBuffer(ByteBuffer.allocate(LENGTH).asDoubleBuffer(), be); - ckDoubleBuffer(ByteBuffer.allocateDirect(LENGTH).asDoubleBuffer(), be); } } diff --git a/jdk/test/java/nio/Buffer/OrderFloat.java b/jdk/test/java/nio/Buffer/OrderFloat.java index 6a65eaa8e4f..905d531d434 100644 --- a/jdk/test/java/nio/Buffer/OrderFloat.java +++ b/jdk/test/java/nio/Buffer/OrderFloat.java @@ -52,8 +52,5 @@ public class OrderFloat extends Order { buf = FloatBuffer.allocate(LENGTH); ck(buf.order(), nord); ckFloatBuffer(buf, nord); - - ckFloatBuffer(ByteBuffer.allocate(LENGTH).asFloatBuffer(), be); - ckFloatBuffer(ByteBuffer.allocateDirect(LENGTH).asFloatBuffer(), be); } } diff --git a/jdk/test/java/nio/Buffer/OrderInt.java b/jdk/test/java/nio/Buffer/OrderInt.java index 5d3843ffec7..700fc07110a 100644 --- a/jdk/test/java/nio/Buffer/OrderInt.java +++ b/jdk/test/java/nio/Buffer/OrderInt.java @@ -52,8 +52,5 @@ public class OrderInt extends Order { buf = IntBuffer.allocate(LENGTH); ck(buf.order(), nord); ckIntBuffer(buf, nord); - - ckIntBuffer(ByteBuffer.allocate(LENGTH).asIntBuffer(), be); - ckIntBuffer(ByteBuffer.allocateDirect(LENGTH).asIntBuffer(), be); } } diff --git a/jdk/test/java/nio/Buffer/OrderLong.java b/jdk/test/java/nio/Buffer/OrderLong.java index abda8b22932..9e507ffc18e 100644 --- a/jdk/test/java/nio/Buffer/OrderLong.java +++ b/jdk/test/java/nio/Buffer/OrderLong.java @@ -52,8 +52,5 @@ public class OrderLong extends Order { buf = LongBuffer.allocate(LENGTH); ck(buf.order(), nord); ckLongBuffer(buf, nord); - - ckLongBuffer(ByteBuffer.allocate(LENGTH).asLongBuffer(), be); - ckLongBuffer(ByteBuffer.allocateDirect(LENGTH).asLongBuffer(), be); } } diff --git a/jdk/test/java/nio/Buffer/OrderShort.java b/jdk/test/java/nio/Buffer/OrderShort.java index d19b43a1b60..f385b62d6dd 100644 --- a/jdk/test/java/nio/Buffer/OrderShort.java +++ b/jdk/test/java/nio/Buffer/OrderShort.java @@ -52,8 +52,5 @@ public class OrderShort extends Order { buf = ShortBuffer.allocate(LENGTH); ck(buf.order(), nord); ckShortBuffer(buf, nord); - - ckShortBuffer(ByteBuffer.allocate(LENGTH).asShortBuffer(), be); - ckShortBuffer(ByteBuffer.allocateDirect(LENGTH).asShortBuffer(), be); } } diff --git a/jdk/test/java/nio/Buffer/SwapMicroBenchmark.java b/jdk/test/java/nio/Buffer/SwapMicroBenchmark.java index 1942639a460..31bbe908c20 100644 --- a/jdk/test/java/nio/Buffer/SwapMicroBenchmark.java +++ b/jdk/test/java/nio/Buffer/SwapMicroBenchmark.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, 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 @@ -35,7 +35,6 @@ import java.util.*; import java.nio.*; -import java.util.concurrent.*; import java.util.regex.Pattern; public class SwapMicroBenchmark { diff --git a/jdk/test/java/sql/TEST.properties b/jdk/test/java/sql/TEST.properties new file mode 100644 index 00000000000..878b05fc591 --- /dev/null +++ b/jdk/test/java/sql/TEST.properties @@ -0,0 +1,2 @@ +modules = java.sql + diff --git a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java index db19675f97b..d0d380cd815 100644 --- a/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java +++ b/jdk/test/java/time/tck/java/time/format/TCKDateTimeFormatterBuilder.java @@ -73,7 +73,10 @@ import java.text.ParsePosition; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.LocalTime; +import java.time.Month; import java.time.YearMonth; +import java.time.ZonedDateTime; +import java.time.ZoneId; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; @@ -459,6 +462,98 @@ public class TCKDateTimeFormatterBuilder { //----------------------------------------------------------------------- //----------------------------------------------------------------------- //----------------------------------------------------------------------- + @DataProvider(name = "formatGenericTimeZonePatterns") + Object[][] data_formatGenericNonLocationPatterns() { + return new Object[][] { + {"v", "America/Los_Angeles", "PT"}, + {"vvvv", "America/Los_Angeles", "Pacific Time"}, + {"v", "America/New_York", "ET"}, + {"vvvv", "America/New_York", "Eastern Time"}, + }; + } + + @Test(dataProvider = "formatGenericTimeZonePatterns") + public void test_appendZoneText_formatGenericTimeZonePatterns(String pattern, String input, String expected) { + ZonedDateTime zdt = ZonedDateTime.of(LocalDateTime.now(), ZoneId.of(input)); + DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern); + assertEquals(zdt.format(df), expected); + } + + @DataProvider(name = "parseGenericTimeZonePatterns") + Object[][] data_parseGenericTimeZonePatterns() { + return new Object[][] { + {"yyyy DDD HH mm v", LocalDateTime.of(2015, Month.MARCH, 10, 12, 13), ZoneId.of("America/Los_Angeles"), + "2015 069 12 13 PT"}, + {"yyyy DDD HH mm vvvv", LocalDateTime.of(2015, Month.MARCH, 10, 12, 13), ZoneId.of("America/Los_Angeles"), + "2015 069 12 13 Pacific Time"}, + {"yyyy DDD HH mm v", LocalDateTime.of(2015, Month.NOVEMBER, 10, 12, 13), ZoneId.of("America/Los_Angeles"), + "2015 314 12 13 PT"}, + {"yyyy DDD HH mm vvvv", LocalDateTime.of(2015, Month.NOVEMBER, 10, 12, 13), ZoneId.of("America/Los_Angeles"), + "2015 314 12 13 Pacific Time"}, + }; + } + + @Test(dataProvider = "parseGenericTimeZonePatterns") + public void test_appendZoneText_parseGenericTimeZonePatterns(String pattern, LocalDateTime ldt, ZoneId zId, String input) { + DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(); + ZonedDateTime expected = ZonedDateTime.parse(input, df); + ZonedDateTime actual = ZonedDateTime.of(ldt, zId); + assertEquals(actual, expected); + } + + @DataProvider(name = "formatNonGenericTimeZonePatterns_1") + Object[][] data_formatNonGenericTimeZonePatterns_1() { + return new Object[][] { + {"yyyy-MM-dd HH:mm:ss z", LocalDateTime.of(2015, Month.NOVEMBER, 1, 0, 30), + "2015-11-01 00:30:00 PDT"}, + {"yyyy-MM-dd HH:mm:ss z", LocalDateTime.of(2015, Month.NOVEMBER, 1, 1, 30), + "2015-11-01 01:30:00 PDT"}, + {"yyyy-MM-dd HH:mm:ss z", LocalDateTime.of(2015, Month.NOVEMBER, 1, 2, 30), + "2015-11-01 02:30:00 PST"}, + {"yyyy-MM-dd HH:mm:ss zzzz", LocalDateTime.of(2015, Month.NOVEMBER, 1, 0, 30), + "2015-11-01 00:30:00 Pacific Daylight Time"}, + {"yyyy-MM-dd HH:mm:ss zzzz", LocalDateTime.of(2015, Month.NOVEMBER, 1, 1, 30), + "2015-11-01 01:30:00 Pacific Daylight Time"}, + {"yyyy-MM-dd HH:mm:ss zzzz", LocalDateTime.of(2015, Month.NOVEMBER, 1, 2, 30), + "2015-11-01 02:30:00 Pacific Standard Time"}, + }; + } + + @Test(dataProvider = "formatNonGenericTimeZonePatterns_1") + public void test_appendZoneText_parseNonGenricTimeZonePatterns_1(String pattern, LocalDateTime ldt, String expected) { + ZoneId zId = ZoneId.of("America/Los_Angeles"); + DateTimeFormatter df = new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter(); + ZonedDateTime zdt = ZonedDateTime.of(ldt, zId); + String actual = df.format(zdt); + assertEquals(actual, expected); + } + + @DataProvider(name = "formatNonGenericTimeZonePatterns_2") + Object[][] data_formatNonGenericTimeZonePatterns_2() { + return new Object[][] { + {"yyyy-MM-dd HH:mm:ss z", LocalDateTime.of(2015, Month.NOVEMBER, 1, 0, 30), + "2015-11-01 00:30:00 PDT"}, + {"yyyy-MM-dd HH:mm:ss z", LocalDateTime.of(2015, Month.NOVEMBER, 1, 1, 30), + "2015-11-01 01:30:00 PT"}, + {"yyyy-MM-dd HH:mm:ss z", LocalDateTime.of(2015, Month.NOVEMBER, 1, 2, 30), + "2015-11-01 02:30:00 PST"}, + {"yyyy-MM-dd HH:mm:ss zzzz", LocalDateTime.of(2015, Month.NOVEMBER, 1, 0, 30), + "2015-11-01 00:30:00 Pacific Daylight Time"}, + {"yyyy-MM-dd HH:mm:ss zzzz", LocalDateTime.of(2015, Month.NOVEMBER, 1, 1, 30), + "2015-11-01 01:30:00 Pacific Time"}, + {"yyyy-MM-dd HH:mm:ss zzzz", LocalDateTime.of(2015, Month.NOVEMBER, 1, 2, 30), + "2015-11-01 02:30:00 Pacific Standard Time"}, + }; + } + + @Test(dataProvider = "formatNonGenericTimeZonePatterns_2") + public void test_appendZoneText_parseNonGenricTimeZonePatterns_2(String pattern, LocalDateTime ldt, String expected) { + ZoneId zId = ZoneId.of("America/Los_Angeles"); + DateTimeFormatter df = DateTimeFormatter.ofPattern(pattern).withZone(zId); + String actual = df.format(ldt); + assertEquals(actual, expected); + } + @Test(expectedExceptions=NullPointerException.class) public void test_appendZoneText_1arg_nullText() throws Exception { builder.appendZoneText(null); @@ -734,6 +829,9 @@ public class TCKDateTimeFormatterBuilder { {"www"}, {"WW"}, + + {"vv"}, + {"vvv"}, }; } diff --git a/jdk/test/java/util/Arrays/SortingNearlySortedPrimitive.java b/jdk/test/java/util/Arrays/SortingNearlySortedPrimitive.java index 99bd4cf04d2..b2c8d6ec45b 100644 --- a/jdk/test/java/util/Arrays/SortingNearlySortedPrimitive.java +++ b/jdk/test/java/util/Arrays/SortingNearlySortedPrimitive.java @@ -1,6 +1,6 @@ /* * Copyright 2015 Goldman Sachs. - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ */ /* * @test + * @bug 8154049 * @summary Tests the sorting of a large array of sorted primitive values, * predominently for cases where the array is nearly sorted. This tests * code that detects patterns in the array to determine if it is nearly @@ -32,32 +33,117 @@ * @run testng SortingNearlySortedPrimitive */ -import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import java.util.ArrayList; import java.util.Arrays; -import java.util.function.Supplier; +import java.util.List; +import java.util.StringJoiner; +import java.util.function.IntFunction; +import java.util.stream.IntStream; +import java.util.stream.Stream; public class SortingNearlySortedPrimitive { - private static final int ARRAY_SIZE = 1_000_000; - @DataProvider(name = "arrays") - public Object[][] createData() { - return new Object[][]{ - {"hiZeroLowTest", (Supplier<int[]>) this::hiZeroLowData}, - {"endLessThanTest", (Supplier<int[]>) this::endLessThanData}, - {"highFlatLowTest", (Supplier<int[]>) this::highFlatLowData}, - {"identicalTest", (Supplier<int[]>) this::identicalData}, - {"sortedReversedSortedTest", (Supplier<int[]>) this::sortedReversedSortedData}, - {"pairFlipTest", (Supplier<int[]>) this::pairFlipData}, - {"zeroHiTest", (Supplier<int[]>) this::zeroHiData}, - }; + static final int BASE = 3; + static final int WIDTH = 4; + // Should be > DualPivotQuicksort.QUICKSORT_THRESHOLD + static final int PAD = 300; + + Stream<int[]> createCombinations() { + // Create all combinations for the BASE value and double the WIDTH + // elements + // This is create various combinations of ascending, descending and + // equal runs to exercise the nearly sorted code paths + return IntStream.range(0, (int) Math.pow(BASE, 2 * WIDTH)). + mapToObj(this::createArray); } - @Test(dataProvider = "arrays") - public void runTests(String testName, Supplier<int[]> dataMethod) throws Exception { - int[] intSourceArray = dataMethod.get(); + // Create an array which at either end is filled with -ve and +ve elements + // according to the base value and padded with zeros in between + int[] createArray(int v) { + int[] a = new int[WIDTH + PAD + WIDTH]; + + // Fill head of array + for (int j = 0; j < WIDTH; j++) { + a[j] = (v % BASE) - (BASE / 2); + v /= BASE; + } + // Fill tail of array + for (int j = 0; j < WIDTH; j++) { + a[WIDTH + PAD + j] = (v % BASE) - (BASE / 2); + v /= BASE; + } + return a; + } + + @Test + public void testCombination() { + createCombinations().forEach(a -> { + try { + // Clone source array to ensure it is not modified + this.sortAndAssert(a.clone()); + this.sortAndAssert(floatCopyFromInt(a)); + this.sortAndAssert(doubleCopyFromInt(a)); + this.sortAndAssert(longCopyFromInt(a)); + this.sortAndAssert(shortCopyFromInt(a)); + this.sortAndAssert(charCopyFromInt(a)); + } catch (AssertionError sae) { + AssertionError ae = new AssertionError("Sort failed for " + arrayToString(a)); + ae.addSuppressed(sae); + throw ae; + } + }); + } + + String arrayToString(int[] a) { + int[] l = Arrays.copyOfRange(a, 0, WIDTH + 2); + int[] r = Arrays.copyOfRange(a, a.length - (WIDTH + 2), a.length); + StringJoiner sj = new StringJoiner(",", "[", "]"); + for (int i : l) { + sj.add(Integer.toString(i)); + } + sj.add("..."); + for (int i : r) { + sj.add(Integer.toString(i)); + } + return sj.toString(); + } + + + @DataProvider(name = "shapes") + public Object[][] createShapes() { + Stream<List<Object>> baseCases = Stream.of( + List.of("hiZeroLowTest", (IntFunction<int[]>) this::hiZeroLowData), + List.of("endLessThanTest", (IntFunction<int[]>) this::endLessThanData), + List.of("highFlatLowTest", (IntFunction<int[]>) this::highFlatLowData), + List.of("identicalTest", (IntFunction<int[]>) this::identicalData), + List.of("sortedReversedSortedTest", (IntFunction<int[]>) this::sortedReversedSortedData), + List.of("pairFlipTest", (IntFunction<int[]>) this::pairFlipData), + List.of("zeroHiTest", (IntFunction<int[]>) this::zeroHiData) + ); + + // Ensure the following inequality holds for certain sizes + // DualPivotQuicksort.QUICKSORT_THRESHOLD <= size - 1 + // < DualPivotQuicksort.COUNTING_SORT_THRESHOLD_FOR_SHORT_OR_CHAR + // This guarantees that code paths are taken for checking nearly sorted + // arrays for all primitive types + List<Integer> sizes = List.of(100, 1_000, 10_000, 1_000_000); + return baseCases. + flatMap(l -> sizes.stream().map(s -> append(l, s))). + toArray(Object[][]::new); + } + + Object[] append(List<Object> l, Object value) { + List<Object> nl = new ArrayList<>(l); + nl.add(value); + return nl.toArray(); + } + + @Test(dataProvider = "shapes") + public void testShapes(String testName, IntFunction<int[]> dataMethod, int size) { + int[] intSourceArray = dataMethod.apply(size); // Clone source array to ensure it is not modified this.sortAndAssert(intSourceArray.clone()); @@ -110,73 +196,67 @@ public class SortingNearlySortedPrimitive { private void sortAndAssert(int[] array) { Arrays.sort(array); - for (int i = 1; i < ARRAY_SIZE; i++) { + for (int i = 1; i < array.length; i++) { if (array[i] < array[i - 1]) { throw new AssertionError("not sorted"); } } - Assert.assertEquals(ARRAY_SIZE, array.length); } private void sortAndAssert(char[] array) { Arrays.sort(array); - for (int i = 1; i < ARRAY_SIZE; i++) { + for (int i = 1; i < array.length; i++) { if (array[i] < array[i - 1]) { throw new AssertionError("not sorted"); } } - Assert.assertEquals(ARRAY_SIZE, array.length); } private void sortAndAssert(short[] array) { Arrays.sort(array); - for (int i = 1; i < ARRAY_SIZE; i++) { + for (int i = 1; i < array.length; i++) { if (array[i] < array[i - 1]) { throw new AssertionError("not sorted"); } } - Assert.assertEquals(ARRAY_SIZE, array.length); } private void sortAndAssert(double[] array) { Arrays.sort(array); - for (int i = 1; i < ARRAY_SIZE; i++) { + for (int i = 1; i < array.length; i++) { if (array[i] < array[i - 1]) { throw new AssertionError("not sorted"); } } - Assert.assertEquals(ARRAY_SIZE, array.length); } private void sortAndAssert(float[] array) { Arrays.sort(array); - for (int i = 1; i < ARRAY_SIZE; i++) { + for (int i = 1; i < array.length; i++) { if (array[i] < array[i - 1]) { throw new AssertionError("not sorted"); } } - Assert.assertEquals(ARRAY_SIZE, array.length); } private void sortAndAssert(long[] array) { Arrays.sort(array); - for (int i = 1; i < ARRAY_SIZE; i++) { + for (int i = 1; i < array.length; i++) { if (array[i] < array[i - 1]) { throw new AssertionError("not sorted"); } } - Assert.assertEquals(ARRAY_SIZE, array.length); } - private int[] zeroHiData() { - int[] array = new int[ARRAY_SIZE]; + private int[] zeroHiData(int size) { + int[] array = new int[size]; - int threeQuarters = (int) (ARRAY_SIZE * 0.75); + int threeQuarters = (int) (size * 0.75); for (int i = 0; i < threeQuarters; i++) { array[i] = 0; } int k = 1; - for (int i = threeQuarters; i < ARRAY_SIZE; i++) { + for (int i = threeQuarters; i < size; i++) { array[i] = k; k++; } @@ -184,10 +264,10 @@ public class SortingNearlySortedPrimitive { return array; } - private int[] hiZeroLowData() { - int[] array = new int[ARRAY_SIZE]; + private int[] hiZeroLowData(int size) { + int[] array = new int[size]; - int oneThird = ARRAY_SIZE / 3; + int oneThird = size / 3; for (int i = 0; i < oneThird; i++) { array[i] = i; } @@ -195,16 +275,16 @@ public class SortingNearlySortedPrimitive { for (int i = oneThird; i < twoThirds; i++) { array[i] = 0; } - for (int i = twoThirds; i < ARRAY_SIZE; i++) { + for (int i = twoThirds; i < size; i++) { array[i] = oneThird - i + twoThirds; } return array; } - private int[] highFlatLowData() { - int[] array = new int[ARRAY_SIZE]; + private int[] highFlatLowData(int size) { + int[] array = new int[size]; - int oneThird = ARRAY_SIZE / 3; + int oneThird = size / 3; for (int i = 0; i < oneThird; i++) { array[i] = i; } @@ -213,57 +293,57 @@ public class SortingNearlySortedPrimitive { for (int i = oneThird; i < twoThirds; i++) { array[i] = constant; } - for (int i = twoThirds; i < ARRAY_SIZE; i++) { + for (int i = twoThirds; i < size; i++) { array[i] = constant - i + twoThirds; } return array; } - private int[] identicalData() { - int[] array = new int[ARRAY_SIZE]; + private int[] identicalData(int size) { + int[] array = new int[size]; int listNumber = 24; - for (int i = 0; i < ARRAY_SIZE; i++) { + for (int i = 0; i < size; i++) { array[i] = listNumber; } return array; } - private int[] endLessThanData() { - int[] array = new int[ARRAY_SIZE]; + private int[] endLessThanData(int size) { + int[] array = new int[size]; - for (int i = 0; i < ARRAY_SIZE - 1; i++) { + for (int i = 0; i < size - 1; i++) { array[i] = 3; } - array[ARRAY_SIZE - 1] = 1; + array[size - 1] = 1; return array; } - private int[] sortedReversedSortedData() { - int[] array = new int[ARRAY_SIZE]; + private int[] sortedReversedSortedData(int size) { + int[] array = new int[size]; - for (int i = 0; i < ARRAY_SIZE / 2; i++) { + for (int i = 0; i < size / 2; i++) { array[i] = i; } int num = 0; - for (int i = ARRAY_SIZE / 2; i < ARRAY_SIZE; i++) { - array[i] = ARRAY_SIZE - num; + for (int i = size / 2; i < size; i++) { + array[i] = size - num; num++; } return array; } - private int[] pairFlipData() { - int[] array = new int[ARRAY_SIZE]; + private int[] pairFlipData(int size) { + int[] array = new int[size]; - for (int i = 0; i < ARRAY_SIZE; i++) { + for (int i = 0; i < size; i++) { array[i] = i; } - for (int i = 0; i < ARRAY_SIZE; i += 2) { + for (int i = 0; i < size; i += 2) { int temp = array[i]; array[i] = array[i + 1]; array[i + 1] = temp; diff --git a/jdk/test/java/util/Objects/CheckIndex.java b/jdk/test/java/util/Objects/CheckIndex.java index c4efdb1c253..bcfa1d5b23d 100644 --- a/jdk/test/java/util/Objects/CheckIndex.java +++ b/jdk/test/java/util/Objects/CheckIndex.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016 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,11 +23,13 @@ /** * @test - * @summary IndexOutOfBoundsException check index tests + * @summary Objects.checkIndex/jdk.internal.util.Preconditions.checkIndex tests * @run testng CheckIndex - * @bug 8135248 8142493 + * @bug 8135248 8142493 8155794 + * @modules java.base/jdk.internal.util */ +import jdk.internal.util.Preconditions; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; @@ -95,7 +97,7 @@ public class CheckIndex { public void testCheckIndex(int index, int length, boolean withinBounds) { String expectedMessage = withinBounds ? null - : Objects.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new). + : Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new). apply("checkIndex", List.of(index, length)).getMessage(); BiConsumer<Class<? extends RuntimeException>, IntSupplier> checker = (ec, s) -> { @@ -117,21 +119,21 @@ public class CheckIndex { }; checker.accept(AssertingOutOfBoundsException.class, - () -> Objects.checkIndex(index, length, - assertingOutOfBounds(expectedMessage, "checkIndex", index, length))); + () -> Preconditions.checkIndex(index, length, + assertingOutOfBounds(expectedMessage, "checkIndex", index, length))); checker.accept(IndexOutOfBoundsException.class, - () -> Objects.checkIndex(index, length, - assertingOutOfBoundsReturnNull("checkIndex", index, length))); + () -> Preconditions.checkIndex(index, length, + assertingOutOfBoundsReturnNull("checkIndex", index, length))); checker.accept(IndexOutOfBoundsException.class, - () -> Objects.checkIndex(index, length, null)); + () -> Preconditions.checkIndex(index, length, null)); checker.accept(IndexOutOfBoundsException.class, () -> Objects.checkIndex(index, length)); checker.accept(ArrayIndexOutOfBoundsException.class, - () -> Objects.checkIndex(index, length, - Objects.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new))); + () -> Preconditions.checkIndex(index, length, + Preconditions.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new))); checker.accept(StringIndexOutOfBoundsException.class, - () -> Objects.checkIndex(index, length, - Objects.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new))); + () -> Preconditions.checkIndex(index, length, + Preconditions.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new))); } @@ -157,7 +159,7 @@ public class CheckIndex { public void testCheckFromToIndex(int fromIndex, int toIndex, int length, boolean withinBounds) { String expectedMessage = withinBounds ? null - : Objects.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new). + : Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new). apply("checkFromToIndex", List.of(fromIndex, toIndex, length)).getMessage(); BiConsumer<Class<? extends RuntimeException>, IntSupplier> check = (ec, s) -> { @@ -179,21 +181,21 @@ public class CheckIndex { }; check.accept(AssertingOutOfBoundsException.class, - () -> Objects.checkFromToIndex(fromIndex, toIndex, length, - assertingOutOfBounds(expectedMessage, "checkFromToIndex", fromIndex, toIndex, length))); + () -> Preconditions.checkFromToIndex(fromIndex, toIndex, length, + assertingOutOfBounds(expectedMessage, "checkFromToIndex", fromIndex, toIndex, length))); check.accept(IndexOutOfBoundsException.class, - () -> Objects.checkFromToIndex(fromIndex, toIndex, length, - assertingOutOfBoundsReturnNull("checkFromToIndex", fromIndex, toIndex, length))); + () -> Preconditions.checkFromToIndex(fromIndex, toIndex, length, + assertingOutOfBoundsReturnNull("checkFromToIndex", fromIndex, toIndex, length))); check.accept(IndexOutOfBoundsException.class, - () -> Objects.checkFromToIndex(fromIndex, toIndex, length, null)); + () -> Preconditions.checkFromToIndex(fromIndex, toIndex, length, null)); check.accept(IndexOutOfBoundsException.class, () -> Objects.checkFromToIndex(fromIndex, toIndex, length)); check.accept(ArrayIndexOutOfBoundsException.class, - () -> Objects.checkFromToIndex(fromIndex, toIndex, length, - Objects.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new))); + () -> Preconditions.checkFromToIndex(fromIndex, toIndex, length, + Preconditions.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new))); check.accept(StringIndexOutOfBoundsException.class, - () -> Objects.checkFromToIndex(fromIndex, toIndex, length, - Objects.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new))); + () -> Preconditions.checkFromToIndex(fromIndex, toIndex, length, + Preconditions.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new))); } @@ -226,7 +228,7 @@ public class CheckIndex { public void testCheckFromIndexSize(int fromIndex, int size, int length, boolean withinBounds) { String expectedMessage = withinBounds ? null - : Objects.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new). + : Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new). apply("checkFromIndexSize", List.of(fromIndex, size, length)).getMessage(); BiConsumer<Class<? extends RuntimeException>, IntSupplier> check = (ec, s) -> { @@ -248,27 +250,27 @@ public class CheckIndex { }; check.accept(AssertingOutOfBoundsException.class, - () -> Objects.checkFromIndexSize(fromIndex, size, length, - assertingOutOfBounds(expectedMessage, "checkFromIndexSize", fromIndex, size, length))); + () -> Preconditions.checkFromIndexSize(fromIndex, size, length, + assertingOutOfBounds(expectedMessage, "checkFromIndexSize", fromIndex, size, length))); check.accept(IndexOutOfBoundsException.class, - () -> Objects.checkFromIndexSize(fromIndex, size, length, - assertingOutOfBoundsReturnNull("checkFromIndexSize", fromIndex, size, length))); + () -> Preconditions.checkFromIndexSize(fromIndex, size, length, + assertingOutOfBoundsReturnNull("checkFromIndexSize", fromIndex, size, length))); check.accept(IndexOutOfBoundsException.class, - () -> Objects.checkFromIndexSize(fromIndex, size, length, null)); + () -> Preconditions.checkFromIndexSize(fromIndex, size, length, null)); check.accept(IndexOutOfBoundsException.class, () -> Objects.checkFromIndexSize(fromIndex, size, length)); check.accept(ArrayIndexOutOfBoundsException.class, - () -> Objects.checkFromIndexSize(fromIndex, size, length, - Objects.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new))); + () -> Preconditions.checkFromIndexSize(fromIndex, size, length, + Preconditions.outOfBoundsExceptionFormatter(ArrayIndexOutOfBoundsException::new))); check.accept(StringIndexOutOfBoundsException.class, - () -> Objects.checkFromIndexSize(fromIndex, size, length, - Objects.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new))); + () -> Preconditions.checkFromIndexSize(fromIndex, size, length, + Preconditions.outOfBoundsExceptionFormatter(StringIndexOutOfBoundsException::new))); } @Test public void uniqueMessagesForCheckKinds() { BiFunction<String, List<Integer>, IndexOutOfBoundsException> f = - Objects.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new); + Preconditions.outOfBoundsExceptionFormatter(IndexOutOfBoundsException::new); List<String> messages = new ArrayList<>(); // Exact arguments diff --git a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java index 7d6da0b255e..630f3796b8c 100644 --- a/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java +++ b/jdk/test/java/util/concurrent/locks/Lock/TimedAcquireLeak.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2016, 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 @@ -167,7 +167,7 @@ public class TimedAcquireLeak { final String childPid, final String className) { final String regex = - "(?m)^ *[0-9]+: +([0-9]+) +[0-9]+ +\\Q"+className+"\\E$"; + "(?m)^ *[0-9]+: +([0-9]+) +[0-9]+ +\\Q"+className+"\\E(?:$| )"; final Callable<Integer> objectsInUse = new Callable<Integer>() { public Integer call() { Integer i = Integer.parseInt( diff --git a/jdk/test/javax/net/ssl/HttpsURLConnection/Equals.java b/jdk/test/javax/net/ssl/HttpsURLConnection/Equals.java index 0a482f31b90..0e40e52ce9b 100644 --- a/jdk/test/javax/net/ssl/HttpsURLConnection/Equals.java +++ b/jdk/test/javax/net/ssl/HttpsURLConnection/Equals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,7 @@ /** * @test * @library /lib/testlibrary + * @modules jdk.httpserver * @build jdk.testlibrary.SimpleSSLContext * @run main Equals * @bug 8055299 diff --git a/jdk/test/javax/net/ssl/ServerName/BestEffortOnLazyConnected.java b/jdk/test/javax/net/ssl/ServerName/BestEffortOnLazyConnected.java index ba3e5f10e50..bda0710f61e 100644 --- a/jdk/test/javax/net/ssl/ServerName/BestEffortOnLazyConnected.java +++ b/jdk/test/javax/net/ssl/ServerName/BestEffortOnLazyConnected.java @@ -34,9 +34,6 @@ */ import java.io.*; -import java.nio.*; -import java.nio.channels.*; -import java.util.*; import java.net.*; import javax.net.ssl.*; @@ -197,6 +194,7 @@ public class BestEffortOnLazyConnected { hostname); // Ignore the test if the hostname does not sound like a domain name. if ((hostname == null) || hostname.isEmpty() || + !hostname.contains(".") || hostname.endsWith(".") || hostname.startsWith("localhost") || Character.isDigit(hostname.charAt(hostname.length() - 1))) { diff --git a/jdk/test/javax/net/ssl/etc/README b/jdk/test/javax/net/ssl/etc/README new file mode 100644 index 00000000000..0ac6a844a86 --- /dev/null +++ b/jdk/test/javax/net/ssl/etc/README @@ -0,0 +1,94 @@ +Keystores used for the JSSE regression test suite. + +keystore +truststore +========== + +These are the primary two keystores and contain entries for testing most +of the JSSE regression test files. There are three entries, one RSA-based, +one DSA-based and one EC-based. If they expire, simply recreate them +using keytool and most of the test cases should work. + +The password on both files is: + + passphrase + +There are no individual key entry passwords at this time. + + +keystore entries +================ + +Alias name: dummy +----------------- +Creation date: May 16, 2016 +Entry type: PrivateKeyEntry +Certificate chain length: 1 +Certificate[1]: +Owner: CN=dummy.example.com, OU=Dummy, O=Dummy, L=Cupertino, ST=CA, C=US +Issuer: CN=dummy.example.com, OU=Dummy, O=Dummy, L=Cupertino, ST=CA, C=US +Serial number: 57399b87 +Valid from: Mon May 16 10:06:38 UTC 2016 until: Sat May 16 10:06:38 UTC 2026 +Signature algorithm name: SHA256withRSA +Version: 1 + +This can be generated using hacked (update the keytool source code so that +it can be used for version 1 X.509 certificate) keytool command: +% keytool -genkeypair -alias dummy -keyalg RSA -keysize 2048 \ + -sigalg SHA256withRSA \ + -dname "CN=dummy.example.com, OU=Dummy, O=Dummy, L=Cupertino, ST=CA, C=US" \ + -validity 3652 -keypass passphrase -keystore keystore -storepass passphrase + + +Alias name: dummyecdsa +---------------------- +Creation date: May 16, 2016 +Entry type: PrivateKeyEntry +Certificate chain length: 1 +Certificate[1]: +Owner: CN=dummy.example.com, OU=Dummy, O=Dummy, L=Cupertino, ST=CA, C=US +Issuer: CN=dummy.example.com, OU=Dummy, O=Dummy, L=Cupertino, ST=CA, C=US +Serial number: 57399c1d +Valid from: Mon May 16 10:09:01 UTC 2016 until: Sat May 16 10:09:01 UTC 2026 +Signature algorithm name: SHA256withECDSA +Version: 1 + +This can be generated using hacked (update the keytool source code so that +it can be used for version 1 X.509 certificate) keytool command: +% keytool -genkeypair -alias dummy -keyalg EC -keysize 256 \ + -sigalg SHA256withECDSA \ + -dname "CN=dummy.example.com, OU=Dummy, O=Dummy, L=Cupertino, ST=CA, C=US" \ + -validity 3652 -keypass passphrase -keystore keystore -storepass passphrase + +Alias name: dummydsa +-------------------- +Creation date: Mar 11, 2007 +Entry type: PrivateKeyEntry +Certificate chain length: 1 +Certificate[1]: +Owner: CN=dummy.example.com, OU=Dummy, O=Dummy, L=Cupertino, ST=CA, C=US +Issuer: CN=dummy.example.com, OU=Dummy, O=Dummy, L=Cupertino, ST=CA, C=US +Serial number: 45f3a314 +Valid from: Sun Mar 11 06:35:00 UTC 2007 until: Wed Mar 08 06:35:00 UTC 2017 +Certificate fingerprints: +Signature algorithm name: SHA1withDSA +Version: 1 + +This can be generated using hacked (update the keytool source code so that +it can be used for version 1 X.509 certificate) keytool command: +% keytool -genkeypair -alias dummy -keyalg DSA -keysize 1024 \ + -sigalg SHA1withDSA \ + -dname "CN=dummy.example.com, OU=Dummy, O=Dummy, L=Cupertino, ST=CA, C=US" \ + -validity 3652 -keypass passphrase -keystore keystore -storepass passphrase + + +truststore entries +================== +This key store contains only trusted certificate entries. The same +certificates are used in both keystore and truststore. + + +unknown_keystore +================ +A keystore you can use when you don't want things to be verified. +Use this with keystore/truststore, and you'll never get a match. diff --git a/jdk/test/javax/net/ssl/etc/keystore b/jdk/test/javax/net/ssl/etc/keystore index 2eb1993f3af..4062e1798c5 100644 Binary files a/jdk/test/javax/net/ssl/etc/keystore and b/jdk/test/javax/net/ssl/etc/keystore differ diff --git a/jdk/test/javax/net/ssl/etc/truststore b/jdk/test/javax/net/ssl/etc/truststore index 65a140d7732..12da39e66a5 100644 Binary files a/jdk/test/javax/net/ssl/etc/truststore and b/jdk/test/javax/net/ssl/etc/truststore differ diff --git a/jdk/test/javax/rmi/TEST.properties b/jdk/test/javax/rmi/TEST.properties new file mode 100644 index 00000000000..d4bbfc905b9 --- /dev/null +++ b/jdk/test/javax/rmi/TEST.properties @@ -0,0 +1 @@ +modules = java.rmi diff --git a/jdk/test/javax/script/ProviderTest.sh b/jdk/test/javax/script/ProviderTest.sh index 1db161dfcf6..24b4120912c 100644 --- a/jdk/test/javax/script/ProviderTest.sh +++ b/jdk/test/javax/script/ProviderTest.sh @@ -43,8 +43,18 @@ $JAR ${TESTTOOLVMOPTS} -cf ${TESTCLASSES}/dummy.jar \ -C ${TESTCLASSES} DummyScriptEngineFactory.class \ -C "${TESTSRC}" META-INF/services/javax.script.ScriptEngineFactory -echo "Running test ..." +echo "Running test with security manager ..." +$JAVA ${TESTVMOPTS} -Djava.security.manager -classpath \ + "${TESTCLASSES}${PS}${TESTCLASSES}/dummy.jar" \ + ProviderTest +ret=$? +if [ $ret -ne 0 ] +then + exit $ret +fi + +echo "Running test without security manager ..." $JAVA ${TESTVMOPTS} -classpath \ "${TESTCLASSES}${PS}${TESTCLASSES}/dummy.jar" \ ProviderTest diff --git a/jdk/test/javax/script/TEST.properties b/jdk/test/javax/script/TEST.properties new file mode 100644 index 00000000000..3bb100c3fad --- /dev/null +++ b/jdk/test/javax/script/TEST.properties @@ -0,0 +1 @@ +modules = java.scripting diff --git a/jdk/test/javax/xml/jaxp/TEST.properties b/jdk/test/javax/xml/jaxp/TEST.properties new file mode 100644 index 00000000000..fbf9f77ec10 --- /dev/null +++ b/jdk/test/javax/xml/jaxp/TEST.properties @@ -0,0 +1 @@ +modules = java.xml diff --git a/jdk/test/lib/testlibrary/CompilerUtils.java b/jdk/test/lib/testlibrary/CompilerUtils.java index 91ca9181340..261c2c8f930 100644 --- a/jdk/test/lib/testlibrary/CompilerUtils.java +++ b/jdk/test/lib/testlibrary/CompilerUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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 @@ -50,13 +50,21 @@ public final class CompilerUtils { * * @return true if the compilation is successful * - * @throws IOException if there is an I/O error scanning the source tree or - * creating the destination directory + * @throws IOException + * if there is an I/O error scanning the source tree or + * creating the destination directory + * @throws UnsupportedOperationException + * if there is no system java compiler */ public static boolean compile(Path source, Path destination, String ... options) throws IOException { JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + if (compiler == null) { + // no compiler available + throw new UnsupportedOperationException("Unable to get system java compiler. " + + "Perhaps, jdk.compiler module is not available."); + } StandardJavaFileManager jfm = compiler.getStandardFileManager(null, null, null); List<Path> sources diff --git a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/ImpactOnSNI.java b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/ImpactOnSNI.java index 4e0f0bdac59..d90d9478e2a 100644 --- a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/ImpactOnSNI.java +++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/ImpactOnSNI.java @@ -235,6 +235,7 @@ public class ImpactOnSNI { hostname); // Ignore the test if the hostname does not sound like a domain name. if ((hostname == null) || hostname.isEmpty() || + !hostname.contains(".") || hostname.endsWith(".") || hostname.startsWith("localhost") || Character.isDigit(hostname.charAt(hostname.length() - 1))) { diff --git a/jdk/test/sun/security/provider/MessageDigest/Offsets.java b/jdk/test/sun/security/provider/MessageDigest/Offsets.java index eaa98fcbd75..44850c2970d 100644 --- a/jdk/test/sun/security/provider/MessageDigest/Offsets.java +++ b/jdk/test/sun/security/provider/MessageDigest/Offsets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, 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 @@ -84,6 +84,10 @@ public class Offsets { test("SHA-256", 0, 64, 0, 128); test("SHA-384", 0, 128, 0, 256); test("SHA-512", 0, 128, 0, 256); + test("SHA3-224", 0, 64, 0, 128); + test("SHA3-256", 0, 64, 0, 128); + test("SHA3-384", 0, 128, 0, 256); + test("SHA3-512", 0, 128, 0, 256); } } diff --git a/jdk/test/sun/security/provider/MessageDigest/TestSHAClone.java b/jdk/test/sun/security/provider/MessageDigest/TestSHAClone.java index f1d1089f39a..ac809153b39 100644 --- a/jdk/test/sun/security/provider/MessageDigest/TestSHAClone.java +++ b/jdk/test/sun/security/provider/MessageDigest/TestSHAClone.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,8 +32,13 @@ import java.util.*; public class TestSHAClone { + // OracleUcrypto provider gets its digest impl from either + // libucrypto (starting S12 with SHA-3 support added) and + // libmd (pre-S12, no SHA-3 at all). + // The impls from libucrypto does not support clone but ones + // from libmd do. private static final String[] ALGOS = { - "SHA", "SHA-224", "SHA-256", "SHA-512", "SHA-384" + "SHA", "SHA-224", "SHA-256", "SHA-384", "SHA-512" }; private static byte[] input1 = { @@ -52,7 +57,13 @@ public class TestSHAClone { private void run() throws Exception { md.update(input1); - MessageDigest md2 = (MessageDigest) md.clone(); + MessageDigest md2; + try { + md2 = (MessageDigest) md.clone(); + } catch (CloneNotSupportedException cnse) { + System.out.println(md.getAlgorithm() + ": clone unsupported"); + return; + } md.update(input2); md2.update(input2); if (!Arrays.equals(md.digest(), md2.digest())) { diff --git a/jdk/src/jdk.jcmd/share/classes/jdk/internal/vm/agent/spi/ToolProviderFinder.java b/jdk/test/sun/security/provider/PolicyFile/BadPolicyFile.java similarity index 51% rename from jdk/src/jdk.jcmd/share/classes/jdk/internal/vm/agent/spi/ToolProviderFinder.java rename to jdk/test/sun/security/provider/PolicyFile/BadPolicyFile.java index b96e6ae6239..17a4c5d8d71 100644 --- a/jdk/src/jdk.jcmd/share/classes/jdk/internal/vm/agent/spi/ToolProviderFinder.java +++ b/jdk/test/sun/security/provider/PolicyFile/BadPolicyFile.java @@ -4,9 +4,7 @@ * * 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. + * 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 @@ -23,24 +21,31 @@ * questions. */ -package jdk.internal.vm.agent.spi; +/* + * @test + * @bug 8150468 + * @summary check that a badly formatted policy file is handled correctly + * @run main/othervm BadPolicyFile + */ -import java.lang.reflect.Layer; -import java.util.HashMap; -import java.util.Map; -import java.util.ServiceLoader; +import java.io.File; +import java.net.URI; +import java.security.AccessControlException; +import java.security.Policy; +import java.security.URIParameter; -public final class ToolProviderFinder { - private static final Map<String, ToolProvider> providers = init(); +public class BadPolicyFile { - public static ToolProvider find(String name) { - return providers.get(name); - } - - private static Map<String, ToolProvider> init() { - Map<String, ToolProvider> providers = new HashMap<>(); - ServiceLoader.load(Layer.boot(), ToolProvider.class) - .forEach(p -> providers.putIfAbsent(p.getName(), p)); - return providers; + public static void main(String[] args) throws Exception { + URI uri = new File(System.getProperty("test.src", "."), + "BadPolicyFile.policy").toURI(); + Policy.setPolicy(Policy.getInstance("JavaPolicy", new URIParameter(uri))); + System.setSecurityManager(new SecurityManager()); + try { + String javahome = System.getProperty("java.home"); + throw new Exception("Expected AccessControlException"); + } catch (AccessControlException ace) { + System.out.println("Test PASSED"); + } } } diff --git a/jdk/test/sun/security/provider/PolicyFile/BadPolicyFile.policy b/jdk/test/sun/security/provider/PolicyFile/BadPolicyFile.policy new file mode 100644 index 00000000000..b5abfaf8f42 --- /dev/null +++ b/jdk/test/sun/security/provider/PolicyFile/BadPolicyFile.policy @@ -0,0 +1,4 @@ +grant { + // permission statement is missing trailing semi-colon + permission "java.util.PropertyPermission" "java.home", "read" +}; diff --git a/jdk/test/sun/security/rsa/SignatureTest.java b/jdk/test/sun/security/rsa/SignatureTest.java index 0eed4ec1e5f..ef34786977b 100644 --- a/jdk/test/sun/security/rsa/SignatureTest.java +++ b/jdk/test/sun/security/rsa/SignatureTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2016, 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,9 +39,9 @@ import java.security.spec.RSAPrivateKeySpec; import java.security.spec.RSAPublicKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Arrays; +import java.util.stream.IntStream; import static javax.crypto.Cipher.PRIVATE_KEY; import static javax.crypto.Cipher.PUBLIC_KEY; -import jdk.testlibrary.RandomFactory; /** * @test @@ -49,36 +49,13 @@ import jdk.testlibrary.RandomFactory; * @summary Create a signature for RSA and get its signed data. re-initiate * the signature with the public key. The signature can be verified * by acquired signed data. - * @key randomness - * @library ../../../lib/testlibrary - * @run main SignatureTest MD2withRSA 512 - * @run main SignatureTest MD5withRSA 512 - * @run main SignatureTest SHA1withRSA 512 - * @run main SignatureTest SHA256withRSA 512 - * @run main SignatureTest MD2withRSA 768 - * @run main SignatureTest MD5withRSA 768 - * @run main SignatureTest SHA1withRSA 768 - * @run main SignatureTest SHA256withRSA 768 - * @run main SignatureTest MD2withRSA 1024 - * @run main SignatureTest MD5withRSA 1024 - * @run main SignatureTest SHA1withRSA 1024 - * @run main SignatureTest SHA256withRSA 1024 - * @run main SignatureTest MD2withRSA 2048 - * @run main SignatureTest MD5withRSA 2048 - * @run main SignatureTest SHA1withRSA 2048 - * @run main SignatureTest SHA256withRSA 2048 - * @run main/timeout=240 SignatureTest MD2withRSA 4096 - * @run main/timeout=240 SignatureTest MD5withRSA 4096 - * @run main/timeout=240 SignatureTest SHA1withRSA 4096 - * @run main/timeout=240 SignatureTest SHA256withRSA 4096 - * @run main/timeout=240 SignatureTest MD2withRSA 5120 - * @run main/timeout=240 SignatureTest MD5withRSA 5120 - * @run main/timeout=240 SignatureTest SHA1withRSA 5120 - * @run main/timeout=240 SignatureTest SHA256withRSA 5120 - * @run main/timeout=240 SignatureTest MD2withRSA 6144 - * @run main/timeout=240 SignatureTest MD5withRSA 6144 - * @run main/timeout=240 SignatureTest SHA1withRSA 6144 - * @run main/timeout=240 SignatureTest SHA256withRSA 6144 + * @run main SignatureTest 512 + * @run main SignatureTest 768 + * @run main SignatureTest 1024 + * @run main SignatureTest 2048 + * @run main/timeout=240 SignatureTest 4096 + * @run main/timeout=240 SignatureTest 5120 + * @run main/timeout=240 SignatureTest 6144 */ public class SignatureTest { /** @@ -101,12 +78,19 @@ public class SignatureTest { */ private static final int UPDATE_TIMES_HUNDRED = 100; + /** + * Signature algorithms to test + */ + private static final String[] SIGN_ALG = {"MD2withRSA", "MD5withRSA", + "SHA1withRSA", "SHA256withRSA"}; + public static void main(String[] args) throws Exception { - String testAlg = args[0]; - int testSize = Integer.parseInt(args[1]); + int testSize = Integer.parseInt(args[0]); byte[] data = new byte[100]; - RandomFactory.getRandom().nextBytes(data); + IntStream.range(0, data.length).forEach(j -> { + data[j] = (byte) j; + }); // create a key pair KeyPair kpair = generateKeys(KEYALG, testSize); @@ -115,16 +99,17 @@ public class SignatureTest { // For signature algorithm, create and verify a signature Arrays.stream(privs).forEach(priv - -> Arrays.stream(pubs).forEach(pub -> { - try { - checkSignature(data, (PublicKey) pub, (PrivateKey) priv, - testAlg); - } catch (NoSuchAlgorithmException | InvalidKeyException - | SignatureException | NoSuchProviderException ex) { - throw new RuntimeException(ex); - } - } - )); + -> Arrays.stream(pubs).forEach(pub + -> Arrays.stream(SIGN_ALG).forEach(testAlg -> { + try { + checkSignature(data, (PublicKey) pub, (PrivateKey) priv, + testAlg); + } catch (NoSuchAlgorithmException | InvalidKeyException | + SignatureException | NoSuchProviderException ex) { + throw new RuntimeException(ex); + } + } + ))); } diff --git a/jdk/test/sun/security/x509/AlgorithmId/OidTableInit.java b/jdk/test/sun/security/x509/AlgorithmId/OidTableInit.java new file mode 100644 index 00000000000..779ddba6eb3 --- /dev/null +++ b/jdk/test/sun/security/x509/AlgorithmId/OidTableInit.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2016 Google Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8156584 + * @modules java.base/sun.security.x509 + * @summary AlgorithmId.get initialization thread safety + * @run main/othervm OidTableInit + */ + +import java.util.ArrayList; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import sun.security.x509.AlgorithmId; + +public class OidTableInit { + public static void main(String[] args) throws Throwable { + final String[] algorithmNames = { + "PBKDF2WITHHMACSHA1", + "PBEWITHMD5ANDDES", + "DSA", + "SHA384WITHRSA", + "RSA", + "SHA1WITHDSA", + "SHA512WITHRSA", + "MD2WITHRSA", + "PBEWITHSHA1ANDDESEDE", + "SHA1WITHRSA", + "DIFFIEHELLMAN", + "MD5WITHRSA", + "PBEWITHSHA1ANDRC2_40", + "SHA256WITHRSA", + }; + + final int THREADS = 2; + final ExecutorService pool = Executors.newFixedThreadPool(THREADS); + final CountDownLatch startingGate = new CountDownLatch(THREADS); + final Runnable r = new Runnable() { public void run() { + startingGate.countDown(); + do {} while (startingGate.getCount() > 0); + try { + for (String algorithmName : algorithmNames) + AlgorithmId.get(algorithmName); + } catch (Throwable fail) { + throw new AssertionError(fail); + } + }}; + final ArrayList<Future<?>> futures = new ArrayList<>(); + for (int i = 0; i < THREADS; i++) + futures.add(pool.submit(r)); + pool.shutdown(); + for (Future<?> future : futures) future.get(); + } +} diff --git a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java index afba30c6055..b0f3b8d4f73 100644 --- a/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java +++ b/jdk/test/sun/tools/jhsdb/BasicLauncherTest.java @@ -31,9 +31,12 @@ * @run main BasicLauncherTest */ +import static jdk.testlibrary.Asserts.assertTrue; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Arrays; @@ -99,7 +102,7 @@ public class BasicLauncherTest { System.out.println("Starting LingeredApp"); try { - theApp = LingeredApp.startApp(); + theApp = LingeredApp.startApp(Arrays.asList("-Xmx256m")); System.out.println("Starting " + toolName + " " + toolArgs.get(0) + " against " + theApp.getPid()); JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK(toolName); @@ -129,6 +132,21 @@ public class BasicLauncherTest { launch(expectedMessage, Arrays.asList(toolArgs)); } + public static void testHeapDump() throws IOException { + File dump = new File("jhsdb.jmap.dump." + + System.currentTimeMillis() + ".hprof"); + if (dump.exists()) { + dump.delete(); + } + dump.deleteOnExit(); + + launch("heap written to", "jmap", + "--binaryheap", "--dumpfile=" + dump.getAbsolutePath()); + + assertTrue(dump.exists() && dump.isFile(), + "Could not create dump file " + dump.getAbsolutePath()); + } + public static void main(String[] args) throws IOException { @@ -145,6 +163,8 @@ public class BasicLauncherTest { launch("Java System Properties", "jinfo"); launch("java.threads", "jsnap"); + testHeapDump(); + // The test throws RuntimeException on error. // IOException is thrown if LingeredApp can't start because of some bad // environment condition diff --git a/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java b/jdk/test/sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java similarity index 98% rename from jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java rename to jdk/test/sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java index 5a84b6261d6..c768dd6eb01 100644 --- a/jdk/test/sun/tools/jmap/heapconfig/JMapHeapConfigTest.java +++ b/jdk/test/sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java @@ -36,9 +36,9 @@ import jdk.testlibrary.Platform; * @test * @bug 8042397 * @summary Unit test for jmap utility test heap configuration reader + * @modules jdk.hotspot.agent/sun.jvm.hotspot * @library /test/lib/share/classes * @library /lib/testlibrary - * @modules java.management * @build jdk.testlibrary.* * @build jdk.test.lib.apps.* * @build JMapHeapConfigTest TmtoolTestScenario @@ -149,7 +149,7 @@ public class JMapHeapConfigTest { } cmd.add("-XX:+PrintFlagsFinal"); - TmtoolTestScenario tmt = TmtoolTestScenario.create("jmap", "-heap"); + TmtoolTestScenario tmt = TmtoolTestScenario.create("jmap", "--heap"); int exitcode = tmt.launch(cmd); if (exitcode != 0) { throw new RuntimeException("Test FAILED jmap exits with non zero exit code " + exitcode); diff --git a/jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java b/jdk/test/sun/tools/jhsdb/heapconfig/TmtoolTestScenario.java similarity index 97% rename from jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java rename to jdk/test/sun/tools/jhsdb/heapconfig/TmtoolTestScenario.java index 4558f3e346b..25beea66f72 100644 --- a/jdk/test/sun/tools/jmap/heapconfig/TmtoolTestScenario.java +++ b/jdk/test/sun/tools/jhsdb/heapconfig/TmtoolTestScenario.java @@ -100,11 +100,13 @@ public class TmtoolTestScenario { theApp = LingeredApp.startApp(vmArgsExtended); System.out.println("Starting " + toolName + " against " + theApp.getPid()); - JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK(toolName); + JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jhsdb"); + launcher.addToolArg(toolName); for (String cmd : toolArgs) { launcher.addToolArg(cmd); } + launcher.addToolArg("--pid"); launcher.addToolArg(Long.toString(theApp.getPid())); ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand()); diff --git a/jdk/test/sun/tools/jinfo/JInfoHelper.java b/jdk/test/sun/tools/jinfo/BasicJInfoTest.java similarity index 51% rename from jdk/test/sun/tools/jinfo/JInfoHelper.java rename to jdk/test/sun/tools/jinfo/BasicJInfoTest.java index 7f945136b4f..c612652f46b 100644 --- a/jdk/test/sun/tools/jinfo/JInfoHelper.java +++ b/jdk/test/sun/tools/jinfo/BasicJInfoTest.java @@ -1,12 +1,10 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, 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. + * 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 @@ -29,41 +27,58 @@ import jdk.testlibrary.JDKToolLauncher; import jdk.testlibrary.OutputAnalyzer; import jdk.testlibrary.ProcessTools; -/** - * The helper class for running jinfo utility. +/* + * @test + * @summary Unit test for jinfo utility + * @library /lib/testlibrary + * @build jdk.testlibrary.* + * @run main BasicJInfoTest */ -public final class JInfoHelper { +public class BasicJInfoTest { - /** - * Print configuration information for the current process - * - * @param toolArgs List of jinfo options - */ - public static OutputAnalyzer jinfo(String... toolArgs) throws Exception { - return jinfo(true, toolArgs); + private static ProcessBuilder processBuilder = new ProcessBuilder(); + + public static void main(String[] args) throws Exception { + testJinfoNoArgs(); + testJinfoFlags(); + testJinfoProps(); + testJinfoFlagInvalid(); } - /** - * Print usage information - * - * @param toolArgs List of jinfo options - */ - public static OutputAnalyzer jinfoNoPid(String... toolArgs) throws Exception { - return jinfo(false, toolArgs); + private static void testJinfoNoArgs() throws Exception { + OutputAnalyzer output = jinfo(); + output.shouldContain("-XX"); + output.shouldContain("test.jdk="); + output.shouldHaveExitValue(0); } - private static OutputAnalyzer jinfo(boolean toPid, String... toolArgs) throws Exception { + private static void testJinfoFlagInvalid() throws Exception { + OutputAnalyzer output = jinfo("-flag"); + output.shouldHaveExitValue(1); + } + + private static void testJinfoFlags() throws Exception { + OutputAnalyzer output = jinfo("-flags"); + output.shouldContain("-XX"); + output.shouldHaveExitValue(0); + } + + private static void testJinfoProps() throws Exception { + OutputAnalyzer output = jinfo("-props"); + output.shouldContain("test.jdk="); + output.shouldHaveExitValue(0); + } + + private static OutputAnalyzer jinfo(String... toolArgs) throws Exception { JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jinfo"); if (toolArgs != null) { for (String toolArg : toolArgs) { launcher.addToolArg(toolArg); } } - if (toPid) { - launcher.addToolArg(Long.toString(ProcessTools.getProcessId())); - } + launcher.addToolArg(Long.toString(ProcessTools.getProcessId())); - ProcessBuilder processBuilder = new ProcessBuilder(launcher.getCommand()); + processBuilder.command(launcher.getCommand()); System.out.println(Arrays.toString(processBuilder.command().toArray()).replace(",", "")); OutputAnalyzer output = ProcessTools.executeProcess(processBuilder); System.out.println(output.getOutput()); diff --git a/jdk/test/sun/tools/jinfo/JInfoLauncherTest.java b/jdk/test/sun/tools/jinfo/JInfoLauncherTest.java deleted file mode 100644 index 09b4750d778..00000000000 --- a/jdk/test/sun/tools/jinfo/JInfoLauncherTest.java +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (c) 2014, 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. - */ - -import org.testng.annotations.Test; -import org.testng.annotations.BeforeClass; -import sun.tools.jinfo.JInfo; - -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.util.Arrays; - -import static org.testng.Assert.*; - -/** - * @test - * @bug 8039080 - * @modules jdk.jcmd/sun.tools.jinfo - * @run testng JInfoLauncherTest - * @summary Test JInfo launcher argument parsing - */ -@Test -public class JInfoLauncherTest { - public static final String VALIDATION_EXCEPTION_CLSNAME = - IllegalArgumentException.class.getName(); - - private Constructor<JInfo> jInfoConstructor; - private Field fldUseSA; - - @BeforeClass - public void setup() throws Exception { - jInfoConstructor = JInfo.class.getDeclaredConstructor(String[].class); - jInfoConstructor.setAccessible(true); - fldUseSA = JInfo.class.getDeclaredField("useSA"); - fldUseSA.setAccessible(true); - } - - private JInfo newJInfo(String[] args) throws Exception { - try { - return jInfoConstructor.newInstance((Object) args); - } catch (Exception e) { - if (isValidationException(e.getCause())) { - throw (Exception)e.getCause(); - } - throw e; - } - } - - private boolean getUseSA(JInfo jinfo) throws Exception { - return fldUseSA.getBoolean(jinfo); - } - - private void cmdPID(String cmd, String ... params) throws Exception { - int offset = (cmd != null ? 1 : 0); - String[] args = new String[offset + params.length]; - args[0] = cmd; - System.arraycopy(params, 0, args, offset, params.length); - JInfo j = newJInfo(args); - assertFalse(getUseSA(j), "Local jinfo must not forward to SA"); - } - - private void cmdCore(String cmd, String ... params) throws Exception { - int offset = (cmd != null ? 1 : 0); - String[] args = new String[offset + params.length]; - args[0] = cmd; - System.arraycopy(params, 0, args, offset, params.length); - JInfo j = newJInfo(args); - assertTrue(getUseSA(j), "Core jinfo must forward to SA"); - } - - private void cmdRemote(String cmd, String ... params) throws Exception { - int offset = (cmd != null ? 1 : 0); - String[] args = new String[offset + params.length]; - args[0] = cmd; - System.arraycopy(params, 0, args, offset, params.length); - JInfo j = newJInfo(args); - assertTrue(getUseSA(j), "Remote jinfo must forward to SA"); - } - - private void cmdExtraArgs(String cmd, int argsLen) throws Exception { - String[] args = new String[argsLen + 1 + (cmd != null ? 1 : 0)]; - Arrays.fill(args, "a"); - if (cmd != null) { - args[0] = cmd; - } else { - cmd = "default"; - } - try { - JInfo j = newJInfo(args); - fail("\"" + cmd + "\" does not support more than " + argsLen + - " arguments"); - } catch (Exception e) { - if (!isValidationException(e)) { - throw e; - } - // ignore - } - } - - private void cmdMissingArgs(String cmd, int reqArgs) throws Exception { - String[] args = new String[reqArgs - 1 + (cmd != null ? 1 : 0)]; - Arrays.fill(args, "a"); - if (cmd != null) { - args[0] = cmd; - } else { - cmd = "default"; - } - try { - JInfo j = newJInfo(args); - fail("\"" + cmd + "\" requires at least " + reqArgs + " argument"); - } catch (Exception e) { - if (!isValidationException(e)) { - throw e; - } - // ignore - } - } - - public void testDefaultPID() throws Exception { - cmdPID(null, "1234"); - } - - public void testFlagsPID() throws Exception { - cmdPID("-flags", "1234"); - } - - public void testSyspropsPID() throws Exception { - cmdPID("-sysprops", "1234"); - } - - public void testReadFlagPID() throws Exception { - cmdPID("-flag", "SomeManagementFlag", "1234"); - } - - public void testSetFlag1PID() throws Exception { - cmdPID("-flag", "+SomeManagementFlag", "1234"); - } - - public void testSetFlag2PID() throws Exception { - cmdPID("-flag", "-SomeManagementFlag", "1234"); - } - - public void testSetFlag3PID() throws Exception { - cmdPID("-flag", "SomeManagementFlag=314", "1234"); - } - - public void testDefaultCore() throws Exception { - cmdCore(null, "myapp.exe", "my.core"); - } - - public void testFlagsCore() throws Exception { - cmdCore("-flags", "myapp.exe", "my.core"); - } - - public void testSyspropsCore() throws Exception { - cmdCore("-sysprops", "myapp.exe", "my.core"); - } - - public void testReadFlagCore() throws Exception { - try { - cmdCore("-flag", "SomeManagementFlag", "myapp.exe", "my.core"); - fail("Flags can not be read from core files"); - } catch (Exception e) { - if (!isValidationException(e)) { - throw e; - } - // ignore - } - } - - public void testSetFlag1Core() throws Exception { - try { - cmdCore("-flag", "+SomeManagementFlag", "myapp.exe", "my.core"); - fail("Flags can not be set in core files"); - } catch (Exception e) { - if (!isValidationException(e)) { - throw e; - } - // ignore - } - } - - public void testSetFlag2Core() throws Exception { - try { - cmdCore("-flag", "-SomeManagementFlag", "myapp.exe", "my.core"); - fail("Flags can not be set in core files"); - } catch (Exception e) { - if (!isValidationException(e)) { - throw e; - } - // ignore - } - } - - public void testSetFlag3Core() throws Exception { - try { - cmdCore("-flag", "SomeManagementFlag=314", "myapp.exe", "my.core"); - fail("Flags can not be set in core files"); - } catch (Exception e) { - if (!isValidationException(e)) { - throw e; - } - // ignore - } - } - - public void testDefaultRemote() throws Exception { - cmdRemote(null, "serverid@host"); - } - - public void testFlagsRemote() throws Exception { - cmdRemote("-flags", "serverid@host"); - } - - public void testSyspropsRemote() throws Exception { - cmdRemote("-sysprops", "serverid@host"); - } - - public void testReadFlagRemote() throws Exception { - try { - cmdCore("-flag", "SomeManagementFlag", "serverid@host"); - fail("Flags can not be read from SA server"); - } catch (Exception e) { - if (!isValidationException(e)) { - throw e; - } - // ignore - } - } - - public void testSetFlag1Remote() throws Exception { - try { - cmdCore("-flag", "+SomeManagementFlag","serverid@host"); - fail("Flags can not be set on SA server"); - } catch (Exception e) { - if (!isValidationException(e)) { - throw e; - } - // ignore - } - } - - public void testSetFlag2Remote() throws Exception { - try { - cmdCore("-flag", "-SomeManagementFlag", "serverid@host"); - fail("Flags can not be read set on SA server"); - } catch (Exception e) { - if (!isValidationException(e)) { - throw e; - } - // ignore - } - } - - public void testSetFlag3Remote() throws Exception { - try { - cmdCore("-flag", "SomeManagementFlag=314", "serverid@host"); - fail("Flags can not be read set on SA server"); - } catch (Exception e) { - if (!isValidationException(e)) { - throw e; - } - // ignore - } - } - - public void testDefaultExtraArgs() throws Exception { - cmdExtraArgs(null, 2); - } - - public void testFlagsExtraArgs() throws Exception { - cmdExtraArgs("-flags", 2); - } - - public void testSyspropsExtraArgs() throws Exception { - cmdExtraArgs("-sysprops", 2); - } - - public void testFlagExtraArgs() throws Exception { - cmdExtraArgs("-flag", 2); - } - - public void testHelp1ExtraArgs() throws Exception { - cmdExtraArgs("-h", 0); - } - - public void testHelp2ExtraArgs() throws Exception { - cmdExtraArgs("-help", 0); - } - - public void testDefaultMissingArgs() throws Exception { - cmdMissingArgs(null, 1); - } - - public void testFlagsMissingArgs() throws Exception { - cmdMissingArgs("-flags", 1); - } - - public void testSyspropsMissingArgs() throws Exception { - cmdMissingArgs("-sysprops", 1); - } - - public void testFlagMissingArgs() throws Exception { - cmdMissingArgs("-flag", 2); - } - - public void testUnknownCommand() throws Exception { - try { - JInfo j = newJInfo(new String[]{"-unknown_command"}); - fail("JInfo accepts unknown commands"); - } catch (Exception e) { - if (!isValidationException(e)) { - throw e; - } - // ignore - } - } - - private static boolean isValidationException(Throwable e) { - return e.getClass().getName().equals(VALIDATION_EXCEPTION_CLSNAME); - } -} diff --git a/jdk/test/sun/tools/jinfo/JInfoRunningProcessFlagTest.java b/jdk/test/sun/tools/jinfo/JInfoRunningProcessFlagTest.java deleted file mode 100644 index cb28cc7a49f..00000000000 --- a/jdk/test/sun/tools/jinfo/JInfoRunningProcessFlagTest.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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. - */ - -import java.lang.management.ManagementFactory; -import com.sun.management.HotSpotDiagnosticMXBean; -import jdk.testlibrary.OutputAnalyzer; -import static jdk.testlibrary.Platform.isSolaris; -import static jdk.testlibrary.Asserts.assertEquals; -import static jdk.testlibrary.Asserts.assertNotEquals; -import static jdk.testlibrary.Asserts.assertTrue; - -/** - * @test - * @summary The test sanity checks 'jinfo -flag' option. - * @library /lib/testlibrary - * @modules java.management - * @build jdk.testlibrary.* JInfoHelper - * @run main/othervm -XX:+HeapDumpOnOutOfMemoryError JInfoRunningProcessFlagTest - */ -public class JInfoRunningProcessFlagTest { - - public static void main(String[] args) throws Exception { - testFlag(); - testFlagPlus(); - testFlagMinus(); - testFlagEqual(); - - testInvalidFlag(); - - testSolarisSpecificFlag(); - } - - private static void testFlag() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfo("-flag", "HeapDumpOnOutOfMemoryError"); - output.shouldHaveExitValue(0); - assertTrue(output.getStderr().isEmpty(), "'jinfo -flag HeapDumpOnOutOfMemoryError' stderr should be empty"); - output.shouldContain("+HeapDumpOnOutOfMemoryError"); - } - - private static void testFlagPlus() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfo("-flag", "+HeapDumpOnOutOfMemoryError"); - output.shouldHaveExitValue(0); - output = JInfoHelper.jinfo("-flag", "HeapDumpOnOutOfMemoryError"); - output.shouldHaveExitValue(0); - output.shouldContain("+HeapDumpOnOutOfMemoryError"); - verifyIsEnabled("HeapDumpOnOutOfMemoryError"); - } - - private static void testFlagMinus() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfo("-flag", "-HeapDumpOnOutOfMemoryError"); - output.shouldHaveExitValue(0); - output = JInfoHelper.jinfo("-flag", "HeapDumpOnOutOfMemoryError"); - output.shouldHaveExitValue(0); - output.shouldContain("-HeapDumpOnOutOfMemoryError"); - verifyIsDisabled("HeapDumpOnOutOfMemoryError"); - } - - private static void testFlagEqual() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfo("-flag", "HeapDumpOnOutOfMemoryError=1"); - output.shouldHaveExitValue(0); - output = JInfoHelper.jinfo("-flag", "HeapDumpOnOutOfMemoryError"); - output.shouldHaveExitValue(0); - output.shouldContain("+HeapDumpOnOutOfMemoryError"); - verifyIsEnabled("HeapDumpOnOutOfMemoryError"); - } - - private static void testInvalidFlag() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfo("-flag", "monkey"); - assertNotEquals(output.getExitValue(), 0, "A non-zero exit code should be returned for invalid flag"); - } - - private static void testSolarisSpecificFlag() throws Exception { - if (!isSolaris()) - return; - - OutputAnalyzer output = JInfoHelper.jinfo("-flag", "+ExtendedDTraceProbes"); - output.shouldHaveExitValue(0); - output = JInfoHelper.jinfo(); - output.shouldContain("+ExtendedDTraceProbes"); - verifyIsEnabled("ExtendedDTraceProbes"); - - output = JInfoHelper.jinfo("-flag", "-ExtendedDTraceProbes"); - output.shouldHaveExitValue(0); - output = JInfoHelper.jinfo(); - output.shouldContain("-ExtendedDTraceProbes"); - verifyIsDisabled("ExtendedDTraceProbes"); - - output = JInfoHelper.jinfo("-flag", "ExtendedDTraceProbes"); - output.shouldContain("-ExtendedDTraceProbes"); - output.shouldHaveExitValue(0); - } - - private static void verifyIsEnabled(String flag) { - HotSpotDiagnosticMXBean hotspotDiagnostic = - ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); - String flagValue = hotspotDiagnostic.getVMOption(flag).getValue(); - assertEquals(flagValue, "true", "Expected '" + flag + "' flag be enabled"); - } - - private static void verifyIsDisabled(String flag) { - HotSpotDiagnosticMXBean hotspotDiagnostic = - ManagementFactory.getPlatformMXBean(HotSpotDiagnosticMXBean.class); - String flagValue = hotspotDiagnostic.getVMOption(flag).getValue(); - assertEquals(flagValue, "false", "Expected '" + flag + "' flag be disabled"); - } - -} diff --git a/jdk/test/sun/tools/jinfo/JInfoRunningProcessTest.java b/jdk/test/sun/tools/jinfo/JInfoRunningProcessTest.java deleted file mode 100644 index 633a2c99b51..00000000000 --- a/jdk/test/sun/tools/jinfo/JInfoRunningProcessTest.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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. - */ - -import jdk.testlibrary.OutputAnalyzer; -import static jdk.testlibrary.Asserts.assertTrue; - -/** - * @test - * @summary The test sanity checks functionality of 'jinfo', 'jinfo -sysprops' and 'jinfo -flags' - * @library /lib/testlibrary - * @modules java.management - * @build jdk.testlibrary.* JInfoHelper - * @run main/othervm -XX:+HeapDumpOnOutOfMemoryError JInfoRunningProcessTest - */ -public class JInfoRunningProcessTest { - - public static void main(String[] args) throws Exception { - testNoOptions(); - testSysprops(); - testFlags(); - } - - private static void testNoOptions() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfo(); - output.shouldHaveExitValue(0); - assertTrue(output.getStderr().isEmpty(), "'jinfo' stderr should be empty"); - output.shouldContain("+HeapDumpOnOutOfMemoryError"); - } - - private static void testSysprops() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfo("-sysprops"); - output.shouldHaveExitValue(0); - assertTrue(output.getStderr().isEmpty(), "'jinfo -sysprops' stderr should be empty"); - } - - private static void testFlags() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfo("-flags"); - output.shouldHaveExitValue(0); - assertTrue(output.getStderr().isEmpty(), "'jinfo -flags' stderr should be empty"); - output.shouldContain("+HeapDumpOnOutOfMemoryError"); - } - -} diff --git a/jdk/test/sun/tools/jinfo/JInfoSanityTest.java b/jdk/test/sun/tools/jinfo/JInfoSanityTest.java deleted file mode 100644 index 9b0bcf1b141..00000000000 --- a/jdk/test/sun/tools/jinfo/JInfoSanityTest.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2014, 2015, 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. - */ - -import static jdk.testlibrary.Asserts.assertNotEquals; -import static jdk.testlibrary.Asserts.assertTrue; -import static jdk.testlibrary.Asserts.assertFalse; -import jdk.testlibrary.OutputAnalyzer; - -/** - * @test - * @summary The test sanity checks functionality of 'jinfo -h', 'jinfo -help', - * and verifies jinfo exits abnormally if started with invalid options. - * @library /lib/testlibrary - * @modules java.management - * @build jdk.testlibrary.* JInfoHelper - * @run main JInfoSanityTest - */ -public class JInfoSanityTest { - - public static void main(String[] args) throws Exception { - test_h(); - test_help(); - testVersion(); - testUnknownHost(); - } - - private static void test_h() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfoNoPid("-h"); - output.shouldHaveExitValue(0); - assertFalse(output.getStderr().isEmpty(), "'jinfo -h' stderr should not be empty"); - assertTrue(output.getStdout().isEmpty(), "'jinfo -h' stdout should be empty"); - } - - private static void test_help() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfoNoPid("-help"); - output.shouldHaveExitValue(0); - assertFalse(output.getStderr().isEmpty(), "'jinfo -help' stderr should not be empty"); - assertTrue(output.getStdout().isEmpty(), "'jinfo -help' stdout should be empty"); - } - - private static void testVersion() throws Exception { - OutputAnalyzer output = JInfoHelper.jinfoNoPid("-version"); - output.shouldHaveExitValue(1); - assertFalse(output.getStderr().isEmpty(), "'jinfo -version' stderr should not be empty"); - assertTrue(output.getStdout().isEmpty(), "'jinfo -version' stdout should be empty"); - } - - private static void testUnknownHost() throws Exception { - String unknownHost = "Oja781nh2ev7vcvbajdg-Sda1-C"; - OutputAnalyzer output = JInfoHelper.jinfoNoPid("med@" + unknownHost); - assertNotEquals(output.getExitValue(), 0, "A non-zero exit code should be returned for invalid operation"); - output.shouldMatch(".*(Connection refused to host\\:|UnknownHostException\\:) " + unknownHost + ".*"); - } - -} diff --git a/jdk/test/sun/tools/jmap/BasicJMapTest.java b/jdk/test/sun/tools/jmap/BasicJMapTest.java index 75c80a2eec3..fa333cddea7 100644 --- a/jdk/test/sun/tools/jmap/BasicJMapTest.java +++ b/jdk/test/sun/tools/jmap/BasicJMapTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, 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,12 +34,10 @@ import jdk.testlibrary.ProcessTools; /* * @test - * @bug 6321286 * @summary Unit test for jmap utility * @key intermittent * @library /lib/testlibrary * @library /test/lib/share/classes - * @modules java.management * @build jdk.testlibrary.* * @build jdk.test.lib.hprof.* * @build jdk.test.lib.hprof.model.* @@ -54,6 +52,8 @@ public class BasicJMapTest { public static void main(String[] args) throws Exception { testHisto(); testHistoLive(); + testFinalizerInfo(); + testClstats(); testDump(); testDumpLive(); } @@ -68,6 +68,16 @@ public class BasicJMapTest { output.shouldHaveExitValue(0); } + private static void testFinalizerInfo() throws Exception { + OutputAnalyzer output = jmap("-finalizerinfo"); + output.shouldHaveExitValue(0); + } + + private static void testClstats() throws Exception { + OutputAnalyzer output = jmap("-clstats"); + output.shouldHaveExitValue(0); + } + private static void testDump() throws Exception { dump(false); } @@ -105,7 +115,6 @@ public class BasicJMapTest { private static OutputAnalyzer jmap(String... toolArgs) throws Exception { JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jmap"); - launcher.addVMArg("-XX:+UsePerfData"); if (toolArgs != null) { for (String toolArg : toolArgs) { launcher.addToolArg(toolArg); diff --git a/jdk/test/sun/tools/jstack/BasicJStackTest.java b/jdk/test/sun/tools/jstack/BasicJStackTest.java index 9fd0b66b578..997876a54c5 100644 --- a/jdk/test/sun/tools/jstack/BasicJStackTest.java +++ b/jdk/test/sun/tools/jstack/BasicJStackTest.java @@ -29,10 +29,8 @@ import jdk.testlibrary.ProcessTools; /* * @test - * @bug 6260070 * @summary Unit test for jstack utility * @library /lib/testlibrary - * @modules java.management * @build jdk.testlibrary.* * @run main BasicJStackTest */ diff --git a/jdk/test/sun/tools/jstack/DeadlockDetectionTest.java b/jdk/test/sun/tools/jstack/DeadlockDetectionTest.java index 4ff2508673b..771fd128ff7 100644 --- a/jdk/test/sun/tools/jstack/DeadlockDetectionTest.java +++ b/jdk/test/sun/tools/jstack/DeadlockDetectionTest.java @@ -39,7 +39,6 @@ import jdk.testlibrary.ProcessTools; * @summary Test deadlock detection * @library /test/lib/share/classes * @library /lib/testlibrary - * @modules java.management * @build jdk.testlibrary.* * @build jdk.test.lib.apps.* * @build DeadlockDetectionTest diff --git a/jdk/test/sun/util/logging/PlatformLoggerTest.java b/jdk/test/sun/util/logging/PlatformLoggerTest.java index 530a2acea8a..4fbf0c95c2d 100644 --- a/jdk/test/sun/util/logging/PlatformLoggerTest.java +++ b/jdk/test/sun/util/logging/PlatformLoggerTest.java @@ -31,7 +31,6 @@ * * @modules java.base/sun.util.logging * java.logging/sun.util.logging.internal - * @compile -XDignore.symbol.file PlatformLoggerTest.java * @run main/othervm PlatformLoggerTest */ @@ -42,25 +41,31 @@ import sun.util.logging.PlatformLogger; import static sun.util.logging.PlatformLogger.Level.*; public class PlatformLoggerTest { + + static Logger logger; + static PlatformLogger bar; + static PlatformLogger goo; + static PlatformLogger foo; + public static void main(String[] args) throws Exception { final String FOO_PLATFORM_LOGGER = "test.platformlogger.foo"; final String BAR_PLATFORM_LOGGER = "test.platformlogger.bar"; final String GOO_PLATFORM_LOGGER = "test.platformlogger.goo"; final String BAR_LOGGER = "test.logger.bar"; - PlatformLogger goo = PlatformLogger.getLogger(GOO_PLATFORM_LOGGER); + goo = PlatformLogger.getLogger(GOO_PLATFORM_LOGGER); // test the PlatformLogger methods testLogMethods(goo); // Create a platform logger using the default - PlatformLogger foo = PlatformLogger.getLogger(FOO_PLATFORM_LOGGER); + foo = PlatformLogger.getLogger(FOO_PLATFORM_LOGGER); checkPlatformLogger(foo, FOO_PLATFORM_LOGGER); // create a java.util.logging.Logger // now java.util.logging.Logger should be created for each platform logger - Logger logger = Logger.getLogger(BAR_LOGGER); + logger = Logger.getLogger(BAR_LOGGER); logger.setLevel(Level.WARNING); - PlatformLogger bar = PlatformLogger.getLogger(BAR_PLATFORM_LOGGER); + bar = PlatformLogger.getLogger(BAR_PLATFORM_LOGGER); checkPlatformLogger(bar, BAR_PLATFORM_LOGGER); // test the PlatformLogger methods diff --git a/jdk/test/tools/jimage/VerifyJimage.java b/jdk/test/tools/jimage/VerifyJimage.java index 9c33cc3fa74..5056e6322a5 100644 --- a/jdk/test/tools/jimage/VerifyJimage.java +++ b/jdk/test/tools/jimage/VerifyJimage.java @@ -188,7 +188,11 @@ public class VerifyJimage { String cn = removeModule(n).replaceAll("\\.class$", "").replace('/', '.'); count.incrementAndGet(); try { + System.out.println("Loading " + cn); Class.forName(cn, false, loader); + } catch (VerifyError ve) { + System.err.println("VerifyError for " + cn); + failed.add(reader.imageName() + ": " + cn + " not verified: " + ve.getMessage()); } catch (ClassNotFoundException e) { failed.add(reader.imageName() + ": " + cn + " not found"); } diff --git a/jdk/test/tools/jlink/DefaultProviderTest.java b/jdk/test/tools/jlink/DefaultProviderTest.java index 22c68287d5c..c10e9d37060 100644 --- a/jdk/test/tools/jlink/DefaultProviderTest.java +++ b/jdk/test/tools/jlink/DefaultProviderTest.java @@ -33,7 +33,7 @@ import java.util.Set; import jdk.tools.jlink.internal.PluginRepository; import jdk.tools.jlink.plugin.Plugin; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; import tests.Helper; @@ -65,26 +65,26 @@ public class DefaultProviderTest { private boolean enabled = true; @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.TRANSFORMER); return Collections.unmodifiableSet(set); } @Override - public Set<STATE> getState() { - return enabled ? EnumSet.of(STATE.AUTO_ENABLED, STATE.FUNCTIONAL) - : EnumSet.of(STATE.DISABLED); + public Set<State> getState() { + return enabled ? EnumSet.of(State.AUTO_ENABLED, State.FUNCTIONAL) + : EnumSet.of(State.DISABLED); } @Override - public void visit(Pool in, Pool out) { + public void visit(ModulePool in, ModulePool out) { if (!enabled) { throw new PluginException(NAME + " was set"); } DefaultProviderTest.isNewPluginsCalled = true; - in.visit((Pool.ModuleData content) -> { + in.transformAndCopy(content -> { return content; }, out); } diff --git a/jdk/test/tools/jlink/ImageFileCreatorTest.java b/jdk/test/tools/jlink/ImageFileCreatorTest.java index 449d950d04d..8e093c69459 100644 --- a/jdk/test/tools/jlink/ImageFileCreatorTest.java +++ b/jdk/test/tools/jlink/ImageFileCreatorTest.java @@ -39,7 +39,7 @@ import jdk.tools.jlink.internal.ImageFileCreator; import jdk.tools.jlink.internal.ImagePluginStack; import jdk.tools.jlink.plugin.ExecutableImage; import jdk.tools.jlink.builder.ImageBuilder; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModulePool; /* @@ -47,6 +47,7 @@ import jdk.tools.jlink.plugin.Pool; * @summary ImageFileCreator class test * @author Jean-Francois Denise * @modules jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink.builder * java.base/jdk.internal.jimage * @run main/othervm -verbose:gc -Xmx1g ImageFileCreatorTest */ @@ -214,7 +215,7 @@ public class ImageFileCreatorTest { } @Override - public void storeFiles(Pool content) { + public void storeFiles(ModulePool content) { } }; diff --git a/jdk/test/tools/jlink/ImageFilePoolTest.java b/jdk/test/tools/jlink/ImageFilePoolTest.java index 7d35f9da8d6..1ea0fada3d7 100644 --- a/jdk/test/tools/jlink/ImageFilePoolTest.java +++ b/jdk/test/tools/jlink/ImageFilePoolTest.java @@ -31,11 +31,12 @@ */ import java.io.ByteArrayInputStream; -import jdk.tools.jlink.internal.PoolImpl; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; -import jdk.tools.jlink.plugin.Pool.Visitor; +import java.util.Optional; +import java.util.function.Function; +import jdk.tools.jlink.internal.ModuleEntryImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; public class ImageFilePoolTest { public static void main(String[] args) throws Exception { @@ -50,45 +51,45 @@ public class ImageFilePoolTest { private static final String SUFFIX = "END"; private void checkVisitor() throws Exception { - Pool input = new PoolImpl(); + ModulePool input = new ModulePoolImpl(); for (int i = 0; i < 1000; ++i) { String module = "module" + (i / 100); input.add(new InMemoryImageFile(module, "/" + module + "/java/class" + i, - ModuleDataType.CONFIG, "class" + i)); + ModuleEntry.Type.CONFIG, "class" + i)); } - if (input.getContent().size() != 1000) { + if (input.getEntryCount() != 1000) { throw new AssertionError(); } - Pool output = new PoolImpl(); + ModulePool output = new ModulePoolImpl(); ResourceVisitor visitor = new ResourceVisitor(); - input.visit(visitor, output); + input.transformAndCopy(visitor, output); if (visitor.getAmountBefore() == 0) { throw new AssertionError("Resources not found"); } - if (visitor.getAmountBefore() != input.getContent().size()) { + if (visitor.getAmountBefore() != input.getEntryCount()) { throw new AssertionError("Number of visited resources. Expected: " + - visitor.getAmountBefore() + ", got: " + input.getContent().size()); + visitor.getAmountBefore() + ", got: " + input.getEntryCount()); } - if (visitor.getAmountAfter() != output.getContent().size()) { + if (visitor.getAmountAfter() != output.getEntryCount()) { throw new AssertionError("Number of added resources. Expected: " + - visitor.getAmountAfter() + ", got: " + output.getContent().size()); + visitor.getAmountAfter() + ", got: " + output.getEntryCount()); } - for (ModuleData outFile : output.getContent()) { + output.entries().forEach(outFile -> { String path = outFile.getPath().replaceAll(SUFFIX + "$", ""); - ModuleData inFile = input.get(path); - if (inFile == null) { + Optional<ModuleEntry> inFile = input.findEntry(path); + if (!inFile.isPresent()) { throw new AssertionError("Unknown resource: " + path); } - } + }); } - private static class ResourceVisitor implements Visitor { + private static class ResourceVisitor implements Function<ModuleEntry, ModuleEntry> { private int amountBefore; private int amountAfter; @Override - public ModuleData visit(ModuleData file) { + public ModuleEntry apply(ModuleEntry file) { int index = ++amountBefore % 3; switch (index) { case 0: @@ -113,7 +114,7 @@ public class ImageFilePoolTest { } private void checkNegative() throws Exception { - PoolImpl input = new PoolImpl(); + ModulePoolImpl input = new ModulePoolImpl(); try { input.add(null); throw new AssertionError("NullPointerException is not thrown"); @@ -126,30 +127,30 @@ public class ImageFilePoolTest { } catch (NullPointerException e) { // expected } - if (input.get("unknown") != null) { - throw new AssertionError("ImageFilePool does not return null for unknown file"); + if (input.findEntry("unknown").isPresent()) { + throw new AssertionError("ImageFileModulePool does not return null for unknown file"); } - if (input.contains(new InMemoryImageFile("", "unknown", ModuleDataType.CONFIG, "unknown"))) { + if (input.contains(new InMemoryImageFile("", "unknown", ModuleEntry.Type.CONFIG, "unknown"))) { throw new AssertionError("'contain' returns true for unknown file"); } - input.add(new InMemoryImageFile("", "/aaa/bbb", ModuleDataType.CONFIG, "")); + input.add(new InMemoryImageFile("", "/aaa/bbb", ModuleEntry.Type.CONFIG, "")); try { - input.add(new InMemoryImageFile("", "/aaa/bbb", ModuleDataType.CONFIG, "")); + input.add(new InMemoryImageFile("", "/aaa/bbb", ModuleEntry.Type.CONFIG, "")); throw new AssertionError("Exception expected"); } catch (Exception e) { // expected } input.setReadOnly(); try { - input.add(new InMemoryImageFile("", "/aaa/ccc", ModuleDataType.CONFIG, "")); + input.add(new InMemoryImageFile("", "/aaa/ccc", ModuleEntry.Type.CONFIG, "")); throw new AssertionError("Exception expected"); } catch (Exception e) { // expected } } - private static class InMemoryImageFile extends ModuleData { - public InMemoryImageFile(String module, String path, ModuleDataType type, String content) { + private static class InMemoryImageFile extends ModuleEntryImpl { + public InMemoryImageFile(String module, String path, ModuleEntry.Type type, String content) { super(module, path, type, new ByteArrayInputStream(content.getBytes()), content.getBytes().length); } } diff --git a/jdk/test/tools/jlink/IntegrationTest.java b/jdk/test/tools/jlink/IntegrationTest.java index 951c16cff74..e5637b421a8 100644 --- a/jdk/test/tools/jlink/IntegrationTest.java +++ b/jdk/test/tools/jlink/IntegrationTest.java @@ -39,7 +39,7 @@ import jdk.tools.jlink.Jlink.JlinkConfiguration; import jdk.tools.jlink.Jlink.PluginsConfiguration; import jdk.tools.jlink.builder.DefaultImageBuilder; import jdk.tools.jlink.plugin.ExecutableImage; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.PostProcessorPlugin; import jdk.tools.jlink.plugin.TransformerPlugin; import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin; @@ -56,6 +56,8 @@ import tests.JImageGenerator; * @library ../lib * @modules java.base/jdk.internal.jimage * jdk.jdeps/com.sun.tools.classfile + * jdk.jlink/jdk.tools.jlink + * jdk.jlink/jdk.tools.jlink.builder * jdk.jlink/jdk.tools.jlink.internal * jdk.jlink/jdk.tools.jlink.internal.plugins * jdk.jlink/jdk.tools.jmod @@ -88,9 +90,9 @@ public class IntegrationTest { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.PROCESSOR); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.PROCESSOR); return Collections.unmodifiableSet(set); } @@ -128,18 +130,18 @@ public class IntegrationTest { } @Override - public void visit(Pool in, Pool out) { + public void visit(ModulePool in, ModulePool out) { System.err.println(NAME + index); ordered.add(index); - in.visit((file) -> { + in.transformAndCopy((file) -> { return file; }, out); } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.TRANSFORMER); return Collections.unmodifiableSet(set); } diff --git a/jdk/test/tools/jlink/JLinkOptimTest.java b/jdk/test/tools/jlink/JLinkOptimTest.java index 82c5431f034..acc089c89c0 100644 --- a/jdk/test/tools/jlink/JLinkOptimTest.java +++ b/jdk/test/tools/jlink/JLinkOptimTest.java @@ -23,15 +23,15 @@ import jdk.internal.org.objectweb.asm.tree.MethodInsnNode; import jdk.internal.org.objectweb.asm.tree.MethodNode; import jdk.internal.org.objectweb.asm.tree.TryCatchBlockNode; import jdk.tools.jlink.internal.PluginRepository; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.plugins.OptimizationPlugin; import jdk.tools.jlink.internal.plugins.asm.AsmModulePool; import jdk.tools.jlink.internal.plugins.asm.AsmPlugin; import jdk.tools.jlink.internal.plugins.asm.AsmPools; import jdk.tools.jlink.internal.plugins.optim.ControlFlow; import jdk.tools.jlink.internal.plugins.optim.ControlFlow.Block; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import tests.Helper; import tests.JImageGenerator; @@ -134,9 +134,9 @@ public class JLinkOptimTest { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.TRANSFORMER); return Collections.unmodifiableSet(set); } } @@ -150,13 +150,13 @@ public class JLinkOptimTest { FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); Path root = fs.getPath("/modules/java.base"); // Access module-info.class to be reused as fake module-info.class - List<ModuleData> javabaseResources = new ArrayList<>(); + List<ModuleEntry> javabaseResources = new ArrayList<>(); try (Stream<Path> stream = Files.walk(root)) { for (Iterator<Path> iterator = stream.iterator(); iterator.hasNext();) { Path p = iterator.next(); if (Files.isRegularFile(p)) { try { - javabaseResources.add(Pool.newResource(p.toString(). + javabaseResources.add(ModuleEntry.create(p.toString(). substring("/modules".length()), Files.readAllBytes(p))); } catch (Exception ex) { throw new RuntimeException(ex); @@ -166,18 +166,18 @@ public class JLinkOptimTest { } //forName folding - PoolImpl pool = new PoolImpl(); + ModulePoolImpl pool = new ModulePoolImpl(); byte[] content = Files.readAllBytes(classes. resolve("optim").resolve("ForNameTestCase.class")); byte[] content2 = Files.readAllBytes(classes. resolve("optim").resolve("AType.class")); byte[] mcontent = Files.readAllBytes(classes.resolve("module-info.class")); - pool.add(Pool.newResource("/optimplugin/optim/ForNameTestCase.class", content)); - pool.add(Pool.newResource("/optimplugin/optim/AType.class", content2)); - pool.add(Pool.newResource("/optimplugin/module-info.class", mcontent)); + pool.add(ModuleEntry.create("/optimplugin/optim/ForNameTestCase.class", content)); + pool.add(ModuleEntry.create("/optimplugin/optim/AType.class", content2)); + pool.add(ModuleEntry.create("/optimplugin/module-info.class", mcontent)); - for (ModuleData r : javabaseResources) { + for (ModuleEntry r : javabaseResources) { pool.add(r); } @@ -186,10 +186,10 @@ public class JLinkOptimTest { optional.put(OptimizationPlugin.NAME, OptimizationPlugin.FORNAME_REMOVAL); optional.put(OptimizationPlugin.LOG, "forName.log"); plugin.configure(optional); - Pool out = new PoolImpl(); + ModulePool out = new ModulePoolImpl(); plugin.visit(pool, out); - ModuleData result = out.getContent().iterator().next(); + ModuleEntry result = out.entries().iterator().next(); ClassReader optimReader = new ClassReader(result.getBytes()); ClassNode optimClass = new ClassNode(); diff --git a/jdk/test/tools/jlink/JLinkOptionsTest.java b/jdk/test/tools/jlink/JLinkOptionsTest.java index 8c8d241f5b7..565c58bffa9 100644 --- a/jdk/test/tools/jlink/JLinkOptionsTest.java +++ b/jdk/test/tools/jlink/JLinkOptionsTest.java @@ -24,7 +24,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.internal.PluginRepository; import jdk.tools.jlink.plugin.TransformerPlugin; @@ -62,7 +62,7 @@ public class JLinkOptionsTest { } @Override - public void visit(Pool in, Pool out) { + public void visit(ModulePool in, ModulePool out) { } diff --git a/jdk/test/tools/jlink/JLinkPostProcessingTest.java b/jdk/test/tools/jlink/JLinkPostProcessingTest.java index b32bf207ff2..abc2b58142e 100644 --- a/jdk/test/tools/jlink/JLinkPostProcessingTest.java +++ b/jdk/test/tools/jlink/JLinkPostProcessingTest.java @@ -75,9 +75,9 @@ public class JLinkPostProcessingTest { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.PROCESSOR); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.PROCESSOR); return Collections.unmodifiableSet(set); } diff --git a/jdk/test/tools/jlink/ResourcePoolTest.java b/jdk/test/tools/jlink/ResourcePoolTest.java index 77a82e5c1b2..523503c996a 100644 --- a/jdk/test/tools/jlink/ResourcePoolTest.java +++ b/jdk/test/tools/jlink/ResourcePoolTest.java @@ -37,14 +37,14 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.List; +import java.util.Optional; import java.util.Set; - -import jdk.tools.jlink.internal.PoolImpl; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.Module; -import jdk.tools.jlink.plugin.Pool.ModuleData; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; -import jdk.tools.jlink.plugin.Pool.Visitor; +import java.util.function.Function; +import jdk.tools.jlink.internal.ModulePoolImpl; +import jdk.tools.jlink.plugin.ModulePool; +import jdk.tools.jlink.plugin.LinkModule; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; public class ResourcePoolTest { @@ -61,54 +61,53 @@ public class ResourcePoolTest { private static final String SUFFIX = "END"; private void checkResourceVisitor() throws Exception { - Pool input = new PoolImpl(); + ModulePool input = new ModulePoolImpl(); for (int i = 0; i < 1000; ++i) { String module = "/module" + (i / 10); String resourcePath = module + "/java/package" + i; byte[] bytes = resourcePath.getBytes(); - input.add(new ModuleData(module, resourcePath, - ModuleDataType.CLASS_OR_RESOURCE, + input.add(ModuleEntry.create(module, resourcePath, + ModuleEntry.Type.CLASS_OR_RESOURCE, new ByteArrayInputStream(bytes), bytes.length)); } - Pool output = new PoolImpl(); + ModulePool output = new ModulePoolImpl(); ResourceVisitor visitor = new ResourceVisitor(); - input.visit(visitor, output); + input.transformAndCopy(visitor, output); if (visitor.getAmountBefore() == 0) { throw new AssertionError("Resources not found"); } - if (visitor.getAmountBefore() != input.getContent().size()) { + if (visitor.getAmountBefore() != input.getEntryCount()) { throw new AssertionError("Number of visited resources. Expected: " + - visitor.getAmountBefore() + ", got: " + input.getContent().size()); + visitor.getAmountBefore() + ", got: " + input.getEntryCount()); } - if (visitor.getAmountAfter() != output.getContent().size()) { + if (visitor.getAmountAfter() != output.getEntryCount()) { throw new AssertionError("Number of added resources. Expected: " + - visitor.getAmountAfter() + ", got: " + output.getContent().size()); + visitor.getAmountAfter() + ", got: " + output.getEntryCount()); } - for (ModuleData outResource : output.getContent()) { + output.entries().forEach(outResource -> { String path = outResource.getPath().replaceAll(SUFFIX + "$", ""); - ModuleData inResource = input.get(path); - if (inResource == null) { + if (!input.findEntry(path).isPresent()) { throw new AssertionError("Unknown resource: " + path); } - } + }); } - private static class ResourceVisitor implements Visitor { + private static class ResourceVisitor implements Function<ModuleEntry, ModuleEntry> { private int amountBefore; private int amountAfter; @Override - public ModuleData visit(ModuleData resource) { + public ModuleEntry apply(ModuleEntry resource) { int index = ++amountBefore % 3; switch (index) { case 0: ++amountAfter; - return new ModuleData(resource.getModule(), resource.getPath() + SUFFIX, + return ModuleEntry.create(resource.getModule(), resource.getPath() + SUFFIX, resource.getType(), resource.stream(), resource.getLength()); case 1: ++amountAfter; - return new ModuleData(resource.getModule(), resource.getPath(), + return ModuleEntry.create(resource.getModule(), resource.getPath(), resource.getType(), resource.stream(), resource.getLength()); } return null; @@ -133,8 +132,8 @@ public class ResourcePoolTest { samples.add("javax/management/ObjectName"); test(samples, (resources, module, path) -> { try { - resources.add(new ModuleData(module, path, - ModuleDataType.CLASS_OR_RESOURCE, + resources.add(ModuleEntry.create(module, path, + ModuleEntry.Type.CLASS_OR_RESOURCE, new ByteArrayInputStream(new byte[0]), 0)); } catch (Exception ex) { throw new RuntimeException(ex); @@ -142,12 +141,12 @@ public class ResourcePoolTest { }); test(samples, (resources, module, path) -> { try { - resources.add(PoolImpl. - newCompressedResource(new ModuleData(module, path, - ModuleDataType.CLASS_OR_RESOURCE, + resources.add(ModulePoolImpl. + newCompressedResource(ModuleEntry.create(module, path, + ModuleEntry.Type.CLASS_OR_RESOURCE, new ByteArrayInputStream(new byte[0]), 0), ByteBuffer.allocate(99), "bitcruncher", null, - ((PoolImpl)resources).getStringTable(), ByteOrder.nativeOrder())); + ((ModulePoolImpl)resources).getStringTable(), ByteOrder.nativeOrder())); } catch (Exception ex) { throw new RuntimeException(ex); } @@ -158,7 +157,7 @@ public class ResourcePoolTest { if (samples.isEmpty()) { throw new AssertionError("No sample to test"); } - Pool resources = new PoolImpl(); + ModulePool resources = new ModulePoolImpl(); Set<String> modules = new HashSet<>(); for (int i = 0; i < samples.size(); i++) { String module = samples.get(i); @@ -173,70 +172,69 @@ public class ResourcePoolTest { i++; String clazz = samples.get(i); String path = "/" + module + "/" + clazz + ".class"; - ModuleData res = resources.get(path); - checkModule(resources, res); - if (res == null) { + Optional<ModuleEntry> res = resources.findEntry(path); + if (!res.isPresent()) { throw new AssertionError("Resource not found " + path); } - ModuleData res2 = resources.get(clazz); - if (res2 != null) { + checkModule(resources, res.get()); + if (resources.findEntry(clazz).isPresent()) { throw new AssertionError("Resource found " + clazz); } } - if (resources.getContent().size() != samples.size() / 2) { + if (resources.getEntryCount() != samples.size() / 2) { throw new AssertionError("Invalid number of resources"); } } - private void checkModule(Pool resources, ModuleData res) { - Module m = resources.getModule(res.getModule()); - if (m == null) { + private void checkModule(ModulePool resources, ModuleEntry res) { + Optional<LinkModule> optMod = resources.findModule(res.getModule()); + if (!optMod.isPresent()) { throw new AssertionError("No module " + res.getModule()); } + LinkModule m = optMod.get(); if (!m.getName().equals(res.getModule())) { throw new AssertionError("Not right module name " + res.getModule()); } - if (m.get(res.getPath()) == null) { + if (!m.findEntry(res.getPath()).isPresent()) { throw new AssertionError("resource " + res.getPath() + " not in module " + m.getName()); } } private void checkResourcesAfterCompression() throws Exception { - PoolImpl resources1 = new PoolImpl(); - ModuleData res1 = new ModuleData("module1", "/module1/toto1", - ModuleDataType.CLASS_OR_RESOURCE, + ModulePoolImpl resources1 = new ModulePoolImpl(); + ModuleEntry res1 = ModuleEntry.create("module1", "/module1/toto1", + ModuleEntry.Type.CLASS_OR_RESOURCE, new ByteArrayInputStream(new byte[0]), 0); - ModuleData res2 = new ModuleData("module2", "/module2/toto1", - ModuleDataType.CLASS_OR_RESOURCE, + ModuleEntry res2 = ModuleEntry.create("module2", "/module2/toto1", + ModuleEntry.Type.CLASS_OR_RESOURCE, new ByteArrayInputStream(new byte[0]), 0); resources1.add(res1); resources1.add(res2); checkResources(resources1, res1, res2); - Pool resources2 = new PoolImpl(); - ModuleData res3 = new ModuleData("module2", "/module2/toto1", - ModuleDataType.CLASS_OR_RESOURCE, + ModulePool resources2 = new ModulePoolImpl(); + ModuleEntry res3 = ModuleEntry.create("module2", "/module2/toto1", + ModuleEntry.Type.CLASS_OR_RESOURCE, new ByteArrayInputStream(new byte[7]), 7); resources2.add(res3); - resources2.add(PoolImpl.newCompressedResource(res1, + resources2.add(ModulePoolImpl.newCompressedResource(res1, ByteBuffer.allocate(7), "zip", null, resources1.getStringTable(), ByteOrder.nativeOrder())); checkResources(resources2, res1, res2); } - private void checkResources(Pool resources, ModuleData... expected) { - Collection<Module> ms = resources.getModules(); + private void checkResources(ModulePool resources, ModuleEntry... expected) { List<String> modules = new ArrayList(); - for(Module m : ms) { + resources.modules().forEach(m -> { modules.add(m.getName()); - } - for (ModuleData res : expected) { + }); + for (ModuleEntry res : expected) { if (!resources.contains(res)) { throw new AssertionError("Resource not found: " + res); } - if (resources.get(res.getPath()) == null) { + if (!resources.findEntry(res.getPath()).isPresent()) { throw new AssertionError("Resource not found: " + res); } @@ -244,7 +242,7 @@ public class ResourcePoolTest { throw new AssertionError("Module not found: " + res.getModule()); } - if (!resources.getContent().contains(res)) { + if (!resources.contains(res)) { throw new AssertionError("Resources not found: " + res); } @@ -260,17 +258,17 @@ public class ResourcePoolTest { throw new AssertionError("ReadOnly resources"); } - ((PoolImpl) resources).setReadOnly(); + ((ModulePoolImpl) resources).setReadOnly(); try { - resources.add(new ModuleData("module2", "/module2/toto1", - ModuleDataType.CLASS_OR_RESOURCE, new ByteArrayInputStream(new byte[0]), 0)); - throw new AssertionError("Pool is read-only, but an exception is not thrown"); + resources.add(ModuleEntry.create("module2", "/module2/toto1", + ModuleEntry.Type.CLASS_OR_RESOURCE, new ByteArrayInputStream(new byte[0]), 0)); + throw new AssertionError("ModulePool is read-only, but an exception is not thrown"); } catch (Exception ex) { // Expected } } interface ResourceAdder { - void add(Pool resources, String module, String path); + void add(ModulePool resources, String module, String path); } } diff --git a/jdk/test/tools/jlink/SecurityTest.java b/jdk/test/tools/jlink/SecurityTest.java index 9497d6f3f34..dbf593bccc0 100644 --- a/jdk/test/tools/jlink/SecurityTest.java +++ b/jdk/test/tools/jlink/SecurityTest.java @@ -25,6 +25,7 @@ * @test * @summary Test JlinkPermission * @author Jean-Francois Denise + * @modules jdk.jlink/jdk.tools.jlink * @run main/othervm SecurityTest */ diff --git a/jdk/test/tools/jlink/asmplugin/AddForgetResourcesTest.java b/jdk/test/tools/jlink/asmplugin/AddForgetResourcesTest.java index 6a414b57d63..4385534e07f 100644 --- a/jdk/test/tools/jlink/asmplugin/AddForgetResourcesTest.java +++ b/jdk/test/tools/jlink/asmplugin/AddForgetResourcesTest.java @@ -55,8 +55,8 @@ import jdk.tools.jlink.internal.plugins.asm.AsmPool.ResourceFile; import jdk.tools.jlink.internal.plugins.asm.AsmPool.WritableClassPool; import jdk.tools.jlink.internal.plugins.asm.AsmPool.WritableResourcePool; import jdk.tools.jlink.internal.plugins.asm.AsmPools; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; public class AddForgetResourcesTest extends AsmPluginTestBase { @@ -82,7 +82,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { new ComboPlugin() }; for (TestPlugin p : plugins) { - Pool out = p.visit(getPool()); + ModulePool out = p.visit(getPool()); p.test(getPool(), out); } } @@ -124,7 +124,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { AsmGlobalPool globalPool = pools.getGlobalPool(); WritableClassPool transformedClasses = globalPool.getTransformedClasses(); expected = globalPool.getClasses().size(); - for (ModuleData res : globalPool.getClasses()) { + for (ModuleEntry res : globalPool.getClasses()) { ClassReader reader = globalPool.getClassReader(res); String className = reader.getClassName(); if (!className.endsWith("module-info")) { @@ -137,14 +137,14 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { } @Override - public void test(Pool inResources, Pool outResources) { - Collection<ModuleData> inClasses = extractClasses(inResources); - Collection<ModuleData> outClasses = extractClasses(outResources); + public void test(ModulePool inResources, ModulePool outResources) { + Collection<ModuleEntry> inClasses = extractClasses(inResources); + Collection<ModuleEntry> outClasses = extractClasses(outResources); if (expected != outClasses.size()) { throw new AssertionError("Classes were not added. Expected: " + expected + ", got: " + outClasses.size()); } - for (ModuleData in : inClasses) { + for (ModuleEntry in : inClasses) { String path = in.getPath(); if (!outClasses.contains(in)) { throw new AssertionError("Class not found: " + path); @@ -153,7 +153,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { continue; } String modifiedPath = path.replace(".class", SUFFIX + ".class"); - if (!outClasses.contains(Pool.newResource(modifiedPath, new byte[0]))) { + if (!outClasses.contains(ModuleEntry.create(modifiedPath, new byte[0]))) { throw new AssertionError("Class not found: " + modifiedPath); } } @@ -166,7 +166,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { public void visit() { AsmPools pools = getPools(); AsmGlobalPool globalPool = pools.getGlobalPool(); - for (ModuleData res : globalPool.getResourceFiles()) { + for (ModuleEntry res : globalPool.getResourceFiles()) { String path = res.getPath(); String moduleName = getModule(path); AsmModulePool modulePool = pools.getModulePool(moduleName); @@ -177,20 +177,20 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { } @Override - public void test(Pool in, Pool out) throws Exception { - Collection<ModuleData> inResources = extractResources(in); - Collection<ModuleData> outResources = extractResources(out); + public void test(ModulePool in, ModulePool out) throws Exception { + Collection<ModuleEntry> inResources = extractResources(in); + Collection<ModuleEntry> outResources = extractResources(out); if (2 * inResources.size() != outResources.size()) { throw new AssertionError("Classes were not added. Expected: " + (2 * inResources.size()) + ", got: " + outResources.size()); } - for (ModuleData r : inResources) { + for (ModuleEntry r : inResources) { String path = r.getPath(); if (!outResources.contains(r)) { throw new AssertionError("Class not found: " + path); } String modifiedPath = path + SUFFIX; - if (!outResources.contains(Pool.newResource(modifiedPath, new byte[0]))) { + if (!outResources.contains(ModuleEntry.create(modifiedPath, new byte[0]))) { throw new AssertionError("Class not found: " + modifiedPath); } } @@ -204,7 +204,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { AsmPools pools = getPools(); AsmGlobalPool globalPool = pools.getGlobalPool(); WritableClassPool transformedClasses = globalPool.getTransformedClasses(); - for (ModuleData res : globalPool.getClasses()) { + for (ModuleEntry res : globalPool.getClasses()) { ClassReader reader = globalPool.getClassReader(res); ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES); reader.accept(new AddMethodClassVisitor(writer), ClassReader.EXPAND_FRAMES); @@ -213,14 +213,14 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { } @Override - public void test(Pool inResources, Pool outResources) throws Exception { - Collection<ModuleData> inClasses = extractClasses(inResources); - Collection<ModuleData> outClasses = extractClasses(outResources); + public void test(ModulePool inResources, ModulePool outResources) throws Exception { + Collection<ModuleEntry> inClasses = extractClasses(inResources); + Collection<ModuleEntry> outClasses = extractClasses(outResources); if (inClasses.size() != outClasses.size()) { throw new AssertionError("Number of classes. Expected: " + (inClasses.size()) + ", got: " + outClasses.size()); } - for (ModuleData out : outClasses) { + for (ModuleEntry out : outClasses) { String path = out.getPath(); if (!inClasses.contains(out)) { throw new AssertionError("Class not found: " + path); @@ -248,7 +248,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { public void visit() { AsmPools pools = getPools(); AsmGlobalPool globalPool = pools.getGlobalPool(); - for (ModuleData res : globalPool.getResourceFiles()) { + for (ModuleEntry res : globalPool.getResourceFiles()) { String path = res.getPath(); AsmModulePool modulePool = pools.getModulePool(getModule(path)); modulePool.getTransformedResourceFiles().addResourceFile(new ResourceFile(removeModule(path), @@ -257,14 +257,14 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { } @Override - public void test(Pool in, Pool out) throws Exception { - Collection<ModuleData> inResources = extractResources(in); - Collection<ModuleData> outResources = extractResources(out); + public void test(ModulePool in, ModulePool out) throws Exception { + Collection<ModuleEntry> inResources = extractResources(in); + Collection<ModuleEntry> outResources = extractResources(out); if (inResources.size() != outResources.size()) { throw new AssertionError("Number of resources. Expected: " + inResources.size() + ", got: " + outResources.size()); } - for (ModuleData r : outResources) { + for (ModuleEntry r : outResources) { String path = r.getPath(); if (!inResources.contains(r)) { throw new AssertionError("Resource not found: " + path); @@ -287,7 +287,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { AsmGlobalPool globalPool = pools.getGlobalPool(); WritableClassPool transformedClasses = globalPool.getTransformedClasses(); int i = 0; - for (ModuleData res : globalPool.getClasses()) { + for (ModuleEntry res : globalPool.getClasses()) { String path = removeModule(res.getPath()); String className = path.replace(".class", ""); if ((i & 1) == 0 && !className.endsWith("module-info")) { @@ -300,8 +300,8 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { } @Override - public void test(Pool inResources, Pool outResources) throws Exception { - Collection<ModuleData> outClasses = extractClasses(outResources); + public void test(ModulePool inResources, ModulePool outResources) throws Exception { + Collection<ModuleEntry> outClasses = extractClasses(outResources); if (expected != outClasses.size()) { throw new AssertionError("Number of classes. Expected: " + expected + ", got: " + outClasses.size()); @@ -318,7 +318,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { AsmPools pools = getPools(); AsmGlobalPool globalPool = pools.getGlobalPool(); int i = 0; - for (ModuleData res : globalPool.getResourceFiles()) { + for (ModuleEntry res : globalPool.getResourceFiles()) { String path = res.getPath(); if (!path.contains("META-INF/services")) { if ((i & 1) == 0) { @@ -335,8 +335,8 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { } @Override - public void test(Pool in, Pool out) throws Exception { - Collection<ModuleData> outResources = extractResources(out); + public void test(ModulePool in, ModulePool out) throws Exception { + Collection<ModuleEntry> outResources = extractResources(out); if (expectedAmount != outResources.size()) { throw new AssertionError("Number of classes. Expected: " + expectedAmount + ", got: " + outResources.size()); @@ -354,7 +354,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { AsmGlobalPool globalPool = pools.getGlobalPool(); WritableClassPool transformedClasses = globalPool.getTransformedClasses(); int i = 0; - for (ModuleData res : globalPool.getClasses()) { + for (ModuleEntry res : globalPool.getClasses()) { ClassReader reader = globalPool.getClassReader(res); String className = reader.getClassName(); ClassWriter writer = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES); @@ -374,8 +374,8 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { } @Override - public void test(Pool inResources, Pool outResources) throws Exception { - Collection<ModuleData> outClasses = extractClasses(outResources); + public void test(ModulePool inResources, ModulePool outResources) throws Exception { + Collection<ModuleEntry> outClasses = extractClasses(outResources); if (expected != outClasses.size()) { throw new AssertionError("Number of classes. Expected: " + expected + ", got: " + outClasses.size()); @@ -392,7 +392,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { AsmPools pools = getPools(); AsmGlobalPool globalPool = pools.getGlobalPool(); int i = 0; - for (ModuleData res : globalPool.getResourceFiles()) { + for (ModuleEntry res : globalPool.getResourceFiles()) { String path = res.getPath(); String moduleName = getModule(path); if (!path.contains("META-INF")) { @@ -412,8 +412,8 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { } @Override - public void test(Pool inResources, Pool out) throws Exception { - Collection<ModuleData> outResources = extractResources(out); + public void test(ModulePool inResources, ModulePool out) throws Exception { + Collection<ModuleEntry> outResources = extractResources(out); if (expectedAmount != outResources.size()) { throw new AssertionError("Number of classes. Expected: " + expectedAmount + ", got: " + outResources.size()); @@ -446,7 +446,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { } @Override - public void test(Pool inResources, Pool outResources) throws Exception { + public void test(ModulePool inResources, ModulePool outResources) throws Exception { if (!isVisitCalled()) { throw new AssertionError("Resources not visited"); } @@ -455,7 +455,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { throw new AssertionError("Number of transformed classes not equal to expected"); } // Check that only renamed classes and resource files are in the result. - for (ModuleData r : outResources.getContent()) { + outResources.entries().forEach(r -> { String resourceName = r.getPath(); if (resourceName.endsWith(".class") && !resourceName.endsWith("module-info.class")) { if (!resourceName.endsWith(SUFFIX + ".class")) { @@ -467,7 +467,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { throw new AssertionError("Resource file not renamed " + resourceName); } } - } + }); } private void renameResources() throws IOException { @@ -476,7 +476,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { for (Map.Entry<String, List<String>> mod : MODULES.entrySet()) { String moduleName = mod.getKey(); AsmModulePool modulePool = pools.getModulePool(moduleName); - for (ModuleData res : modulePool.getResourceFiles()) { + for (ModuleEntry res : modulePool.getResourceFiles()) { ResourceFile resFile = modulePool.getResourceFile(res); if (resFile.getPath().startsWith("META-INF/services/")) { String newContent = new String(resFile.getContent()) + SUFFIX; @@ -492,7 +492,7 @@ public class AddForgetResourcesTest extends AsmPluginTestBase { AsmPools pools = getPools(); AsmGlobalPool globalPool = pools.getGlobalPool(); WritableClassPool transformedClasses = globalPool.getTransformedClasses(); - for (ModuleData res : globalPool.getClasses()) { + for (ModuleEntry res : globalPool.getClasses()) { if (res.getPath().endsWith("module-info.class")) { continue; } diff --git a/jdk/test/tools/jlink/asmplugin/AsmPluginTestBase.java b/jdk/test/tools/jlink/asmplugin/AsmPluginTestBase.java index d5c035562fa..c51419e682c 100644 --- a/jdk/test/tools/jlink/asmplugin/AsmPluginTestBase.java +++ b/jdk/test/tools/jlink/asmplugin/AsmPluginTestBase.java @@ -38,23 +38,23 @@ import java.util.Set; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.StringTable; import jdk.tools.jlink.internal.plugins.asm.AsmPlugin; import jdk.tools.jlink.internal.plugins.asm.AsmPools; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; public abstract class AsmPluginTestBase { protected static final String TEST_MODULE = "jlink.test"; protected static final Map<String, List<String>> MODULES; - private static final Predicate<ModuleData> isClass = r -> r.getPath().endsWith(".class"); + private static final Predicate<ModuleEntry> isClass = r -> r.getPath().endsWith(".class"); private final List<String> classes; private final List<String> resources; - private final Pool pool; + private final ModulePool pool; static { Map<String, List<String>> map = new HashMap<>(); @@ -75,7 +75,7 @@ public abstract class AsmPluginTestBase { List<String> classes = new ArrayList<>(); List<String> resources = new ArrayList<>(); - pool = new PoolImpl(); + pool = new ModulePoolImpl(); FileSystem fs = FileSystems.getFileSystem(URI.create("jrt:/")); Path root = fs.getPath("/modules"); @@ -100,7 +100,7 @@ public abstract class AsmPluginTestBase { MODULES.get(module).add(toResourceFile(p)); } resources.add(toPath(p.toString())); - ModuleData res = Pool.newResource(toPath(p.toString()), content); + ModuleEntry res = ModuleEntry.create(toPath(p.toString()), content); pool.add(res); } catch (Exception ex) { throw new RuntimeException(ex); @@ -110,17 +110,17 @@ public abstract class AsmPluginTestBase { } } // There is more than 10 classes in java.base... - if (classes.size() < 10 || pool.getContent().size() < 10) { + if (classes.size() < 10 || pool.getEntryCount() < 10) { throw new AssertionError("Not expected resource or class number"); } //Add a fake resource file String content = "java.lang.Object"; String path = "META-INF/services/com.foo.BarProvider"; - ModuleData resFile = Pool.newResource("/" + TEST_MODULE + "/" + + ModuleEntry resFile = ModuleEntry.create("/" + TEST_MODULE + "/" + path, content.getBytes()); pool.add(resFile); - ModuleData fakeInfoFile = Pool.newResource("/" + TEST_MODULE + ModuleEntry fakeInfoFile = ModuleEntry.create("/" + TEST_MODULE + "/module-info.class", moduleInfos.get(0)); pool.add(fakeInfoFile); MODULES.get(TEST_MODULE).add(path); @@ -144,20 +144,20 @@ public abstract class AsmPluginTestBase { return resources; } - public Pool getPool() { + public ModulePool getPool() { return pool; } public abstract void test() throws Exception; - public Collection<ModuleData> extractClasses(Pool pool) { - return pool.getContent().stream() + public Collection<ModuleEntry> extractClasses(ModulePool pool) { + return pool.entries() .filter(isClass) .collect(Collectors.toSet()); } - public Collection<ModuleData> extractResources(Pool pool) { - return pool.getContent().stream() + public Collection<ModuleEntry> extractResources(ModulePool pool) { + return pool.entries() .filter(isClass.negate()) .collect(Collectors.toSet()); } @@ -209,9 +209,9 @@ public abstract class AsmPluginTestBase { return pools != null; } - public Pool visit(Pool inResources) throws IOException { + public ModulePool visit(ModulePool inResources) throws IOException { try { - Pool outResources = new PoolImpl(inResources.getByteOrder(), new StringTable() { + ModulePool outResources = new ModulePoolImpl(inResources.getByteOrder(), new StringTable() { @Override public int addString(String str) { return -1; @@ -239,7 +239,7 @@ public abstract class AsmPluginTestBase { } public abstract void visit(); - public abstract void test(Pool inResources, Pool outResources) throws Exception; + public abstract void test(ModulePool inResources, ModulePool outResources) throws Exception; @Override public String getName() { diff --git a/jdk/test/tools/jlink/asmplugin/BasicTest.java b/jdk/test/tools/jlink/asmplugin/BasicTest.java index 0c42d4cfb99..afc5fd5f634 100644 --- a/jdk/test/tools/jlink/asmplugin/BasicTest.java +++ b/jdk/test/tools/jlink/asmplugin/BasicTest.java @@ -45,8 +45,8 @@ import java.util.logging.Logger; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.tools.jlink.internal.plugins.asm.AsmModulePool; import jdk.tools.jlink.internal.plugins.asm.AsmPool; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; public class BasicTest extends AsmPluginTestBase { @@ -61,7 +61,7 @@ public class BasicTest extends AsmPluginTestBase { @Override public void test() throws Exception { BasicPlugin basicPlugin = new BasicPlugin(getClasses()); - Pool res = basicPlugin.visit(getPool()); + ModulePool res = basicPlugin.visit(getPool()); basicPlugin.test(getPool(), res); } @@ -107,13 +107,13 @@ public class BasicTest extends AsmPluginTestBase { } @Override - public void test(Pool inResources, Pool outResources) throws Exception { + public void test(ModulePool inResources, ModulePool outResources) throws Exception { if (!isVisitCalled()) { throw new AssertionError("Resources not visited"); } - if (inResources.getContent().size() != outResources.getContent().size()) { - throw new AssertionError("Input size " + inResources.getContent().size() + - " != to " + outResources.getContent().size()); + if (inResources.getEntryCount() != outResources.getEntryCount()) { + throw new AssertionError("Input size " + inResources.getEntryCount() + + " != to " + outResources.getEntryCount()); } } @@ -142,7 +142,7 @@ public class BasicTest extends AsmPluginTestBase { private void testPools() throws IOException { Set<String> remain = new HashSet<>(classes); - for (ModuleData res : getPools().getGlobalPool().getClasses()) { + for (ModuleEntry res : getPools().getGlobalPool().getClasses()) { ClassReader reader = getPools().getGlobalPool().getClassReader(res); String className = reader.getClassName(); // Wrong naming of module-info.class in ASM diff --git a/jdk/test/tools/jlink/asmplugin/IdentityPluginTest.java b/jdk/test/tools/jlink/asmplugin/IdentityPluginTest.java index ceb2e50f9b9..416d3581552 100644 --- a/jdk/test/tools/jlink/asmplugin/IdentityPluginTest.java +++ b/jdk/test/tools/jlink/asmplugin/IdentityPluginTest.java @@ -35,14 +35,15 @@ import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.UncheckedIOException; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.ClassVisitor; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Opcodes; import jdk.tools.jlink.internal.plugins.asm.AsmPool.WritableClassPool; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; public class IdentityPluginTest extends AsmPluginTestBase { @@ -56,7 +57,7 @@ public class IdentityPluginTest extends AsmPluginTestBase { public void test() throws Exception { IdentityPlugin asm = new IdentityPlugin(); - Pool resourcePool = asm.visit(getPool()); + ModulePool resourcePool = asm.visit(getPool()); asm.test(getPool(), resourcePool); } @@ -64,7 +65,7 @@ public class IdentityPluginTest extends AsmPluginTestBase { @Override public void visit() { - for (ModuleData res : getPools().getGlobalPool().getClasses()) { + for (ModuleEntry res : getPools().getGlobalPool().getClasses()) { if (res.getPath().endsWith("module-info.class")) { continue; } @@ -77,7 +78,7 @@ public class IdentityPluginTest extends AsmPluginTestBase { } @Override - public void test(Pool inResources, Pool outResources) throws IOException { + public void test(ModulePool inResources, ModulePool outResources) throws IOException { if (outResources.isEmpty()) { throw new AssertionError("Empty result"); } @@ -93,13 +94,17 @@ public class IdentityPluginTest extends AsmPluginTestBase { throw new AssertionError("Class not transformed " + className); } } - for (ModuleData r : outResources.getContent()) { + outResources.entries().forEach(r -> { if (r.getPath().endsWith(".class") && !r.getPath().endsWith("module-info.class")) { - ClassReader reader = new ClassReader(new ByteArrayInputStream(r.getBytes())); - ClassWriter w = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES); - reader.accept(w, ClassReader.EXPAND_FRAMES); + try { + ClassReader reader = new ClassReader(new ByteArrayInputStream(r.getBytes())); + ClassWriter w = new ClassWriter(reader, ClassWriter.COMPUTE_FRAMES); + reader.accept(w, ClassReader.EXPAND_FRAMES); + } catch (IOException exp) { + throw new UncheckedIOException(exp); + } } - } + }); } @Override diff --git a/jdk/test/tools/jlink/asmplugin/NegativeTest.java b/jdk/test/tools/jlink/asmplugin/NegativeTest.java index f95b7c62399..6263fcaaa4a 100644 --- a/jdk/test/tools/jlink/asmplugin/NegativeTest.java +++ b/jdk/test/tools/jlink/asmplugin/NegativeTest.java @@ -43,7 +43,7 @@ import jdk.internal.org.objectweb.asm.ClassVisitor; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Opcodes; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.StringTable; import jdk.tools.jlink.internal.plugins.asm.AsmGlobalPool; import jdk.tools.jlink.internal.plugins.asm.AsmModulePool; @@ -51,7 +51,7 @@ import jdk.tools.jlink.internal.plugins.asm.AsmPlugin; import jdk.tools.jlink.internal.plugins.asm.AsmPool.ResourceFile; import jdk.tools.jlink.internal.plugins.asm.AsmPools; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModulePool; public class NegativeTest extends AsmPluginTestBase { public static void main(String[] args) throws Exception { @@ -102,7 +102,7 @@ public class NegativeTest extends AsmPluginTestBase { } } }; - Pool resources = new PoolImpl(ByteOrder.BIG_ENDIAN, new StringTable() { + ModulePool resources = new ModulePoolImpl(ByteOrder.BIG_ENDIAN, new StringTable() { @Override public int addString(String str) { return -1; @@ -136,7 +136,7 @@ public class NegativeTest extends AsmPluginTestBase { action(() -> pools.fillOutputResources(null), "Output resource is null", NullPointerException.class); } }; - Pool resources = new PoolImpl(ByteOrder.BIG_ENDIAN, new StringTable() { + ModulePool resources = new ModulePoolImpl(ByteOrder.BIG_ENDIAN, new StringTable() { @Override public int addString(String str) { return -1; diff --git a/jdk/test/tools/jlink/asmplugin/PackageMappingTest.java b/jdk/test/tools/jlink/asmplugin/PackageMappingTest.java index 9453ac5f917..bd0a8fdbf4d 100644 --- a/jdk/test/tools/jlink/asmplugin/PackageMappingTest.java +++ b/jdk/test/tools/jlink/asmplugin/PackageMappingTest.java @@ -48,8 +48,8 @@ import jdk.tools.jlink.internal.plugins.asm.AsmModulePool; import jdk.tools.jlink.internal.plugins.asm.AsmPool.ResourceFile; import jdk.tools.jlink.internal.plugins.asm.AsmPool.WritableResourcePool; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; public class PackageMappingTest extends AsmPluginTestBase { @@ -72,7 +72,7 @@ public class PackageMappingTest extends AsmPluginTestBase { new PackageMappingPlugin(newFiles, true) }; for (TestPlugin p : plugins) { - Pool pool = p.visit(getPool()); + ModulePool pool = p.visit(getPool()); p.test(getPool(), pool); } } @@ -105,12 +105,12 @@ public class PackageMappingTest extends AsmPluginTestBase { } @Override - public void test(Pool inResources, Pool outResources) { + public void test(ModulePool inResources, ModulePool outResources) { Set<String> in = getPools().getGlobalPool().getResourceFiles().stream() - .map(ModuleData::getPath) + .map(ModuleEntry::getPath) .collect(Collectors.toSet()); Set<String> out = extractResources(outResources).stream() - .map(ModuleData::getPath) + .map(ModuleEntry::getPath) .collect(Collectors.toSet()); in.addAll(PackageMappingTest.this.newFiles); if (!Objects.equals(in, out)) { diff --git a/jdk/test/tools/jlink/asmplugin/SortingTest.java b/jdk/test/tools/jlink/asmplugin/SortingTest.java index 0fc4c7a6854..26974b3b065 100644 --- a/jdk/test/tools/jlink/asmplugin/SortingTest.java +++ b/jdk/test/tools/jlink/asmplugin/SortingTest.java @@ -35,12 +35,13 @@ import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import java.util.stream.Collectors; import jdk.tools.jlink.internal.plugins.asm.AsmModulePool; import jdk.tools.jlink.plugin.PluginException; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; public class SortingTest extends AsmPluginTestBase { @@ -66,7 +67,7 @@ public class SortingTest extends AsmPluginTestBase { List<String> sorted = new ArrayList<>(getResources()); sorted.sort(null); ClassSorterPlugin sorterPlugin = new ClassSorterPlugin(sorted); - Pool resourcePool = sorterPlugin.visit(getPool()); + ModulePool resourcePool = sorterPlugin.visit(getPool()); sorterPlugin.test(getPool(), resourcePool); } @@ -78,7 +79,7 @@ public class SortingTest extends AsmPluginTestBase { List<String> sorted = new ArrayList<>(getResources()); sorted.sort((s1, s2) -> -getModuleName(s1).compareTo(getModuleName(s2))); ModuleSorterPlugin sorterPlugin = new ModuleSorterPlugin(); - Pool resourcePool = sorterPlugin.visit(getPool()); + ModulePool resourcePool = sorterPlugin.visit(getPool()); sorterPlugin.test(getPool(), resourcePool); } @@ -88,8 +89,8 @@ public class SortingTest extends AsmPluginTestBase { public void visit() { for (AsmModulePool modulePool : getPools().getModulePools()) { modulePool.setSorter(resources -> { - List<String> sort = resources.getContent().stream() - .map(ModuleData::getPath) + List<String> sort = resources.entries() + .map(ModuleEntry::getPath) .collect(Collectors.toList()); sort.sort(null); return sort; @@ -102,21 +103,21 @@ public class SortingTest extends AsmPluginTestBase { } @Override - public void test(Pool inResources, Pool outResources) throws Exception { + public void test(ModulePool inResources, ModulePool outResources) throws Exception { if (!isVisitCalled()) { throw new AssertionError("Resources not visited"); } - List<String> sortedResourcePaths = outResources.getContent().stream() - .map(ModuleData::getPath) + List<String> sortedResourcePaths = outResources.entries() + .map(ModuleEntry::getPath) .collect(Collectors.toList()); List<String> defaultResourceOrder = new ArrayList<>(); - for (ModuleData r : inResources.getContent()) { - if (!inResources.getContent().contains(r)) { + inResources.entries().forEach(r -> { + if (!inResources.contains(r)) { throw new AssertionError("Resource " + r.getPath() + " not in result pool"); } defaultResourceOrder.add(r.getPath()); - } + }); // Check that default sorting is not equal to sorted one if (defaultResourceOrder.equals(sortedResourcePaths)) { throw new AssertionError("Sorting not applied, default ordering"); @@ -147,27 +148,28 @@ public class SortingTest extends AsmPluginTestBase { public void visit() { getPools().getGlobalPool().setSorter( (resources) -> expectedClassesOrder.stream() - .map(resources::get) - .map(ModuleData::getPath) + .map(resources::findEntry) + .map(Optional::get) + .map(ModuleEntry::getPath) .collect(Collectors.toList())); } @Override - public void test(Pool inResources, Pool outResources) throws Exception { + public void test(ModulePool inResources, ModulePool outResources) throws Exception { if (!isVisitCalled()) { throw new AssertionError("Resources not visited"); } - List<String> sortedResourcePaths = outResources.getContent().stream() - .map(ModuleData::getPath) + List<String> sortedResourcePaths = outResources.entries() + .map(ModuleEntry::getPath) .collect(Collectors.toList()); List<String> defaultResourceOrder = new ArrayList<>(); - for (ModuleData r : getPool().getContent()) { - if (!getPool().getContent().contains(r)) { + getPool().entries().forEach(r -> { + if (!getPool().contains(r)) { throw new AssertionError("Resource " + r.getPath() + " not in result pool"); } defaultResourceOrder.add(r.getPath()); - } + }); // Check that default sorting is not equal to sorted one if (defaultResourceOrder.equals(sortedResourcePaths)) { throw new AssertionError("Sorting not applied, default ordering"); diff --git a/jdk/test/tools/jlink/asmplugin/VisitorTest.java b/jdk/test/tools/jlink/asmplugin/VisitorTest.java index 1b278a8bd48..500d415bc50 100644 --- a/jdk/test/tools/jlink/asmplugin/VisitorTest.java +++ b/jdk/test/tools/jlink/asmplugin/VisitorTest.java @@ -46,8 +46,8 @@ import jdk.tools.jlink.internal.plugins.asm.AsmPool.ClassReaderVisitor; import jdk.tools.jlink.internal.plugins.asm.AsmPool.ResourceFile; import jdk.tools.jlink.internal.plugins.asm.AsmPool.ResourceFileVisitor; import jdk.tools.jlink.internal.plugins.asm.AsmPools; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; public class VisitorTest extends AsmPluginTestBase { @@ -69,7 +69,7 @@ public class VisitorTest extends AsmPluginTestBase { }; for (TestPlugin p : plugins) { System.err.println("Testing: " + p.getName()); - Pool out = p.visit(getPool()); + ModulePool out = p.visit(getPool()); p.test(getPool(), out); } } @@ -149,15 +149,15 @@ public class VisitorTest extends AsmPluginTestBase { } @Override - public void test(Pool in, Pool out) throws Exception { - Collection<ModuleData> inClasses = getPool.apply(getPools()).getClasses(); + public void test(ModulePool in, ModulePool out) throws Exception { + Collection<ModuleEntry> inClasses = getPool.apply(getPools()).getClasses(); if (inClasses.size() != classReaderVisitor.getAmount()) { throw new AssertionError("Testing " + name + ". Number of visited classes. Expected: " + inClasses.size() + ", got: " + classReaderVisitor.getAmount()); } - Collection<ModuleData> outClasses = extractClasses(out); + Collection<ModuleEntry> outClasses = extractClasses(out); int changedClasses = 0; - for (ModuleData r : outClasses) { + for (ModuleEntry r : outClasses) { if (r.getPath().endsWith("Changed.class")) { ++changedClasses; } @@ -192,15 +192,15 @@ public class VisitorTest extends AsmPluginTestBase { } @Override - public void test(Pool in, Pool out) throws Exception { - Collection<ModuleData> inResources = getPool.apply(getPools()).getResourceFiles(); + public void test(ModulePool in, ModulePool out) throws Exception { + Collection<ModuleEntry> inResources = getPool.apply(getPools()).getResourceFiles(); if (inResources.size() != resourceFileVisitor.getAmount()) { throw new AssertionError("Testing " + name + ". Number of visited resources. Expected: " + inResources.size() + ", got: " + resourceFileVisitor.getAmount()); } - Collection<ModuleData> outResources = extractResources(out); + Collection<ModuleEntry> outResources = extractResources(out); int changedClasses = 0; - for (ModuleData r : outResources) { + for (ModuleEntry r : outResources) { if (r.getPath().endsWith("Changed")) { ++changedClasses; } diff --git a/jdk/test/tools/jlink/customplugin/plugin/CustomPlugin.java b/jdk/test/tools/jlink/customplugin/plugin/CustomPlugin.java index 38054ec2015..781039a517a 100644 --- a/jdk/test/tools/jlink/customplugin/plugin/CustomPlugin.java +++ b/jdk/test/tools/jlink/customplugin/plugin/CustomPlugin.java @@ -26,7 +26,9 @@ import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; -import jdk.tools.jlink.plugin.Pool; +import java.util.function.Function; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; public class CustomPlugin implements TransformerPlugin { @@ -37,13 +39,8 @@ public class CustomPlugin implements TransformerPlugin { } @Override - public void visit(Pool in, Pool out) { - in.visit(new Pool.Visitor() { - @Override - public Pool.ModuleData visit(Pool.ModuleData content) { - return content; - } - }, out); + public void visit(ModulePool in, ModulePool out) { + in.transformAndCopy(Function.identity(), out); } @Override @@ -61,9 +58,9 @@ public class CustomPlugin implements TransformerPlugin { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.PROCESSOR); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.PROCESSOR); return Collections.unmodifiableSet(set); } } diff --git a/jdk/test/tools/jlink/customplugin/plugin/HelloPlugin.java b/jdk/test/tools/jlink/customplugin/plugin/HelloPlugin.java index d06f99050b1..aa150350d7f 100644 --- a/jdk/test/tools/jlink/customplugin/plugin/HelloPlugin.java +++ b/jdk/test/tools/jlink/customplugin/plugin/HelloPlugin.java @@ -29,8 +29,8 @@ import java.util.Collections; import java.util.HashSet; import java.util.Map; import java.util.Set; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; /** @@ -49,23 +49,23 @@ public final class HelloPlugin implements TransformerPlugin { } @Override - public void visit(Pool inResources, Pool outResources) { + public void visit(ModulePool inResources, ModulePool outResources) { try { System.out.println("Hello!!!!!!!!!!"); File f = new File(OUTPUT_FILE); f.createNewFile(); - for (ModuleData res : inResources.getContent()) { + inResources.entries().forEach(res -> { outResources.add(res); - } + }); } catch (IOException ex) { throw new UncheckedIOException(ex); } } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.TRANSFORMER); return Collections.unmodifiableSet(set); } diff --git a/jdk/test/tools/jlink/plugins/CompressorPluginTest.java b/jdk/test/tools/jlink/plugins/CompressorPluginTest.java index cd01b93836b..d37bf1b73d2 100644 --- a/jdk/test/tools/jlink/plugins/CompressorPluginTest.java +++ b/jdk/test/tools/jlink/plugins/CompressorPluginTest.java @@ -53,14 +53,14 @@ import jdk.internal.jimage.decompressor.ResourceDecompressor; import jdk.internal.jimage.decompressor.ResourceDecompressorFactory; import jdk.internal.jimage.decompressor.StringSharingDecompressorFactory; import jdk.internal.jimage.decompressor.ZipDecompressorFactory; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.StringTable; import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin; import jdk.tools.jlink.internal.plugins.StringSharingPlugin; import jdk.tools.jlink.internal.plugins.ZipPlugin; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; public class CompressorPluginTest { @@ -86,7 +86,7 @@ public class CompressorPluginTest { new ZipDecompressorFactory() }); - Pool classes = gatherClasses(javabase); + ModulePool classes = gatherClasses(javabase); // compress = String sharing checkCompress(classes, new StringSharingPlugin(), null, new ResourceDecompressorFactory[]{ @@ -173,8 +173,8 @@ public class CompressorPluginTest { Collections.singletonList(".*IOException.class")); } - private Pool gatherResources(Path module) throws Exception { - Pool pool = new PoolImpl(ByteOrder.nativeOrder(), new StringTable() { + private ModulePool gatherResources(Path module) throws Exception { + ModulePool pool = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() { @Override public int addString(String str) { @@ -191,15 +191,15 @@ public class CompressorPluginTest { Path p = iterator.next(); if (Files.isRegularFile(p)) { byte[] content = Files.readAllBytes(p); - pool.add(Pool.newResource(p.toString(), content)); + pool.add(ModuleEntry.create(p.toString(), content)); } } } return pool; } - private Pool gatherClasses(Path module) throws Exception { - Pool pool = new PoolImpl(ByteOrder.nativeOrder(), new StringTable() { + private ModulePool gatherClasses(Path module) throws Exception { + ModulePool pool = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() { @Override public int addString(String str) { @@ -216,27 +216,27 @@ public class CompressorPluginTest { Path p = iterator.next(); if (Files.isRegularFile(p) && p.toString().endsWith(".class")) { byte[] content = Files.readAllBytes(p); - pool.add(Pool.newResource(p.toString(), content)); + pool.add(ModuleEntry.create(p.toString(), content)); } } } return pool; } - private void checkCompress(Pool resources, Plugin prov, + private void checkCompress(ModulePool resources, Plugin prov, Properties config, ResourceDecompressorFactory[] factories) throws Exception { checkCompress(resources, prov, config, factories, Collections.emptyList(), Collections.emptyList()); } - private void checkCompress(Pool resources, Plugin prov, + private void checkCompress(ModulePool resources, Plugin prov, Properties config, ResourceDecompressorFactory[] factories, List<String> includes, List<String> excludes) throws Exception { - long original = 0; - long compressed = 0; - for (ModuleData resource : resources.getContent()) { + long[] original = new long[1]; + long[] compressed = new long[1]; + resources.entries().forEach(resource -> { List<Pattern> includesPatterns = includes.stream() .map(Pattern::compile) .collect(Collectors.toList()); @@ -252,7 +252,7 @@ public class CompressorPluginTest { } prov.configure(props); final Map<Integer, String> strings = new HashMap<>(); - PoolImpl inputResources = new PoolImpl(ByteOrder.nativeOrder(), new StringTable() { + ModulePoolImpl inputResources = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() { @Override public int addString(String str) { int id = strID; @@ -267,32 +267,32 @@ public class CompressorPluginTest { } }); inputResources.add(resource); - Pool compressedResources = applyCompressor(prov, inputResources, resource, includesPatterns, excludesPatterns); - original += resource.getLength(); - compressed += compressedResources.get(resource.getPath()).getLength(); + ModulePool compressedResources = applyCompressor(prov, inputResources, resource, includesPatterns, excludesPatterns); + original[0] += resource.getLength(); + compressed[0] += compressedResources.findEntry(resource.getPath()).get().getLength(); applyDecompressors(factories, inputResources, compressedResources, strings, includesPatterns, excludesPatterns); - } + }); String compressors = Stream.of(factories) .map(Object::getClass) .map(Class::getSimpleName) .collect(Collectors.joining(", ")); - String size = "Compressed size: " + compressed + ", original size: " + original; + String size = "Compressed size: " + compressed[0] + ", original size: " + original[0]; System.out.println("Used " + compressors + ". " + size); - if (original <= compressed) { + if (original[0] <= compressed[0]) { throw new AssertionError("java.base not compressed."); } } - private Pool applyCompressor(Plugin plugin, - PoolImpl inputResources, - ModuleData res, + private ModulePool applyCompressor(Plugin plugin, + ModulePoolImpl inputResources, + ModuleEntry res, List<Pattern> includesPatterns, - List<Pattern> excludesPatterns) throws Exception { + List<Pattern> excludesPatterns) { TransformerPlugin compressor = (TransformerPlugin) plugin; - Pool compressedPool = new PoolImpl(ByteOrder.nativeOrder(), inputResources.getStringTable()); - compressor.visit(inputResources, compressedPool); + ModulePool compressedModulePool = new ModulePoolImpl(ByteOrder.nativeOrder(), inputResources.getStringTable()); + compressor.visit(inputResources, compressedModulePool); String path = res.getPath(); - ModuleData compressed = compressedPool.get(path); + ModuleEntry compressed = compressedModulePool.findEntry(path).get(); CompressedResourceHeader header = CompressedResourceHeader.readFromResource(ByteOrder.nativeOrder(), compressed.getBytes()); if (isIncluded(includesPatterns, excludesPatterns, path)) { @@ -310,29 +310,33 @@ public class CompressorPluginTest { } else if (header != null) { throw new AssertionError("Path should not be compressed: " + path); } - return compressedPool; + return compressedModulePool; } private void applyDecompressors(ResourceDecompressorFactory[] decompressors, - Pool inputResources, - Pool compressedResources, + ModulePool inputResources, + ModulePool compressedResources, Map<Integer, String> strings, List<Pattern> includesPatterns, - List<Pattern> excludesPatterns) throws Exception { - for (ModuleData compressed : compressedResources.getContent()) { + List<Pattern> excludesPatterns) { + compressedResources.entries().forEach(compressed -> { CompressedResourceHeader header = CompressedResourceHeader.readFromResource( ByteOrder.nativeOrder(), compressed.getBytes()); String path = compressed.getPath(); - ModuleData orig = inputResources.get(path); + ModuleEntry orig = inputResources.findEntry(path).get(); if (!isIncluded(includesPatterns, excludesPatterns, path)) { - continue; + return; } byte[] decompressed = compressed.getBytes(); for (ResourceDecompressorFactory factory : decompressors) { - ResourceDecompressor decompressor = factory.newDecompressor(new Properties()); - decompressed = decompressor.decompress( + try { + ResourceDecompressor decompressor = factory.newDecompressor(new Properties()); + decompressed = decompressor.decompress( strings::get, decompressed, CompressedResourceHeader.getSize(), header.getUncompressedSize()); + } catch (Exception exp) { + throw new RuntimeException(exp); + } } if (decompressed.length != orig.getLength()) { @@ -345,7 +349,7 @@ public class CompressorPluginTest { throw new AssertionError("Decompressed and original differ at index " + i); } } - } + }); } private boolean isIncluded(List<Pattern> includesPatterns, List<Pattern> excludesPatterns, String path) { diff --git a/jdk/test/tools/jlink/plugins/ExcludeFilesPluginTest.java b/jdk/test/tools/jlink/plugins/ExcludeFilesPluginTest.java index cde83aa2761..744d7a2ba25 100644 --- a/jdk/test/tools/jlink/plugins/ExcludeFilesPluginTest.java +++ b/jdk/test/tools/jlink/plugins/ExcludeFilesPluginTest.java @@ -35,12 +35,11 @@ import java.io.File; import java.nio.file.Files; import java.util.HashMap; import java.util.Map; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; public class ExcludeFilesPluginTest { @@ -73,20 +72,20 @@ public class ExcludeFilesPluginTest { prop.put(ExcludeFilesPlugin.NAME, s); ExcludeFilesPlugin fplug = new ExcludeFilesPlugin(); fplug.configure(prop); - PoolImpl files = new PoolImpl(); - PoolImpl fresult = new PoolImpl(); - ModuleData f = Pool.newImageFile(module, "/" + module + "/" + sample, - ModuleDataType.CONFIG, new ByteArrayInputStream(new byte[0]), 0); + ModulePoolImpl files = new ModulePoolImpl(); + ModulePoolImpl fresult = new ModulePoolImpl(); + ModuleEntry f = ModuleEntry.create(module, "/" + module + "/" + sample, + ModuleEntry.Type.CONFIG, new ByteArrayInputStream(new byte[0]), 0); files.add(f); fplug.visit(files, fresult); if (exclude) { - if (fresult.getContent().contains(f)) { + if (fresult.contains(f)) { throw new Exception(sample + " should be excluded by " + s); } } else { - if (!fresult.getContent().contains(f)) { + if (!fresult.contains(f)) { throw new Exception(sample + " shouldn't be excluded by " + s); } } diff --git a/jdk/test/tools/jlink/plugins/ExcludePluginTest.java b/jdk/test/tools/jlink/plugins/ExcludePluginTest.java index 0f508073288..c39e738e079 100644 --- a/jdk/test/tools/jlink/plugins/ExcludePluginTest.java +++ b/jdk/test/tools/jlink/plugins/ExcludePluginTest.java @@ -34,11 +34,11 @@ import java.io.File; import java.nio.file.Files; import java.util.HashMap; import java.util.Map; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.plugins.ExcludePlugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; public class ExcludePluginTest { @@ -75,17 +75,17 @@ public class ExcludePluginTest { prop.put(ExcludePlugin.NAME, s); ExcludePlugin excludePlugin = new ExcludePlugin(); excludePlugin.configure(prop); - Pool resources = new PoolImpl(); - ModuleData resource = Pool.newResource(sample, new byte[0]); + ModulePool resources = new ModulePoolImpl(); + ModuleEntry resource = ModuleEntry.create(sample, new byte[0]); resources.add(resource); - Pool result = new PoolImpl(); + ModulePool result = new ModulePoolImpl(); excludePlugin.visit(resources, result); if (exclude) { - if (result.getContent().contains(resource)) { + if (result.contains(resource)) { throw new AssertionError(sample + " should be excluded by " + s); } } else { - if (!result.getContent().contains(resource)) { + if (!result.contains(resource)) { throw new AssertionError(sample + " shouldn't be excluded by " + s); } } diff --git a/jdk/test/tools/jlink/plugins/ExcludeVMPluginTest.java b/jdk/test/tools/jlink/plugins/ExcludeVMPluginTest.java index 701368c3dd0..edc10702eb3 100644 --- a/jdk/test/tools/jlink/plugins/ExcludeVMPluginTest.java +++ b/jdk/test/tools/jlink/plugins/ExcludeVMPluginTest.java @@ -32,13 +32,12 @@ import java.io.ByteArrayInputStream; import java.util.HashMap; import java.util.Map; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.plugins.ExcludeVMPlugin; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.plugin.ModulePool; +import jdk.tools.jlink.plugin.ModuleEntry; import jdk.tools.jlink.plugin.TransformerPlugin; public class ExcludeVMPluginTest { @@ -165,14 +164,14 @@ public class ExcludeVMPluginTest { private void doCheckVM(String vm, String[] input, String jvmcfg, String[] expectedOutput, String expectdJvmCfg) throws Exception { // Create a pool with jvm.cfg and the input paths. byte[] jvmcfgContent = jvmcfg.getBytes(); - Pool pool = new PoolImpl(); - pool.add(Pool.newImageFile("java.base", "/java.base/native/jvm.cfg", - ModuleDataType.NATIVE_LIB, new ByteArrayInputStream(jvmcfgContent), jvmcfgContent.length)); + ModulePool pool = new ModulePoolImpl(); + pool.add(ModuleEntry.create("java.base", "/java.base/native/jvm.cfg", + ModuleEntry.Type.NATIVE_LIB, new ByteArrayInputStream(jvmcfgContent), jvmcfgContent.length)); for (String in : input) { - pool.add(Pool.newImageFile("java.base", in, - ModuleDataType.NATIVE_LIB, new ByteArrayInputStream(new byte[0]), 0)); + pool.add(ModuleEntry.create("java.base", in, + ModuleEntry.Type.NATIVE_LIB, new ByteArrayInputStream(new byte[0]), 0)); } - Pool out = new PoolImpl(); + ModulePool out = new ModulePoolImpl(); TransformerPlugin p = new ExcludeVMPlugin(); Map<String, String> config = new HashMap<>(); @@ -182,22 +181,22 @@ public class ExcludeVMPluginTest { p.configure(config); p.visit(pool, out); - String newContent = new String(out.get("/java.base/native/jvm.cfg").stream().readAllBytes()); + String newContent = new String(out.findEntry("/java.base/native/jvm.cfg").get().stream().readAllBytes()); if (!expectdJvmCfg.equals(newContent)) { throw new Exception("Got content " + newContent + " expected " + expectdJvmCfg); } - if (out.getContent().size() != (expectedOutput.length + 1)) { - for (ModuleData m : out.getContent()) { + if (out.getEntryCount() != (expectedOutput.length + 1)) { + out.entries().forEach(m -> { System.err.println(m.getPath()); - } - throw new Exception("Invalid output size " + out.getContent().size() + " expected " + (expectedOutput.length + 1)); + }); + throw new Exception("Invalid output size " + out.getEntryCount() + " expected " + (expectedOutput.length + 1)); } - for (ModuleData md : out.getContent()) { + out.entries().forEach(md -> { if (md.getPath().equals("/java.base/native/jvm.cfg")) { - continue; + return; } boolean contained = false; for (String o : expectedOutput) { @@ -207,9 +206,9 @@ public class ExcludeVMPluginTest { } } if (!contained) { - throw new Exception(md.getPath() + " not expected"); + throw new RuntimeException(md.getPath() + " not expected"); } - } + }); } diff --git a/jdk/test/tools/jlink/plugins/FileCopierPluginTest.java b/jdk/test/tools/jlink/plugins/FileCopierPluginTest.java index 5fecfec388b..a6fb749ba7f 100644 --- a/jdk/test/tools/jlink/plugins/FileCopierPluginTest.java +++ b/jdk/test/tools/jlink/plugins/FileCopierPluginTest.java @@ -26,6 +26,7 @@ * @summary Test files copy plugin * @author Jean-Francois Denise * @modules jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink.builder * jdk.jlink/jdk.tools.jlink.internal.plugins * @run main FileCopierPluginTest */ @@ -36,13 +37,12 @@ import java.nio.file.Path; import java.util.Collections; import java.util.HashMap; import java.util.Map; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.builder.DefaultImageBuilder; import jdk.tools.jlink.internal.plugins.FileCopierPlugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; -import jdk.tools.jlink.plugin.Pool.ModuleDataType; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; public class FileCopierPluginTest { @@ -85,21 +85,20 @@ public class FileCopierPluginTest { Map<String, String> conf = new HashMap<>(); conf.put(FileCopierPlugin.NAME, builder.toString()); plug.configure(conf); - Pool pool = new PoolImpl(); - plug.visit(new PoolImpl(), pool); - if (pool.getContent().size() != expected) { + ModulePool pool = new ModulePoolImpl(); + plug.visit(new ModulePoolImpl(), pool); + if (pool.getEntryCount() != expected) { throw new AssertionError("Wrong number of added files"); } - for (ModuleData f : pool.getContent()) { - if (!f.getType().equals(ModuleDataType.OTHER)) { + pool.entries().forEach(f -> { + if (!f.getType().equals(ModuleEntry.Type.OTHER)) { throw new AssertionError("Invalid type " + f.getType() + " for file " + f.getPath()); } if (f.stream() == null) { throw new AssertionError("Null stream for file " + f.getPath()); } - - } + }); Path root = new File(".").toPath(); DefaultImageBuilder imgbuilder = new DefaultImageBuilder(root); imgbuilder.storeFiles(pool); diff --git a/jdk/test/tools/jlink/plugins/LastSorterTest.java b/jdk/test/tools/jlink/plugins/LastSorterTest.java index 100ca1e4674..0dc27b44ec8 100644 --- a/jdk/test/tools/jlink/plugins/LastSorterTest.java +++ b/jdk/test/tools/jlink/plugins/LastSorterTest.java @@ -26,6 +26,7 @@ * @summary Test last sorter property * @author Jean-Francois Denise * @modules jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink * @run main/othervm LastSorterTest */ @@ -40,12 +41,12 @@ import java.util.Set; import jdk.tools.jlink.internal.ImagePluginConfiguration; import jdk.tools.jlink.internal.PluginRepository; import jdk.tools.jlink.internal.ImagePluginStack; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.Jlink; import jdk.tools.jlink.Jlink.PluginsConfiguration; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; public class LastSorterTest { @@ -80,7 +81,7 @@ public class LastSorterTest { ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config); // check order - PoolImpl res = fillOutResourcePool(); + ModulePoolImpl res = fillOutResourceModulePool(); try { stack.visitResources(res); @@ -91,18 +92,18 @@ public class LastSorterTest { } } - private PoolImpl fillOutResourcePool() throws Exception { - PoolImpl res = new PoolImpl(); - res.add(Pool.newResource("/eee/bbb/res1.class", new byte[90])); - res.add(Pool.newResource("/aaaa/bbb/res2.class", new byte[90])); - res.add(Pool.newResource("/bbb/aa/res1.class", new byte[90])); - res.add(Pool.newResource("/aaaa/bbb/res3.class", new byte[90])); - res.add(Pool.newResource("/bbb/aa/res2.class", new byte[90])); - res.add(Pool.newResource("/fff/bbb/res1.class", new byte[90])); - res.add(Pool.newResource("/aaaa/bbb/res1.class", new byte[90])); - res.add(Pool.newResource("/bbb/aa/res3.class", new byte[90])); - res.add(Pool.newResource("/ccc/bbb/res1.class", new byte[90])); - res.add(Pool.newResource("/ddd/bbb/res1.class", new byte[90])); + private ModulePoolImpl fillOutResourceModulePool() throws Exception { + ModulePoolImpl res = new ModulePoolImpl(); + res.add(ModuleEntry.create("/eee/bbb/res1.class", new byte[90])); + res.add(ModuleEntry.create("/aaaa/bbb/res2.class", new byte[90])); + res.add(ModuleEntry.create("/bbb/aa/res1.class", new byte[90])); + res.add(ModuleEntry.create("/aaaa/bbb/res3.class", new byte[90])); + res.add(ModuleEntry.create("/bbb/aa/res2.class", new byte[90])); + res.add(ModuleEntry.create("/fff/bbb/res1.class", new byte[90])); + res.add(ModuleEntry.create("/aaaa/bbb/res1.class", new byte[90])); + res.add(ModuleEntry.create("/bbb/aa/res3.class", new byte[90])); + res.add(ModuleEntry.create("/ccc/bbb/res1.class", new byte[90])); + res.add(ModuleEntry.create("/ddd/bbb/res1.class", new byte[90])); return res; } @@ -124,7 +125,7 @@ public class LastSorterTest { ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config); // check order - PoolImpl res = fillOutResourcePool(); + ModulePoolImpl res = fillOutResourceModulePool(); stack.visitResources(res); } @@ -159,7 +160,7 @@ public class LastSorterTest { ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(config); // check order - PoolImpl res = fillOutResourcePool(); + ModulePoolImpl res = fillOutResourceModulePool(); try { stack.visitResources(res); throw new AssertionError("Order was changed after the last sorter, but no exception occurred"); @@ -178,17 +179,17 @@ public class LastSorterTest { } @Override - public void visit(Pool resources, Pool output) { - List<ModuleData> paths = new ArrayList<>(); - for (ModuleData res : resources.getContent()) { + public void visit(ModulePool resources, ModulePool output) { + List<ModuleEntry> paths = new ArrayList<>(); + resources.entries().forEach(res -> { if (res.getPath().startsWith(starts)) { paths.add(0, res); } else { paths.add(res); } - } + }); - for (ModuleData r : paths) { + for (ModuleEntry r : paths) { output.add(r); } } @@ -199,9 +200,9 @@ public class LastSorterTest { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.TRANSFORMER); return Collections.unmodifiableSet(set); } diff --git a/jdk/test/tools/jlink/plugins/OrderResourcesPluginTest.java b/jdk/test/tools/jlink/plugins/OrderResourcesPluginTest.java index cbf418669c0..701736139c6 100644 --- a/jdk/test/tools/jlink/plugins/OrderResourcesPluginTest.java +++ b/jdk/test/tools/jlink/plugins/OrderResourcesPluginTest.java @@ -36,11 +36,12 @@ import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; -import jdk.tools.jlink.internal.PoolImpl; +import java.util.stream.Collectors; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.plugins.OrderResourcesPlugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; public class OrderResourcesPluginTest { @@ -50,52 +51,52 @@ public class OrderResourcesPluginTest { } public void test() throws Exception { - ModuleData[] array = { - Pool.newResource("/module1/toto1.class", new byte[0]), - Pool.newResource("/module2/toto2.class", new byte[0]), - Pool.newResource("/module3/toto3.class", new byte[0]), - Pool.newResource("/module3/toto3/module-info.class", new byte[0]), - Pool.newResource("/zazou/toto.class", new byte[0]), - Pool.newResource("/module4/zazou.class", new byte[0]), - Pool.newResource("/module5/toto5.class", new byte[0]), - Pool.newResource("/module6/toto6/module-info.class", new byte[0]) + ModuleEntry[] array = { + ModuleEntry.create("/module1/toto1.class", new byte[0]), + ModuleEntry.create("/module2/toto2.class", new byte[0]), + ModuleEntry.create("/module3/toto3.class", new byte[0]), + ModuleEntry.create("/module3/toto3/module-info.class", new byte[0]), + ModuleEntry.create("/zazou/toto.class", new byte[0]), + ModuleEntry.create("/module4/zazou.class", new byte[0]), + ModuleEntry.create("/module5/toto5.class", new byte[0]), + ModuleEntry.create("/module6/toto6/module-info.class", new byte[0]) }; - ModuleData[] sorted = { - Pool.newResource("/zazou/toto.class", new byte[0]), - Pool.newResource("/module3/toto3/module-info.class", new byte[0]), - Pool.newResource("/module6/toto6/module-info.class", new byte[0]), - Pool.newResource("/module1/toto1.class", new byte[0]), - Pool.newResource("/module2/toto2.class", new byte[0]), - Pool.newResource("/module3/toto3.class", new byte[0]), - Pool.newResource("/module4/zazou.class", new byte[0]), - Pool.newResource("/module5/toto5.class", new byte[0]) + ModuleEntry[] sorted = { + ModuleEntry.create("/zazou/toto.class", new byte[0]), + ModuleEntry.create("/module3/toto3/module-info.class", new byte[0]), + ModuleEntry.create("/module6/toto6/module-info.class", new byte[0]), + ModuleEntry.create("/module1/toto1.class", new byte[0]), + ModuleEntry.create("/module2/toto2.class", new byte[0]), + ModuleEntry.create("/module3/toto3.class", new byte[0]), + ModuleEntry.create("/module4/zazou.class", new byte[0]), + ModuleEntry.create("/module5/toto5.class", new byte[0]) }; - ModuleData[] sorted2 = { - Pool.newResource("/module5/toto5.class", new byte[0]), - Pool.newResource("/module6/toto6/module-info.class", new byte[0]), - Pool.newResource("/module4/zazou.class", new byte[0]), - Pool.newResource("/module3/toto3.class", new byte[0]), - Pool.newResource("/module3/toto3/module-info.class", new byte[0]), - Pool.newResource("/module1/toto1.class", new byte[0]), - Pool.newResource("/module2/toto2.class", new byte[0]), - Pool.newResource("/zazou/toto.class", new byte[0]) + ModuleEntry[] sorted2 = { + ModuleEntry.create("/module5/toto5.class", new byte[0]), + ModuleEntry.create("/module6/toto6/module-info.class", new byte[0]), + ModuleEntry.create("/module4/zazou.class", new byte[0]), + ModuleEntry.create("/module3/toto3.class", new byte[0]), + ModuleEntry.create("/module3/toto3/module-info.class", new byte[0]), + ModuleEntry.create("/module1/toto1.class", new byte[0]), + ModuleEntry.create("/module2/toto2.class", new byte[0]), + ModuleEntry.create("/zazou/toto.class", new byte[0]) }; - Pool resources = new PoolImpl(); - for (ModuleData r : array) { + ModulePool resources = new ModulePoolImpl(); + for (ModuleEntry r : array) { resources.add(r); } { - Pool out = new PoolImpl(); + ModulePool out = new ModulePoolImpl(); Map<String, String> config = new HashMap<>(); config.put(OrderResourcesPlugin.NAME, "/zazou/*,*/module-info.class"); TransformerPlugin p = new OrderResourcesPlugin(); p.configure(config); p.visit(resources, out); - check(out.getContent(), sorted); + check(out.entries().collect(Collectors.toList()), sorted); } { @@ -112,26 +113,26 @@ public class OrderResourcesPluginTest { } Files.write(order.toPath(), builder.toString().getBytes()); - Pool out = new PoolImpl(); + ModulePool out = new ModulePoolImpl(); Map<String, String> config = new HashMap<>(); config.put(OrderResourcesPlugin.NAME, "@" + order.getAbsolutePath()); TransformerPlugin p = new OrderResourcesPlugin(); p.configure(config); p.visit(resources, out); - check(out.getContent(), sorted2); + check(out.entries().collect(Collectors.toList()), sorted2); } } - private void check(Collection<ModuleData> outResources, - ModuleData[] sorted) { + private void check(Collection<ModuleEntry> outResources, + ModuleEntry[] sorted) { if (outResources.size() != sorted.length) { throw new AssertionError("Wrong number of resources:\n" + "expected: " + Arrays.toString(sorted) + ",\n" + " got: " + outResources); } int i = 0; - for (ModuleData r : outResources) { + for (ModuleEntry r : outResources) { System.err.println("Resource: " + r); if (!sorted[i].getPath().equals(r.getPath())) { throw new AssertionError("Resource not properly sorted, difference at: " + i + "\n" diff --git a/jdk/test/tools/jlink/plugins/PluginOrderTest.java b/jdk/test/tools/jlink/plugins/PluginOrderTest.java index 42655d408fe..4c9f2c2241d 100644 --- a/jdk/test/tools/jlink/plugins/PluginOrderTest.java +++ b/jdk/test/tools/jlink/plugins/PluginOrderTest.java @@ -44,8 +44,8 @@ import java.util.Set; import jdk.tools.jlink.internal.PluginOrderingGraph; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.Plugin.CATEGORY; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.Plugin.Category; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; public class PluginOrderTest { @@ -96,8 +96,8 @@ public class PluginOrderTest { set.add("plug2"); List<Plugin> plugins = new ArrayList<>(); plugins.add(new Plug("plug2", Collections.emptySet(), Collections.emptySet(), - CATEGORY.TRANSFORMER)); - plugins.add(new Plug("plug1", set, Collections.emptySet(), CATEGORY.TRANSFORMER)); + Category.TRANSFORMER)); + plugins.add(new Plug("plug1", set, Collections.emptySet(), Category.TRANSFORMER)); List<Plugin> ordered = PluginOrderingGraph.sort(plugins); if (ordered.get(0) != plugins.get(1) || ordered.get(1) != plugins.get(0)) { throw new Exception("Invalid sorting"); @@ -108,32 +108,32 @@ public class PluginOrderTest { Set<String> lst1 = new HashSet<>(); lst1.add("plug2"); lst1.add("plug3"); - Plugin p1 = new Plug("plug1", lst1, Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p1 = new Plug("plug1", lst1, Collections.emptySet(), Category.TRANSFORMER); - Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER); Set<String> lst3 = new HashSet<>(); lst3.add("plug4"); lst3.add("plug6"); - Plugin p3 = new Plug("plug3", lst3, Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p3 = new Plug("plug3", lst3, Collections.emptySet(), Category.TRANSFORMER); - Plugin p4 = new Plug("plug4", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p4 = new Plug("plug4", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER); Set<String> lst5 = new HashSet<>(); lst5.add("plug3"); lst5.add("plug1"); lst5.add("plug2"); lst5.add("plug6"); - Plugin p5 = new Plug("plug5", lst5, Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p5 = new Plug("plug5", lst5, Collections.emptySet(), Category.TRANSFORMER); Set<String> lst6 = new HashSet<>(); lst6.add("plug4"); lst6.add("plug2"); - Plugin p6 = new Plug("plug6", lst6, Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p6 = new Plug("plug6", lst6, Collections.emptySet(), Category.TRANSFORMER); - Plugin p7 = new Plug("plug7", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p7 = new Plug("plug7", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER); - Plugin p8 = new Plug("plug8", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p8 = new Plug("plug8", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER); List<Plugin> plugins = new ArrayList<>(); plugins.add(p1); @@ -153,11 +153,11 @@ public class PluginOrderTest { set2.add("plug1"); List<Plugin> plugins = new ArrayList<>(); plugins.add(new Plug("plug2", set2, Collections.emptySet(), - CATEGORY.TRANSFORMER)); + Category.TRANSFORMER)); Set<String> set1 = new HashSet<>(); set1.add("plug2"); - plugins.add(new Plug("plug1", set1, Collections.emptySet(), CATEGORY.TRANSFORMER)); + plugins.add(new Plug("plug1", set1, Collections.emptySet(), Category.TRANSFORMER)); PluginOrderingGraph.sort(plugins); } @@ -166,31 +166,31 @@ public class PluginOrderTest { Set<String> lst1 = new HashSet<>(); lst1.add("plug2"); lst1.add("plug3"); - Plugin p1 = new Plug("plug1", lst1, Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p1 = new Plug("plug1", lst1, Collections.emptySet(), Category.TRANSFORMER); - Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER); Set<String> lst3 = new HashSet<>(); lst3.add("plug4"); lst3.add("plug6"); - Plugin p3 = new Plug("plug3", lst3, Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p3 = new Plug("plug3", lst3, Collections.emptySet(), Category.TRANSFORMER); - Plugin p4 = new Plug("plug4", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p4 = new Plug("plug4", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER); Set<String> lst5 = new HashSet<>(); lst5.add("plug3"); lst5.add("plug1"); lst5.add("plug2"); - Plugin p5 = new Plug("plug5", lst5, Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p5 = new Plug("plug5", lst5, Collections.emptySet(), Category.TRANSFORMER); Set<String> lst6 = new HashSet<>(); lst6.add("plug4"); lst6.add("plug1"); - Plugin p6 = new Plug("plug6", lst6, Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p6 = new Plug("plug6", lst6, Collections.emptySet(), Category.TRANSFORMER); - Plugin p7 = new Plug("plug7", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p7 = new Plug("plug7", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER); - Plugin p8 = new Plug("plug8", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p8 = new Plug("plug8", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER); List<Plugin> plugins = new ArrayList<>(); plugins.add(p1); @@ -208,8 +208,8 @@ public class PluginOrderTest { Set<String> lst1 = new HashSet<>(); lst1.add("plug2"); lst1.add("plug3"); - Plugin p = new Plug("plug1", lst1, Collections.emptySet(), CATEGORY.TRANSFORMER); - Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), CATEGORY.TRANSFORMER); + Plugin p = new Plug("plug1", lst1, Collections.emptySet(), Category.TRANSFORMER); + Plugin p2 = new Plug("plug2", Collections.emptySet(), Collections.emptySet(), Category.TRANSFORMER); Set<String> lst3 = new HashSet<>(); lst3.add("plug2"); @@ -217,7 +217,7 @@ public class PluginOrderTest { Set<String> lst4 = new HashSet<>(); lst4.add("plug1"); - Plugin p3 = new Plug("plug3", lst4, lst3, CATEGORY.TRANSFORMER); + Plugin p3 = new Plug("plug3", lst4, lst3, Category.TRANSFORMER); List<Plugin> plugins = new ArrayList<>(); plugins.add(p); plugins.add(p2); @@ -229,10 +229,10 @@ public class PluginOrderTest { private final Set<String> isBefore; private final Set<String> isAfter; - private final CATEGORY category; + private final Category category; private final String name; - private Plug(String name, Set<String> isBefore, Set<String> isAfter, CATEGORY category) { + private Plug(String name, Set<String> isBefore, Set<String> isAfter, Category category) { this.name = name; this.isBefore = isBefore; this.isAfter = isAfter; @@ -255,12 +255,12 @@ public class PluginOrderTest { } @Override - public void visit(Pool in, Pool out) { + public void visit(ModulePool in, ModulePool out) { } @Override - public Set<PluginType> getType() { + public Set<Category> getType() { return Collections.singleton(category); } diff --git a/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java b/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java index 525fb0b5ce2..5b8ed2d6c83 100644 --- a/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java +++ b/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java @@ -26,6 +26,7 @@ * @summary Negative test for ImagePluginStack. * @author Andrei Eremeev * @modules jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink * @run main/othervm PluginsNegativeTest */ import java.lang.reflect.Layer; @@ -39,11 +40,12 @@ import java.util.Set; import jdk.tools.jlink.internal.ImagePluginConfiguration; import jdk.tools.jlink.internal.PluginRepository; import jdk.tools.jlink.internal.ImagePluginStack; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.Jlink; import jdk.tools.jlink.Jlink.PluginsConfiguration; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.Pool; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; public class PluginsNegativeTest { @@ -96,8 +98,8 @@ public class PluginsNegativeTest { plugins.add(createPlugin("plugin")); ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new PluginsConfiguration(plugins, null, null)); - PoolImpl inResources = new PoolImpl(); - inResources.add(Pool.newResource("/aaa/bbb/A", new byte[10])); + ModulePoolImpl inResources = new ModulePoolImpl(); + inResources.add(ModuleEntry.create("/aaa/bbb/A", new byte[10])); try { stack.visitResources(inResources); throw new AssertionError("Exception expected when output resource is empty"); @@ -110,8 +112,8 @@ public class PluginsNegativeTest { plugins.add(createPlugin("plugin")); ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new PluginsConfiguration(plugins, null, null)); - PoolImpl inResources = new PoolImpl(); - PoolImpl outResources = (PoolImpl) stack.visitResources(inResources); + ModulePoolImpl inResources = new ModulePoolImpl(); + ModulePoolImpl outResources = (ModulePoolImpl) stack.visitResources(inResources); if (!outResources.isEmpty()) { throw new AssertionError("Output resource is not empty"); } @@ -126,7 +128,7 @@ public class PluginsNegativeTest { } @Override - public void visit(Pool inResources, Pool outResources) { + public void visit(ModulePool inResources, ModulePool outResources) { // do nothing } @@ -136,9 +138,9 @@ public class PluginsNegativeTest { } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.TRANSFORMER); return Collections.unmodifiableSet(set); } diff --git a/jdk/test/tools/jlink/plugins/PrevisitorTest.java b/jdk/test/tools/jlink/plugins/PrevisitorTest.java index 16d79f0c068..1f721d66d5f 100644 --- a/jdk/test/tools/jlink/plugins/PrevisitorTest.java +++ b/jdk/test/tools/jlink/plugins/PrevisitorTest.java @@ -26,6 +26,7 @@ * @summary Test previsitor * @author Andrei Eremeev * @modules jdk.jlink/jdk.tools.jlink.internal + * jdk.jlink/jdk.tools.jlink * @run main/othervm PrevisitorTest */ import java.nio.ByteOrder; @@ -36,19 +37,20 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import jdk.tools.jlink.internal.ImagePluginConfiguration; import jdk.tools.jlink.internal.PluginRepository; import jdk.tools.jlink.internal.ImagePluginStack; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.ResourcePrevisitor; import jdk.tools.jlink.internal.StringTable; import jdk.tools.jlink.Jlink; import jdk.tools.jlink.plugin.Plugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; public class PrevisitorTest { @@ -68,17 +70,17 @@ public class PrevisitorTest { plugins.add(createPlugin(CustomPlugin.NAME)); ImagePluginStack stack = ImagePluginConfiguration.parseConfiguration(new Jlink.PluginsConfiguration(plugins, null, null)); - PoolImpl inResources = new PoolImpl(ByteOrder.nativeOrder(), new CustomStringTable()); - inResources.add(Pool.newResource("/aaa/bbb/res1.class", new byte[90])); - inResources.add(Pool.newResource("/aaa/bbb/res2.class", new byte[90])); - inResources.add(Pool.newResource("/aaa/bbb/res3.class", new byte[90])); - inResources.add(Pool.newResource("/aaa/ddd/res1.class", new byte[90])); - inResources.add(Pool.newResource("/aaa/res1.class", new byte[90])); - Pool outResources = stack.visitResources(inResources); - Collection<String> input = inResources.getContent().stream() + ModulePoolImpl inResources = new ModulePoolImpl(ByteOrder.nativeOrder(), new CustomStringTable()); + inResources.add(ModuleEntry.create("/aaa/bbb/res1.class", new byte[90])); + inResources.add(ModuleEntry.create("/aaa/bbb/res2.class", new byte[90])); + inResources.add(ModuleEntry.create("/aaa/bbb/res3.class", new byte[90])); + inResources.add(ModuleEntry.create("/aaa/ddd/res1.class", new byte[90])); + inResources.add(ModuleEntry.create("/aaa/res1.class", new byte[90])); + ModulePool outResources = stack.visitResources(inResources); + Collection<String> input = inResources.entries() .map(Object::toString) .collect(Collectors.toList()); - Collection<String> output = outResources.getContent().stream() + Collection<String> output = outResources.entries() .map(Object::toString) .collect(Collectors.toList()); if (!input.equals(output)) { @@ -114,19 +116,20 @@ public class PrevisitorTest { private boolean isPrevisitCalled = false; @Override - public void visit(Pool inResources, Pool outResources) { + public void visit(ModulePool inResources, ModulePool outResources) { if (!isPrevisitCalled) { throw new AssertionError("Previsit was not called"); } CustomStringTable table = (CustomStringTable) - ((PoolImpl) inResources).getStringTable(); + ((ModulePoolImpl) inResources).getStringTable(); if (table.size() == 0) { throw new AssertionError("Table is empty"); } Map<String, Integer> count = new HashMap<>(); for (int i = 0; i < table.size(); ++i) { String s = table.getString(i); - if (inResources.get(s) != null) { + Optional<ModuleEntry> e = inResources.findEntry(s); + if (e.isPresent()) { throw new AssertionError(); } count.compute(s, (k, c) -> 1 + (c == null ? 0 : c)); @@ -136,9 +139,9 @@ public class PrevisitorTest { throw new AssertionError("Expected one entry in the table, got: " + v + " for " + k); } }); - for (ModuleData r : inResources.getContent()) { + inResources.entries().forEach(r -> { outResources.add(r); - } + }); } @Override @@ -147,21 +150,21 @@ public class PrevisitorTest { } @Override - public void previsit(Pool resources, StringTable strings) { + public void previsit(ModulePool resources, StringTable strings) { isPrevisitCalled = true; - for (ModuleData r : resources.getContent()) { + resources.entries().forEach(r -> { String s = r.getPath(); int lastIndexOf = s.lastIndexOf('/'); if (lastIndexOf >= 0) { strings.addString(s.substring(0, lastIndexOf)); } - } + }); } @Override - public Set<PluginType> getType() { - Set<PluginType> set = new HashSet<>(); - set.add(CATEGORY.TRANSFORMER); + public Set<Category> getType() { + Set<Category> set = new HashSet<>(); + set.add(Category.TRANSFORMER); return Collections.unmodifiableSet(set); } } diff --git a/jdk/test/tools/jlink/plugins/StringSharingPluginTest.java b/jdk/test/tools/jlink/plugins/StringSharingPluginTest.java index 786da460990..c02a8e6db0c 100644 --- a/jdk/test/tools/jlink/plugins/StringSharingPluginTest.java +++ b/jdk/test/tools/jlink/plugins/StringSharingPluginTest.java @@ -38,6 +38,8 @@ * @run main StringSharingPluginTest */ +import java.io.IOException; +import java.io.UncheckedIOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.file.Files; @@ -50,11 +52,11 @@ import java.util.function.Consumer; import jdk.internal.jimage.decompressor.CompressedResourceHeader; import jdk.internal.jimage.decompressor.StringSharingDecompressor; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.StringTable; import jdk.tools.jlink.internal.plugins.StringSharingPlugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; import tests.Helper; import tests.JImageValidator; @@ -78,7 +80,7 @@ public class StringSharingPluginTest { Map<String, Integer> map = new HashMap<>(); Map<Integer, String> reversedMap = new HashMap<>(); - PoolImpl resources = new PoolImpl(ByteOrder.nativeOrder(), new StringTable() { + ModulePoolImpl resources = new ModulePoolImpl(ByteOrder.nativeOrder(), new StringTable() { @Override public int addString(String str) { Integer id = map.get(str); @@ -104,7 +106,7 @@ public class StringSharingPluginTest { byte[] content = Files.readAllBytes(p); String path = p.toString().replace('\\', '/'); path = path.substring("/modules".length()); - ModuleData res = Pool.newResource(path, content); + ModuleEntry res = ModuleEntry.create(path, content); resources.add(res); } catch (Exception ex) { throw new RuntimeException(ex); @@ -115,19 +117,23 @@ public class StringSharingPluginTest { stream.forEach(c); } TransformerPlugin plugin = new StringSharingPlugin(); - PoolImpl result = new PoolImpl(resources.getByteOrder(), resources.getStringTable()); + ModulePoolImpl result = new ModulePoolImpl(resources.getByteOrder(), resources.getStringTable()); plugin.visit(resources, result); if (result.isEmpty()) { throw new AssertionError("No result"); } - for (ModuleData res : result.getContent()) { + result.entries().forEach(res -> { if (res.getPath().endsWith(".class")) { - byte[] uncompacted = StringSharingDecompressor.normalize(reversedMap::get, res.getBytes(), + try { + byte[] uncompacted = StringSharingDecompressor.normalize(reversedMap::get, res.getBytes(), CompressedResourceHeader.getSize()); - JImageValidator.readClass(uncompacted); + JImageValidator.readClass(uncompacted); + } catch (IOException exp) { + throw new UncheckedIOException(exp); + } } - } + }); } } diff --git a/jdk/test/tools/jlink/plugins/StripDebugPluginTest.java b/jdk/test/tools/jlink/plugins/StripDebugPluginTest.java index fd8acae896c..d3617db6f8a 100644 --- a/jdk/test/tools/jlink/plugins/StripDebugPluginTest.java +++ b/jdk/test/tools/jlink/plugins/StripDebugPluginTest.java @@ -54,10 +54,10 @@ import com.sun.tools.classfile.ConstantPoolException; import com.sun.tools.classfile.Method; import java.util.HashMap; import java.util.Map; -import jdk.tools.jlink.internal.PoolImpl; +import jdk.tools.jlink.internal.ModulePoolImpl; import jdk.tools.jlink.internal.plugins.StripDebugPlugin; -import jdk.tools.jlink.plugin.Pool; -import jdk.tools.jlink.plugin.Pool.ModuleData; +import jdk.tools.jlink.plugin.ModuleEntry; +import jdk.tools.jlink.plugin.ModulePool; import jdk.tools.jlink.plugin.TransformerPlugin; import tests.Helper; @@ -106,7 +106,7 @@ public class StripDebugPluginTest { path = path.replace('\\', '/'); StripDebugPlugin debug = new StripDebugPlugin(); debug.configure(new HashMap<>()); - ModuleData result1 = stripDebug(debug, Pool.newResource(path,content), path, infoPath, moduleInfo); + ModuleEntry result1 = stripDebug(debug, ModuleEntry.create(path,content), path, infoPath, moduleInfo); if (!path.endsWith("module-info.class")) { if (result1.getLength() >= content.length) { @@ -116,7 +116,7 @@ public class StripDebugPluginTest { checkDebugAttributes(result1.getBytes()); } - ModuleData result2 = stripDebug(debug, result1, path, infoPath, moduleInfo); + ModuleEntry result2 = stripDebug(debug, result1, path, infoPath, moduleInfo); if (result1.getLength() != result2.getLength()) { throw new AssertionError("removing debug info twice reduces class size of " + path); @@ -124,18 +124,18 @@ public class StripDebugPluginTest { checkDebugAttributes(result1.getBytes()); } - private ModuleData stripDebug(TransformerPlugin debug, ModuleData classResource, + private ModuleEntry stripDebug(TransformerPlugin debug, ModuleEntry classResource, String path, String infoPath, byte[] moduleInfo) throws Exception { - Pool resources = new PoolImpl(); + ModulePool resources = new ModulePoolImpl(); resources.add(classResource); if (!path.endsWith("module-info.class")) { - ModuleData res2 = Pool.newResource(infoPath, moduleInfo); + ModuleEntry res2 = ModuleEntry.create(infoPath, moduleInfo); resources.add(res2); } - Pool results = new PoolImpl(); + ModulePool results = new ModulePoolImpl(); debug.visit(resources, results); System.out.println(classResource.getPath()); - return results.get(classResource.getPath()); + return results.findEntry(classResource.getPath()).get(); } private void checkDebugAttributes(byte[] strippedClassFile) throws IOException, ConstantPoolException { diff --git a/langtools/.hgtags b/langtools/.hgtags index ab91141afde..5f7979643e2 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -360,3 +360,4 @@ cba09a2e6ae969b029783eb59bb01017b78f8eef jdk-9+114 31c8b18fdc5b94a2ddd5ea0694f350a2c907e9f7 jdk-9+115 3e3553ee39d9e081573bc7c88a252214a3152763 jdk-9+116 59adcdd0cd3b6724b4fc0083c258bf4682689f2f jdk-9+117 +59a16fa5dedea9ff5bea0a501e4d0d40193426f3 jdk-9+118 diff --git a/langtools/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java b/langtools/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java index e24d5a2e915..2c33367f7d6 100644 --- a/langtools/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java +++ b/langtools/src/java.compiler/share/classes/javax/tools/StandardJavaFileManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,6 +29,7 @@ import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.util.Arrays; +import java.util.Collection; import static javax.tools.FileManagerUtils.*; @@ -176,7 +177,8 @@ public interface StandardJavaFileManager extends JavaFileManager { /** * Returns file objects representing the given paths. * - * <p>The default implementation converts each path to a file and calls + * @implSpec + * The default implementation converts each path to a file and calls * {@link #getJavaFileObjectsFromFiles getJavaObjectsFromFiles}. * IllegalArgumentException will be thrown if any of the paths * cannot be converted to a file. @@ -280,10 +282,21 @@ public interface StandardJavaFileManager extends JavaFileManager { * Associates the given search path with the given location. Any * previous value will be discarded. * - * <p>The default implementation converts each path to a file and calls + * @apiNote + * The type of the {@code paths} parameter is a {@code Collection} + * and not {@code Iterable}. This is to prevent the possibility of + * accidentally calling the method with a single {@code Path} as + * the second argument, because although {@code Path} implements + * {@code Iterable<Path>}, it would almost never be correct to call + * this method with a single {@code Path} and have it be treated as + * an {@code Iterable} of its components. + * + * + * @implSpec + * The default implementation converts each path to a file and calls * {@link #getJavaFileObjectsFromFiles getJavaObjectsFromFiles}. * IllegalArgumentException will be thrown if any of the paths - * cannot be converted to a file.</p> + * cannot be converted to a file. * * @param location a location * @param paths a list of paths, if {@code null} use the default @@ -297,8 +310,8 @@ public interface StandardJavaFileManager extends JavaFileManager { * * @since 9 */ - default void setLocationFromPaths(Location location, Iterable<? extends Path> paths) - throws IOException { + default void setLocationFromPaths(Location location, Collection<? extends Path> paths) + throws IOException { setLocation(location, asFiles(paths)); } @@ -319,6 +332,11 @@ public interface StandardJavaFileManager extends JavaFileManager { /** * Returns the search path associated with the given location. * + * @implSpec + * The default implementation calls {@link #getLocation getLocation} + * and then returns an {@code Iterable} formed by calling {@code toPath()} + * on each {@code File} returned from {@code getLocation}. + * * @param location a location * @return a list of paths or {@code null} if this location has no * associated search path @@ -337,8 +355,9 @@ public interface StandardJavaFileManager extends JavaFileManager { * {@link java.nio.file.Path Path} object. In such cases, this method may be * used to access that object. * - * <p>The default implementation throws {@link UnsupportedOperationException} - * for all files.</p> + * @implSpec + * The default implementation throws {@link UnsupportedOperationException} + * for all files. * * @param file a file object * @return a path representing the same underlying file system artifact @@ -351,4 +370,36 @@ public interface StandardJavaFileManager extends JavaFileManager { throw new UnsupportedOperationException(); } + /** + * Factory to create {@code Path} objects from strings. + * + * @since 9 + */ + interface PathFactory { + /** + * Converts a path string, or a sequence of strings that when joined form a path string, to a Path. + * + * @param first the path string or initial part of the path string + * @param more additional strings to be joined to form the path string + * @return the resulting {@code Path} + */ + Path getPath(String first, String... more); + } + + /** + * Specify a factory that can be used to generate a path from a string, or series of strings. + * + * If this method is not called, a factory whose {@code getPath} method is + * equivalent to calling + * {@link java.nio.file.Paths#get(String, String...) java.nio.file.Paths.get(first, more)} + * will be used. + * + * @implSpec + * The default implementation of this method ignores the factory that is provided. + * + * @param f the factory + * + * @since 9 + */ + default void setPathFactory(PathFactory f) { } } diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java index 3bdd3169d9e..5895f2e77ec 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2016, 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 @@ -492,7 +492,7 @@ public class ClientCodeWrapper { } @Override @DefinedBy(Api.COMPILER) - public void setLocationFromPaths(Location location, Iterable<? extends Path> paths) throws IOException { + public void setLocationFromPaths(Location location, Collection<? extends Path> paths) throws IOException { try { ((StandardJavaFileManager)clientJavaFileManager).setLocationFromPaths(location, paths); } catch (ClientCodeException e) { @@ -534,6 +534,17 @@ public class ClientCodeWrapper { throw new ClientCodeException(e); } } + + @Override @DefinedBy(Api.COMPILER) + public void setPathFactory(PathFactory f) { + try { + ((StandardJavaFileManager)clientJavaFileManager).setPathFactory(f); + } catch (ClientCodeException e) { + throw e; + } catch (RuntimeException | Error e) { + throw new ClientCodeException(e); + } + } } protected class WrappedFileObject implements FileObject { diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java index 9867b008487..7fc0ffa47dd 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2016, 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 @@ -98,7 +98,9 @@ public abstract class Directive implements ModuleElement.Directive { @Override @DefinedBy(Api.LANGUAGE_MODEL) public java.util.List<? extends ModuleElement> getTargetModules() { - return Collections.unmodifiableList(modules); + return modules == null + ? null + : Collections.unmodifiableList(modules); } @Override diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java index 8e8665dd1eb..33e82384993 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java @@ -841,6 +841,28 @@ public class TypeEnter implements Completer { super(CompletionCause.MEMBERS_PHASE, null); } + private boolean completing; + private List<Env<AttrContext>> todo = List.nil(); + + @Override + protected void doCompleteEnvs(List<Env<AttrContext>> envs) { + todo = todo.prependList(envs); + if (completing) { + return ; //the top-level invocation will handle all envs + } + boolean prevCompleting = completing; + completing = true; + try { + while (todo.nonEmpty()) { + Env<AttrContext> head = todo.head; + todo = todo.tail; + super.doCompleteEnvs(List.of(head)); + } + } finally { + completing = prevCompleting; + } + } + @Override protected void runPhase(Env<AttrContext> env) { JCClassDecl tree = env.enclClass; diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java index fea4ef7a60a..9d11bb8683a 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/FSInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,6 +26,7 @@ package com.sun.tools.javac.file; import java.io.IOException; +import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -108,7 +109,7 @@ public class FSInfo { for (StringTokenizer st = new StringTokenizer(path); st.hasMoreTokens(); ) { String elt = st.nextToken(); - Path f = Paths.get(elt); + Path f = FileSystems.getDefault().getPath(elt); if (!f.isAbsolute() && parent != null) f = parent.resolve(f).toAbsolutePath(); list.add(f); diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java index fa1a3a5c608..53f515da4eb 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java @@ -109,6 +109,8 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil protected boolean symbolFileEnabled; + private PathFactory pathFactory = Paths::get; + protected enum SortFiles implements Comparator<Path> { FORWARD { @Override @@ -166,6 +168,16 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil } } + @Override @DefinedBy(DefinedBy.Api.COMPILER) + public void setPathFactory(PathFactory f) { + pathFactory = Objects.requireNonNull(f); + locations.setPathFactory(f); + } + + private Path getPath(String first, String... more) { + return pathFactory.getPath(first, more); + } + /** * Set whether or not to use ct.sym as an alternate to rt.jar. */ @@ -199,7 +211,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) { ListBuffer<Path> paths = new ListBuffer<>(); for (String name : names) - paths.append(Paths.get(nullCheck(name))); + paths.append(getPath(nullCheck(name))); return getJavaFileObjectsFromPaths(paths.toList()); } @@ -837,7 +849,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil if (sibling != null && sibling instanceof PathFileObject) { return ((PathFileObject) sibling).getSibling(baseName); } else { - Path p = Paths.get(baseName); + Path p = getPath(baseName); Path real = fsInfo.getCanonicalFile(p); return PathFileObject.forSimplePath(this, real, p); } @@ -855,7 +867,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil try { if (dir == null) { - dir = Paths.get(System.getProperty("user.dir")); + dir = getPath(System.getProperty("user.dir")); } Path path = fileName.resolveAgainst(fsInfo.getCanonicalFile(dir)); return PathFileObject.forDirectoryPath(this, path, dir, fileName); @@ -918,7 +930,7 @@ public class JavacFileManager extends BaseFileManager implements StandardJavaFil @Override @DefinedBy(Api.COMPILER) public void setLocationFromPaths(Location location, - Iterable<? extends Path> searchpath) + Collection<? extends Path> searchpath) throws IOException { nullCheck(location); diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java index 68f7781b0ef..12106e3ecc1 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java @@ -68,6 +68,7 @@ import javax.lang.model.SourceVersion; import javax.tools.JavaFileManager; import javax.tools.JavaFileManager.Location; import javax.tools.StandardJavaFileManager; +import javax.tools.StandardJavaFileManager.PathFactory; import javax.tools.StandardLocation; import com.sun.tools.javac.code.Lint; @@ -121,7 +122,9 @@ public class Locations { private ModuleNameReader moduleNameReader; - static final Path javaHome = Paths.get(System.getProperty("java.home")); + private PathFactory pathFactory = Paths::get; + + static final Path javaHome = FileSystems.getDefault().getPath(System.getProperty("java.home")); static final Path thisSystemModules = javaHome.resolve("lib").resolve("modules"); Map<Path, FileSystem> fileSystems = new LinkedHashMap<>(); @@ -131,6 +134,10 @@ public class Locations { initHandlers(); } + Path getPath(String first, String... more) { + return pathFactory.getPath(first, more); + } + public void close() throws IOException { ListBuffer<IOException> list = new ListBuffer<>(); closeables.forEach(closeable -> { @@ -155,6 +162,10 @@ public class Locations { this.fsInfo = fsInfo; } + void setPathFactory(PathFactory f) { + pathFactory = f; + } + boolean isDefaultBootClassPath() { BootClassPathLocationHandler h = (BootClassPathLocationHandler) getHandler(PLATFORM_CLASS_PATH); @@ -167,7 +178,7 @@ public class Locations { * @param searchPath The search path to be split * @return The elements of the path */ - private static Iterable<Path> getPathEntries(String searchPath) { + private Iterable<Path> getPathEntries(String searchPath) { return getPathEntries(searchPath, null); } @@ -181,7 +192,7 @@ public class Locations { * empty path elements * @return The elements of the path */ - private static Iterable<Path> getPathEntries(String searchPath, Path emptyPathDefault) { + private Iterable<Path> getPathEntries(String searchPath, Path emptyPathDefault) { ListBuffer<Path> entries = new ListBuffer<>(); for (String s: searchPath.split(Pattern.quote(File.pathSeparator), -1)) { if (s.isEmpty()) { @@ -189,7 +200,7 @@ public class Locations { entries.add(emptyPathDefault); } } else { - entries.add(Paths.get(s)); + entries.add(getPath(s)); } } return entries; @@ -465,7 +476,7 @@ public class Locations { // need to decide how best to report issue for benefit of // direct API call on JavaFileManager.handleOption(specifies IAE) // vs. command line decoding. - outputDir = (value == null) ? null : Paths.get(value); + outputDir = (value == null) ? null : getPath(value); return true; } @@ -606,7 +617,7 @@ public class Locations { protected SearchPath createPath() { return new SearchPath() .expandJarClassPaths(true) // Only search user jars for Class-Paths - .emptyPathDefault(Paths.get(".")); // Empty path elt ==> current directory + .emptyPathDefault(getPath(".")); // Empty path elt ==> current directory } private void lazy() { @@ -791,7 +802,7 @@ public class Locations { paths.addAll(modules); for (String s : files.split(Pattern.quote(File.pathSeparator))) { - paths.add(Paths.get(s)); + paths.add(getPath(s)); } return paths; @@ -1170,12 +1181,12 @@ public class Locations { for (String seg: segments) { int markStart = seg.indexOf(MARKER); if (markStart == -1) { - add(map, Paths.get(seg), null); + add(map, getPath(seg), null); } else { if (markStart == 0 || !isSeparator(seg.charAt(markStart - 1))) { throw new IllegalArgumentException("illegal use of " + MARKER + " in " + seg); } - Path prefix = Paths.get(seg.substring(0, markStart - 1)); + Path prefix = getPath(seg.substring(0, markStart - 1)); Path suffix; int markEnd = markStart + MARKER.length(); if (markEnd == seg.length()) { @@ -1184,7 +1195,7 @@ public class Locations { || seg.indexOf(MARKER, markEnd) != -1) { throw new IllegalArgumentException("illegal use of " + MARKER + " in " + seg); } else { - suffix = Paths.get(seg.substring(markEnd + 1)); + suffix = getPath(seg.substring(markEnd + 1)); } add(map, prefix, suffix); } @@ -1331,13 +1342,13 @@ public class Locations { } private class SystemModulesLocationHandler extends BasicLocationHandler { - private Path javaHome; + private Path systemJavaHome; private Path modules; private Map<String, ModuleLocationHandler> systemModules; SystemModulesLocationHandler() { super(StandardLocation.SYSTEM_MODULES, Option.SYSTEM); - javaHome = Paths.get(System.getProperty("java.home")); + systemJavaHome = Locations.javaHome; } @Override @@ -1347,11 +1358,11 @@ public class Locations { } if (value == null) { - javaHome = Paths.get(System.getProperty("java.home")); + systemJavaHome = Locations.javaHome; } else if (value.equals("none")) { - javaHome = null; + systemJavaHome = null; } else { - update(Paths.get(value)); + update(getPath(value)); } modules = null; @@ -1360,13 +1371,13 @@ public class Locations { @Override Collection<Path> getPaths() { - return (javaHome == null) ? null : Collections.singleton(javaHome); + return (systemJavaHome == null) ? null : Collections.singleton(systemJavaHome); } @Override void setPaths(Iterable<? extends Path> files) throws IOException { if (files == null) { - javaHome = null; + systemJavaHome = null; } else { Iterator<? extends Path> pathIter = files.iterator(); if (!pathIter.hasNext()) { @@ -1386,16 +1397,15 @@ public class Locations { } private void update(Path p) { - if (!isCurrentPlatform(p) && !Files.exists(p.resolve("jrt-fs.jar")) && !Files.exists(javaHome.resolve("modules"))) + if (!isCurrentPlatform(p) && !Files.exists(p.resolve("jrt-fs.jar")) && !Files.exists(systemJavaHome.resolve("modules"))) throw new IllegalArgumentException(p.toString()); - javaHome = p; + systemJavaHome = p; modules = null; } private boolean isCurrentPlatform(Path p) { - Path jh = Paths.get(System.getProperty("java.home")); try { - return Files.isSameFile(p, jh); + return Files.isSameFile(p, Locations.javaHome); } catch (IOException ex) { throw new IllegalArgumentException(p.toString(), ex); } @@ -1421,7 +1431,7 @@ public class Locations { return; } - if (javaHome == null) { + if (systemJavaHome == null) { systemModules = Collections.emptyMap(); return; } @@ -1431,15 +1441,15 @@ public class Locations { URI jrtURI = URI.create("jrt:/"); FileSystem jrtfs; - if (isCurrentPlatform(javaHome)) { + if (isCurrentPlatform(systemJavaHome)) { jrtfs = FileSystems.getFileSystem(jrtURI); } else { try { Map<String, String> attrMap = - Collections.singletonMap("java.home", javaHome.toString()); + Collections.singletonMap("java.home", systemJavaHome.toString()); jrtfs = FileSystems.newFileSystem(jrtURI, attrMap); } catch (ProviderNotFoundException ex) { - URL javaHomeURL = javaHome.resolve("jrt-fs.jar").toUri().toURL(); + URL javaHomeURL = systemJavaHome.resolve("jrt-fs.jar").toUri().toURL(); ClassLoader currentLoader = Locations.class.getClassLoader(); URLClassLoader fsLoader = new URLClassLoader(new URL[] {javaHomeURL}, currentLoader); @@ -1454,7 +1464,7 @@ public class Locations { modules = jrtfs.getPath("/modules"); } catch (FileSystemNotFoundException | ProviderNotFoundException e) { - modules = javaHome.resolve("modules"); + modules = systemJavaHome.resolve("modules"); if (!Files.exists(modules)) throw new IOException("can't find system classes", e); } diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java index 73be502e052..f30896c2cbc 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/PathFileObject.java @@ -109,7 +109,7 @@ public abstract class PathFileObject implements JavaFileObject { private DirectoryFileObject(BaseFileManager fileManager, Path path, Path userPackageRootDir, RelativePath relativePath) { super(fileManager, path); - this.userPackageRootDir = userPackageRootDir; + this.userPackageRootDir = Objects.requireNonNull(userPackageRootDir); this.relativePath = relativePath; } diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java index 3e541b884f1..75fdcf1b031 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/RelativePath.java @@ -26,10 +26,8 @@ package com.sun.tools.javac.file; import java.nio.file.FileSystem; -import java.nio.file.FileSystems; import java.nio.file.InvalidPathException; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; @@ -58,13 +56,8 @@ public abstract class RelativePath implements Comparable<RelativePath> { public abstract String basename(); public Path resolveAgainst(Path directory) throws /*unchecked*/ InvalidPathException { - if (directory == null) { - String sep = FileSystems.getDefault().getSeparator(); - return Paths.get(path.replace("/", sep)); - } else { - String sep = directory.getFileSystem().getSeparator(); - return directory.resolve(path.replace("/", sep)); - } + String sep = directory.getFileSystem().getSeparator(); + return directory.resolve(path.replace("/", sep)); } public Path resolveAgainst(FileSystem fs) throws /*unchecked*/ InvalidPathException { diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java index 3ef115ff8dd..62bfd05484c 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, 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 @@ -108,7 +108,7 @@ public class ClassFile { V50(50, 0), // JDK 1.6: stackmaps V51(51, 0), // JDK 1.7 V52(52, 0), // JDK 1.8: lambda, type annos, param names - V53(52, 0); // JDK 1.9: modules **** FIXME TO 53 BEFORE RELEASE ***** + V53(53, 0); // JDK 1.9: modules, indy string concat Version(int major, int minor) { this.major = major; this.minor = minor; diff --git a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java index 75f314b1912..b0737558596 100644 --- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java +++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Target.java @@ -60,8 +60,8 @@ public enum Target { /** JDK 8. */ JDK1_8("1.8", 52, 0), - /** JDK 9, initially an alias for 8. */ - JDK1_9("1.9", 52, 0); + /** JDK 9. */ + JDK1_9("1.9", 53, 0); private static final Context.Key<Target> targetKey = new Context.Key<>(); diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java index 6eac715fa98..348054f1269 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ClassWriterImpl.java @@ -28,7 +28,7 @@ package com.sun.tools.doclets.formats.html; import java.util.*; import com.sun.javadoc.*; -import com.sun.tools.javadoc.RootDocImpl; +import com.sun.tools.javadoc.main.RootDocImpl; import com.sun.tools.doclets.formats.html.markup.*; import com.sun.tools.doclets.internal.toolkit.*; import com.sun.tools.doclets.internal.toolkit.builders.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java index 5751a70807b..83fc46a34e0 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java @@ -40,7 +40,7 @@ import com.sun.tools.doclint.DocLint; import com.sun.tools.javac.file.JavacFileManager; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.StringUtils; -import com.sun.tools.javadoc.RootDocImpl; +import com.sun.tools.javadoc.main.RootDocImpl; /** * Configure the output based on the command line options. diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java index 2c8f185d981..216f0f7886a 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/doclets/formats/html/SourceToHTMLConverter.java @@ -149,8 +149,8 @@ public class SourceToHTMLConverter { return; Reader r; // temp hack until we can update SourcePosition API. - if (sp instanceof com.sun.tools.javadoc.SourcePositionImpl) { - FileObject fo = ((com.sun.tools.javadoc.SourcePositionImpl) sp).fileObject(); + if (sp instanceof com.sun.tools.javadoc.main.SourcePositionImpl) { + FileObject fo = ((com.sun.tools.javadoc.main.SourcePositionImpl) sp).fileObject(); if (fo == null) return; r = fo.openReader(true); diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Main.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Main.java index dfc21b27702..467fd2d34e0 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Main.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Main.java @@ -27,6 +27,8 @@ package com.sun.tools.javadoc; import java.io.PrintWriter; +import com.sun.tools.javadoc.main.Start; + /** * Provides external entry points (tool and programmatic) * for the javadoc program. diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AbstractTypeImpl.java similarity index 98% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AbstractTypeImpl.java index 856cd558ea8..c0570aa7516 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AbstractTypeImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AbstractTypeImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotatedTypeImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotatedTypeImpl.java index 3ee1c0a99c1..982b8744ed5 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotatedTypeImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotatedTypeImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; import com.sun.tools.javac.code.Attribute; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationDescImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationDescImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationDescImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationDescImpl.java index 2647d9983be..d348f35ec02 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationDescImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationDescImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationTypeDocImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationTypeDocImpl.java index 2ff3ba6d971..d691959f4c3 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationTypeDocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationTypeDocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationTypeElementDocImpl.java similarity index 98% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationTypeElementDocImpl.java index 230542958f0..bd0f8284c2d 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationTypeElementDocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationTypeElementDocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationValueImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationValueImpl.java index b79a19ce8ff..036f2b40a88 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/AnnotationValueImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/AnnotationValueImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ClassDocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ClassDocImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ClassDocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ClassDocImpl.java index acebdb840f6..c1437e007ed 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ClassDocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ClassDocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.io.File; import java.io.IOException; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Comment.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Comment.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Comment.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Comment.java index e2e29007874..ade553baba9 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Comment.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Comment.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ConstructorDocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ConstructorDocImpl.java similarity index 98% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ConstructorDocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ConstructorDocImpl.java index d0a0853dc3f..ca53d182e6c 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ConstructorDocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ConstructorDocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocEnv.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocEnv.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocEnv.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocEnv.java index 2ac36520cd6..d123013013b 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocEnv.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocEnv.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.lang.reflect.Modifier; import java.util.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocImpl.java index bf77bd089e0..0f085e7eeef 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.io.DataInputStream; import java.io.IOException; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocLocale.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocLocale.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocLocale.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocLocale.java index 5dcd1b72201..4460d7e311c 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocLocale.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocLocale.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.text.BreakIterator; import java.text.Collator; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocletInvoker.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocletInvoker.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocletInvoker.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocletInvoker.java index 91e333e8ccb..402e67ef70b 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/DocletInvoker.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/DocletInvoker.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.io.File; import java.io.IOException; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ExecutableMemberDocImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ExecutableMemberDocImpl.java index cfbc0cb4001..30075a96d78 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ExecutableMemberDocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ExecutableMemberDocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.lang.reflect.Modifier; import java.text.CollationKey; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/FieldDocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/FieldDocImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/FieldDocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/FieldDocImpl.java index 8317128c945..c3432633dc8 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/FieldDocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/FieldDocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.source.util.TreePath; import java.lang.reflect.Modifier; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocClassFinder.java similarity index 98% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocClassFinder.java index ecb3659f174..997b8d97759 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocClassFinder.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocClassFinder.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.util.EnumSet; import javax.tools.JavaFileObject; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocEnter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocEnter.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocEnter.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocEnter.java index 3732098289f..a49abaeabb6 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocEnter.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocEnter.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import javax.tools.JavaFileObject; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocMemberEnter.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocMemberEnter.java index 220ffb5504e..452cc614938 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocMemberEnter.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocMemberEnter.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.source.util.TreePath; import com.sun.tools.javac.code.Flags; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocTodo.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTodo.java similarity index 98% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocTodo.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTodo.java index cbeaf699376..88ab1ad1dd2 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocTodo.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTodo.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.tools.javac.comp.*; import com.sun.tools.javac.util.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocTool.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocTool.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java index b29c2899222..fa358ddf47d 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/JavadocTool.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/JavadocTool.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.io.File; import java.io.IOException; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/MemberDocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/MemberDocImpl.java similarity index 98% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/MemberDocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/MemberDocImpl.java index 37c7c66eb46..d87c0ae01f1 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/MemberDocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/MemberDocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Messager.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Messager.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Messager.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Messager.java index 2a97cd0ff25..d181fb2a82d 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Messager.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Messager.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.io.PrintWriter; import java.util.Locale; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/MethodDocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/MethodDocImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/MethodDocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/MethodDocImpl.java index b624694a771..391eab2b8d3 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/MethodDocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/MethodDocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.lang.reflect.Modifier; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ModifierFilter.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ModifierFilter.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ModifierFilter.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ModifierFilter.java index 40a9040971c..76624e64f60 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ModifierFilter.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ModifierFilter.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import static com.sun.tools.javac.code.Flags.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/PackageDocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/PackageDocImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/PackageDocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/PackageDocImpl.java index 13753959b3e..a5683240e67 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/PackageDocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/PackageDocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.io.IOException; import java.io.InputStream; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ParamTagImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParamTagImpl.java similarity index 98% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ParamTagImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParamTagImpl.java index e8775393776..56cf966f62f 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ParamTagImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParamTagImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.util.regex.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ParameterImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParameterImpl.java similarity index 98% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ParameterImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParameterImpl.java index 14de4a2f43a..ce047b59c37 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ParameterImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParameterImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ParameterizedTypeImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParameterizedTypeImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ParameterizedTypeImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParameterizedTypeImpl.java index 2fac11119d3..e7c8875f76b 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ParameterizedTypeImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ParameterizedTypeImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/PrimitiveType.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/PrimitiveType.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/PrimitiveType.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/PrimitiveType.java index a3a81983734..79d2a3a246f 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/PrimitiveType.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/PrimitiveType.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ProgramElementDocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ProgramElementDocImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ProgramElementDocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ProgramElementDocImpl.java index d647b491639..663263ee166 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ProgramElementDocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ProgramElementDocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.lang.reflect.Modifier; import java.text.CollationKey; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/RootDocImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/RootDocImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java index d4b0da6d03d..03157373e7f 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/RootDocImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/RootDocImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.io.IOException; import java.util.Collection; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SeeTagImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SeeTagImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SeeTagImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SeeTagImpl.java index de73bc87b6a..626a54d81b1 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SeeTagImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SeeTagImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.io.File; import java.util.Locale; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SerialFieldTagImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SerialFieldTagImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SerialFieldTagImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SerialFieldTagImpl.java index e89866d9de9..a7dc95da462 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SerialFieldTagImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SerialFieldTagImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SerializedForm.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SerializedForm.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SerializedForm.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SerializedForm.java index f6d056a52c7..f06987ce89e 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SerializedForm.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SerializedForm.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; import com.sun.tools.javac.code.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SourcePositionImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SourcePositionImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SourcePositionImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SourcePositionImpl.java index b508b615ea6..911e57c8f99 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/SourcePositionImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/SourcePositionImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.io.File; import javax.tools.FileObject; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Start.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java similarity index 98% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Start.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java index c05762504e5..188c6b5fd84 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/Start.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/Start.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.io.File; import java.io.FileNotFoundException; @@ -95,7 +95,7 @@ public class Start extends ToolOption.Helper { private JavaFileManager fileManager; - Start(String programName, + public Start(String programName, PrintWriter errWriter, PrintWriter warnWriter, PrintWriter noticeWriter, @@ -119,11 +119,11 @@ public class Start extends ToolOption.Helper { this.docletParentClassLoader = docletParentClassLoader; } - Start(String programName, String defaultDocletClassName) { + public Start(String programName, String defaultDocletClassName) { this(programName, defaultDocletClassName, null); } - Start(String programName, String defaultDocletClassName, + public Start(String programName, String defaultDocletClassName, ClassLoader docletParentClassLoader) { context = new Context(); messager = new Messager(context, programName); @@ -131,15 +131,15 @@ public class Start extends ToolOption.Helper { this.docletParentClassLoader = docletParentClassLoader; } - Start(String programName, ClassLoader docletParentClassLoader) { + public Start(String programName, ClassLoader docletParentClassLoader) { this(programName, standardDocletClassName, docletParentClassLoader); } - Start(String programName) { + public Start(String programName) { this(programName, standardDocletClassName); } - Start(ClassLoader docletParentClassLoader) { + public Start(ClassLoader docletParentClassLoader) { this(javadocName, docletParentClassLoader); } diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/TagImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TagImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/TagImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TagImpl.java index a106bb68f40..352c9fc7152 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/TagImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TagImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ThrowsTagImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ThrowsTagImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ThrowsTagImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ThrowsTagImpl.java index 6da454fdbb8..e92d871263b 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ThrowsTagImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ThrowsTagImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ToolOption.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ToolOption.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java index 18ab44f3c06..180f99b5162 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/ToolOption.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import java.util.LinkedHashMap; import java.util.Map; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/TypeMaker.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TypeMaker.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/TypeMaker.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TypeMaker.java index aae1917d573..7c18ce120b2 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/TypeMaker.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TypeMaker.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; import com.sun.tools.javac.code.Symbol; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TypeVariableImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TypeVariableImpl.java index 93d4e31dd20..8207695e285 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/TypeVariableImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/TypeVariableImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/WildcardTypeImpl.java b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/WildcardTypeImpl.java similarity index 99% rename from langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/WildcardTypeImpl.java rename to langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/WildcardTypeImpl.java index cf458d2335c..f3b4138e9d7 100644 --- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/WildcardTypeImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/WildcardTypeImpl.java @@ -23,7 +23,7 @@ * questions. */ -package com.sun.tools.javadoc; +package com.sun.tools.javadoc.main; import com.sun.javadoc.*; diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java index 3d6a248da57..61b101ce5e6 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/AnnotationTypeWriterImpl.java @@ -90,6 +90,19 @@ public class AnnotationTypeWriterImpl extends SubWriterHolderWriter this.next = nextType; } + /** + * Get the module link. + * + * @return a content tree for the module link + */ + @Override + protected Content getNavLinkModule() { + Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(annotationType), + moduleLabel); + Content li = HtmlTree.LI(linkContent); + return li; + } + /** * Get this package link. * diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java index 9e3834dffba..61993e1490b 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassUseWriter.java @@ -504,6 +504,19 @@ public class ClassUseWriter extends SubWriterHolderWriter { return bodyTree; } + /** + * Get the module link. + * + * @return a content tree for the module link + */ + @Override + protected Content getNavLinkModule() { + Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement), + moduleLabel); + Content li = HtmlTree.LI(linkContent); + return li; + } + /** * Get this package link. * diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java index 4137cefb6f7..3758a0bd665 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java @@ -104,6 +104,19 @@ public class ClassWriterImpl extends SubWriterHolderWriter implements ClassWrite this.next = nextClass; } + /** + * Get the module link. + * + * @return a content tree for the module link + */ + @Override + protected Content getNavLinkModule() { + Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(typeElement), + moduleLabel); + Content li = HtmlTree.LI(linkContent); + return li; + } + /** * Get this package link. * diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java index 71eedc88e42..c5af88209b9 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java @@ -570,6 +570,11 @@ public class HtmlDocletWriter extends HtmlDocWriter { if (configuration.createoverview) { navList.addContent(getNavLinkContents()); } + if (configuration.modules.size() == 1) { + navList.addContent(getNavLinkModule(configuration.modules.first())); + } else if (!configuration.modules.isEmpty()) { + navList.addContent(getNavLinkModule()); + } if (configuration.packages.size() == 1) { navList.addContent(getNavLinkPackage(configuration.packages.first())); } else if (!configuration.packages.isEmpty()) { @@ -678,6 +683,28 @@ public class HtmlDocletWriter extends HtmlDocWriter { return li; } + /** + * Get link to the module summary page for the module passed. + * + * @param mdle Module to which link will be generated + * @return a content tree for the link + */ + protected Content getNavLinkModule(ModuleElement mdle) { + Content linkContent = getModuleLink(mdle, moduleLabel); + Content li = HtmlTree.LI(linkContent); + return li; + } + + /** + * Get the word "Module", to indicate that link is not available here. + * + * @return a content tree for the link + */ + protected Content getNavLinkModule() { + Content li = HtmlTree.LI(moduleLabel); + return li; + } + /** * Get link to the "package-summary.html" page for the package passed. * diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java index 555f0dcb03d..0a61c05fb76 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriterImpl.java @@ -267,6 +267,17 @@ public class ModuleWriterImpl extends HtmlDocletWriter implements ModuleSummaryW } } + /** + * Get this module link. + * + * @return a content tree for the module link + */ + @Override + protected Content getNavLinkModule() { + Content li = HtmlTree.LI(HtmlStyle.navBarCell1Rev, moduleLabel); + return li; + } + /** * Get "PREV MODULE" link in the navigation bar. * diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java index 9dac9a3bf18..4db9a00c804 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageTreeWriter.java @@ -223,6 +223,19 @@ public class PackageTreeWriter extends AbstractTreeWriter { } } + /** + * Get the module link. + * + * @return a content tree for the module link + */ + @Override + protected Content getNavLinkModule() { + Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement), + moduleLabel); + Content li = HtmlTree.LI(linkContent); + return li; + } + /** * Get link to the package summary page for the package of this tree. * diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java index 3763e725892..d73fab18f8d 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageUseWriter.java @@ -303,6 +303,19 @@ public class PackageUseWriter extends SubWriterHolderWriter { return bodyTree; } + /** + * Get the module link. + * + * @return a content tree for the module link + */ + @Override + protected Content getNavLinkModule() { + Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement), + moduleLabel); + Content li = HtmlTree.LI(linkContent); + return li; + } + /** * Get this package link. * diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java index 64d76a0743c..438687b0d6c 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageWriterImpl.java @@ -375,6 +375,19 @@ public class PackageWriterImpl extends HtmlDocletWriter return li; } + /** + * Get the module link. + * + * @return a content tree for the module link + */ + @Override + protected Content getNavLinkModule() { + Content linkContent = getModuleLink(utils.elementUtils.getModuleOf(packageElement), + moduleLabel); + Content li = HtmlTree.LI(linkContent); + return li; + } + /** * Highlight "Package" in the navigation bar, as this is the package page. * diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java index 917063e98ae..34eced11854 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/Configuration.java @@ -329,6 +329,7 @@ public abstract class Configuration { public abstract MessageRetriever getDocletSpecificMsg(); public CommentUtils cmtUtils; + public SortedSet<ModuleElement> modules; /** * A sorted set of packages specified on the command-line merged with a @@ -395,6 +396,8 @@ public abstract class Configuration { s.add(p); } } + modules = new TreeSet<>(utils.makeModuleComparator()); + modules.addAll(modulePackages.keySet()); showModules = (modulePackages.size() > 1); } diff --git a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java index 2cca6849e26..a0058e15b0d 100644 --- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java +++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/Start.java @@ -283,8 +283,8 @@ public class Start extends ToolOption.Helper { } } else { if (this.apiMode) { - com.sun.tools.javadoc.Start ostart - = new com.sun.tools.javadoc.Start(context); + com.sun.tools.javadoc.main.Start ostart + = new com.sun.tools.javadoc.main.Start(context); return ostart.begin(docletClass, options, fileObjects); } warn("main.legacy_api"); diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java index ca6b08612b9..50959ba539a 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,10 +40,13 @@ import com.sun.source.tree.Scope; import com.sun.source.tree.Tree; import com.sun.source.tree.Tree.Kind; import com.sun.source.tree.VariableTree; +import com.sun.source.util.JavacTask; import com.sun.source.util.SourcePositions; import com.sun.source.util.TreePath; import com.sun.source.util.TreePathScanner; +import com.sun.source.util.Trees; import com.sun.tools.javac.api.JavacScope; +import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Symbol.CompletionFailure; import com.sun.tools.javac.code.Symbol.VarSymbol; @@ -119,8 +122,12 @@ import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeKind; import javax.lang.model.util.ElementFilter; import javax.lang.model.util.Types; +import javax.tools.JavaCompiler; import javax.tools.JavaFileManager.Location; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; import javax.tools.StandardLocation; +import javax.tools.ToolProvider; import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME; @@ -932,6 +939,12 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { } } + //tweaked by tests to disable reading parameter names from classfiles so that tests using + //JDK's classes are stable for both release and fastdebug builds: + private final String[] keepParameterNames = new String[] { + "-XDsave-parameter-names=true" + }; + private String documentationImpl(String code, int cursor) { code = code.substring(0, cursor); if (code.trim().isEmpty()) { //TODO: comment handling @@ -942,7 +955,7 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { return null; OuterWrap codeWrap = proc.outerMap.wrapInTrialClass(Wrap.methodWrap(code)); - AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap); + AnalyzeTask at = proc.taskFactory.new AnalyzeTask(codeWrap, keepParameterNames); SourcePositions sp = at.trees().getSourcePositions(); CompilationUnitTree topLevel = at.firstCuTree(); TreePath tp = pathFor(topLevel, sp, codeWrap.snippetIndexToWrapIndex(cursor)); @@ -983,9 +996,11 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { .collect(Collectors.toList()); } - return Util.stream(candidates) - .map(method -> Util.expunge(element2String(method.fst))) - .collect(joining("\n")); + try (SourceCache sourceCache = new SourceCache(at)) { + return Util.stream(candidates) + .map(method -> Util.expunge(element2String(sourceCache, method.fst))) + .collect(joining("\n")); + } } private boolean isEmptyArgumentsContext(List<? extends ExpressionTree> arguments) { @@ -996,19 +1011,173 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { return false; } - private String element2String(Element el) { + private String element2String(SourceCache sourceCache, Element el) { + try { + if (hasSyntheticParameterNames(el)) { + el = sourceCache.getSourceMethod(el); + } + } catch (IOException ex) { + proc.debug(ex, "SourceCodeAnalysisImpl.element2String(..., " + el + ")"); + } + + return Util.expunge(elementHeader(el)); + } + + private boolean hasSyntheticParameterNames(Element el) { + if (el.getKind() != ElementKind.CONSTRUCTOR && el.getKind() != ElementKind.METHOD) + return false; + + ExecutableElement ee = (ExecutableElement) el; + + if (ee.getParameters().isEmpty()) + return false; + + return ee.getParameters() + .stream() + .allMatch(param -> param.getSimpleName().toString().startsWith("arg")); + } + + private final class SourceCache implements AutoCloseable { + private final JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); + private final Map<String, Map<String, Element>> topLevelName2Signature2Method = new HashMap<>(); + private final AnalyzeTask originalTask; + private final StandardJavaFileManager fm; + + public SourceCache(AnalyzeTask originalTask) { + this.originalTask = originalTask; + List<Path> sources = findSources(); + if (sources.iterator().hasNext()) { + StandardJavaFileManager fm = compiler.getStandardFileManager(null, null, null); + try { + fm.setLocationFromPaths(StandardLocation.SOURCE_PATH, sources); + } catch (IOException ex) { + proc.debug(ex, "SourceCodeAnalysisImpl.SourceCache.<init>(...)"); + fm = null; + } + this.fm = fm; + } else { + //don't waste time if there are no sources + this.fm = null; + } + } + + public Element getSourceMethod(Element method) throws IOException { + if (fm == null) + return method; + + TypeElement type = topLevelType(method); + + if (type == null) + return method; + + String binaryName = originalTask.task.getElements().getBinaryName(type).toString(); + + Map<String, Element> cache = topLevelName2Signature2Method.get(binaryName); + + if (cache == null) { + topLevelName2Signature2Method.put(binaryName, cache = createMethodCache(binaryName)); + } + + String handle = elementHeader(method, false); + + return cache.getOrDefault(handle, method); + } + + private TypeElement topLevelType(Element el) { + while (el != null && el.getEnclosingElement().getKind() != ElementKind.PACKAGE) { + el = el.getEnclosingElement(); + } + + return el != null && (el.getKind().isClass() || el.getKind().isInterface()) ? (TypeElement) el : null; + } + + private Map<String, Element> createMethodCache(String binaryName) throws IOException { + Pair<JavacTask, CompilationUnitTree> source = findSource(binaryName); + + if (source == null) + return Collections.emptyMap(); + + Map<String, Element> signature2Method = new HashMap<>(); + Trees trees = Trees.instance(source.fst); + + new TreePathScanner<Void, Void>() { + @Override @DefinedBy(Api.COMPILER_TREE) + public Void visitMethod(MethodTree node, Void p) { + Element currentMethod = trees.getElement(getCurrentPath()); + + if (currentMethod != null) { + signature2Method.put(elementHeader(currentMethod, false), currentMethod); + } + + return null; + } + }.scan(source.snd, null); + + return signature2Method; + } + + private Pair<JavacTask, CompilationUnitTree> findSource(String binaryName) throws IOException { + JavaFileObject jfo = fm.getJavaFileForInput(StandardLocation.SOURCE_PATH, + binaryName, + JavaFileObject.Kind.SOURCE); + + if (jfo == null) + return null; + + List<JavaFileObject> jfos = Arrays.asList(jfo); + JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, fm, d -> {}, null, null, jfos); + Iterable<? extends CompilationUnitTree> cuts = task.parse(); + + task.enter(); + + return Pair.of(task, cuts.iterator().next()); + } + + @Override + public void close() { + try { + if (fm != null) { + fm.close(); + } + } catch (IOException ex) { + proc.debug(ex, "SourceCodeAnalysisImpl.SourceCache.close()"); + } + } + } + + private List<Path> availableSources; + + private List<Path> findSources() { + if (availableSources != null) { + return availableSources; + } + List<Path> result = new ArrayList<>(); + Path home = Paths.get(System.getProperty("java.home")); + Path srcZip = home.resolve("src.zip"); + if (!Files.isReadable(srcZip)) + srcZip = home.getParent().resolve("src.zip"); + if (Files.isReadable(srcZip)) + result.add(srcZip); + return availableSources = result; + } + + private String elementHeader(Element el) { + return elementHeader(el, true); + } + + private String elementHeader(Element el, boolean includeParameterNames) { switch (el.getKind()) { case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE: return ((TypeElement) el).getQualifiedName().toString(); case FIELD: - return element2String(el.getEnclosingElement()) + "." + el.getSimpleName() + ":" + el.asType(); + return elementHeader(el.getEnclosingElement()) + "." + el.getSimpleName() + ":" + el.asType(); case ENUM_CONSTANT: - return element2String(el.getEnclosingElement()) + "." + el.getSimpleName(); + return elementHeader(el.getEnclosingElement()) + "." + el.getSimpleName(); case EXCEPTION_PARAMETER: case LOCAL_VARIABLE: case PARAMETER: case RESOURCE_VARIABLE: return el.getSimpleName() + ":" + el.asType(); case CONSTRUCTOR: case METHOD: StringBuilder header = new StringBuilder(); - header.append(element2String(el.getEnclosingElement())); + header.append(elementHeader(el.getEnclosingElement())); if (el.getKind() == ElementKind.METHOD) { header.append("."); header.append(el.getSimpleName()); @@ -1026,8 +1195,10 @@ class SourceCodeAnalysisImpl extends SourceCodeAnalysis { } else { header.append(p.asType()); } - header.append(" "); - header.append(p.getSimpleName()); + if (includeParameterNames) { + header.append(" "); + header.append(p.getSimpleName()); + } sep = ", "; } header.append(")"); diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java index ce34f5f16a6..fe0a3b73f74 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TaskFactory.java @@ -215,17 +215,21 @@ class TaskFactory { private final Iterable<? extends CompilationUnitTree> cuts; - AnalyzeTask(final OuterWrap wrap) { - this(Collections.singletonList(wrap)); + AnalyzeTask(final OuterWrap wrap, String... extraArgs) { + this(Collections.singletonList(wrap), extraArgs); } - AnalyzeTask(final Collection<OuterWrap> wraps) { + AnalyzeTask(final Collection<OuterWrap> wraps, String... extraArgs) { this(wraps.stream(), new WrapSourceHandler(), - "-XDshouldStopPolicy=FLOW", "-Xlint:unchecked", "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", "-proc:none"); + Util.join(new String[] { + "-XDshouldStopPolicy=FLOW", "-Xlint:unchecked", + "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", + "-proc:none" + }, extraArgs)); } - <T>AnalyzeTask(final Stream<T> stream, SourceHandler<T> sourceHandler, + private <T>AnalyzeTask(final Stream<T> stream, SourceHandler<T> sourceHandler, String... extraOptions) { super(stream, sourceHandler, extraOptions); cuts = analyze(); @@ -264,7 +268,7 @@ class TaskFactory { CompileTask(final Collection<OuterWrap> wraps) { super(wraps.stream(), new WrapSourceHandler(), - "-Xlint:unchecked", "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", "-proc:none"); + "-Xlint:unchecked", "-XaddExports:jdk.jshell/jdk.internal.jshell.remote=ALL-UNNAMED", "-proc:none", "-parameters"); } boolean compile() { diff --git a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java index 553e6c97fb3..413c30baa13 100644 --- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java +++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Util.java @@ -25,6 +25,9 @@ package jdk.jshell; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; import java.util.Locale; import java.util.stream.Stream; import java.util.stream.StreamSupport; @@ -95,6 +98,15 @@ class Util { return StreamSupport.stream(iterable.spliterator(), false); } + static String[] join(String[] a1, String[] a2) { + List<String> result = new ArrayList<>(); + + result.addAll(Arrays.asList(a1)); + result.addAll(Arrays.asList(a2)); + + return result.toArray(new String[0]); + } + static class Pair<T, U> { final T first; final U second; diff --git a/langtools/test/Makefile b/langtools/test/Makefile index 0940c512fdc..f5b43ab0b0b 100644 --- a/langtools/test/Makefile +++ b/langtools/test/Makefile @@ -86,6 +86,8 @@ endif # Default JTREG to run ifdef JPRT_JTREG_HOME JTREG_HOME = $(JPRT_JTREG_HOME) +else ifdef JT_HOME + JTREG_HOME = $(JT_HOME) else JTREG_HOME = $(SLASH_JAVA)/re/jtreg/4.1-jigsaw/nightly/binaries/jtreg/ endif @@ -113,10 +115,12 @@ endif # # JT_JAVA is the version of java used to run jtreg/JCK. # -ifdef JPRT_JAVA_HOME - JT_JAVA = $(JPRT_JAVA_HOME) -else - JT_JAVA = $(SLASH_JAVA)/re/jdk/1.9.0/archive/fcs/binaries/$(PLATFORM)-$(ARCH) +ifndef JT_JAVA + ifdef JPRT_JAVA_HOME + JT_JAVA = $(JPRT_JAVA_HOME) + else + JT_JAVA = $(SLASH_JAVA)/re/jdk/1.9.0/archive/fcs/binaries/$(PLATFORM)-$(ARCH) + endif endif # Default JDK to test @@ -149,6 +153,10 @@ ifdef TESTBOOTCLASSPATH -refvmoptions:-Xbootclasspath/p:$(TESTBOOTCLASSPATH) endif +ifdef EXTRA_JTREG_OPTIONS + JTREG_OPTIONS += $(EXTRA_JTREG_OPTIONS) +endif + # Concurrency is the number of tests that can execute at once. # On an otherwise empty machine, suggest setting to (#cpus + 2) # If unset, the default is (#cpus) @@ -262,6 +270,12 @@ javah: JTREG_TESTDIRS = tools/javah javap: JTREG_TESTDIRS = tools/javap jdeps: JTREG_TESTDIRS = tools/jdeps +# a way to select jtreg tests from outside +ifdef TEST_SELECTION + JTREG_TESTDIRS = $(TEST_SELECTION) +endif + + # Run jtreg tests # # JTREG_HOME @@ -290,13 +304,13 @@ jtreg-tests: check-jtreg FRC -J-Xmx512m \ -vmoption:-Xmx768m \ -a -ignore:quiet $(if $(JTREG_VERBOSE),-v:$(JTREG_VERBOSE)) \ - -r:$(JTREG_OUTPUT_DIR)/JTreport \ - -w:$(JTREG_OUTPUT_DIR)/JTwork \ - -jdk:$(TESTJAVA) \ - $(JAVA_ARGS:%=-vmoption:%) \ - $(JTREG_EXCLUSIONS) \ + -r:$(JTREG_OUTPUT_DIR)/JTreport \ + -w:$(JTREG_OUTPUT_DIR)/JTwork \ + -jdk:$(TESTJAVA) \ + $(JAVA_ARGS:%=-vmoption:%) \ + $(JTREG_EXCLUSIONS) \ $(JTREG_OPTIONS) \ - $(JTREG_TESTDIRS) \ + $(JTREG_TESTDIRS) \ || ( $(call EXIT_IF_FATAL,$(FATAL_JTREG_EXIT)) ; \ echo $$status > $(JTREG_OUTPUT_DIR)/status.txt \ ) diff --git a/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java b/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java index d887c0933a7..1848e172ab7 100644 --- a/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java +++ b/langtools/test/jdk/javadoc/doclet/testModules/TestModules.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8154119 + * @bug 8154119 8154262 * @summary Test modules support in javadoc. * @author bpatel * @library ../lib @@ -41,46 +41,58 @@ public class TestModules extends JavadocTester { @Test void test1() { - javadoc("-d", "out", + javadoc("-d", "out", "-use", "-modulesourcepath", testSrc, "-addmods", "module1,module2", "testpkgmdl1", "testpkgmdl2"); checkExit(Exit.OK); testDescription(true); testNoDescription(false); + testModuleLink(); } @Test void test2() { - javadoc("-d", "out-html5", "-html5", + javadoc("-d", "out-html5", "-html5", "-use", "-modulesourcepath", testSrc, "-addmods", "module1,module2", "testpkgmdl1", "testpkgmdl2"); checkExit(Exit.OK); testHtml5Description(true); testHtml5NoDescription(false); + testModuleLink(); } @Test void test3() { - javadoc("-d", "out-nocomment", "-nocomment", + javadoc("-d", "out-nocomment", "-nocomment", "-use", "-modulesourcepath", testSrc, "-addmods", "module1,module2", "testpkgmdl1", "testpkgmdl2"); checkExit(Exit.OK); testDescription(false); testNoDescription(true); + testModuleLink(); } @Test void test4() { - javadoc("-d", "out-html5-nocomment", "-nocomment", "-html5", + javadoc("-d", "out-html5-nocomment", "-nocomment", "-html5", "-use", "-modulesourcepath", testSrc, "-addmods", "module1,module2", "testpkgmdl1", "testpkgmdl2"); checkExit(Exit.OK); testHtml5Description(false); testHtml5NoDescription(true); + testModuleLink(); + } + + @Test + void test5() { + javadoc("-d", "out-nomodule", "-use", + "-sourcepath", testSrc, + "testpkgnomodule"); + checkExit(Exit.OK); } void testDescription(boolean found) { @@ -142,4 +154,37 @@ public class TestModules extends JavadocTester { + "<li class=\"blockList\">\n" + "<table class=\"overviewSummary\">"); } + + void testModuleLink() { + checkOutput("overview-summary.html", true, + "<li>Module</li>"); + checkOutput("module1-summary.html", true, + "<li class=\"navBarCell1Rev\">Module</li>"); + checkOutput("module2-summary.html", true, + "<li class=\"navBarCell1Rev\">Module</li>"); + checkOutput("testpkgmdl1/package-summary.html", true, + "<li><a href=\"../module1-summary.html\">Module</a></li>"); + checkOutput("testpkgmdl1/TestClassInModule1.html", true, + "<li><a href=\"../module1-summary.html\">Module</a></li>"); + checkOutput("testpkgmdl1/class-use/TestClassInModule1.html", true, + "<li><a href=\"../../module1-summary.html\">Module</a></li>"); + checkOutput("testpkgmdl2/package-summary.html", true, + "<li><a href=\"../module2-summary.html\">Module</a></li>"); + checkOutput("testpkgmdl2/TestClassInModule2.html", true, + "<li><a href=\"../module2-summary.html\">Module</a></li>"); + checkOutput("testpkgmdl2/class-use/TestClassInModule2.html", true, + "<li><a href=\"../../module2-summary.html\">Module</a></li>"); + } + + void testNoModuleLink() { + checkOutput("testpkgnomodule/package-summary.html", true, + "<ul class=\"navList\" title=\"Navigation\">\n" + + "<li><a href=\"../testpkgnomodule/package-summary.html\">Package</a></li>"); + checkOutput("testpkgnomodule/TestClassNoModule.html", true, + "<ul class=\"navList\" title=\"Navigation\">\n" + + "<li><a href=\"../testpkgnomodule/package-summary.html\">Package</a></li>"); + checkOutput("testpkgnomodule/class-use/TestClassNoModule.html", true, + "<ul class=\"navList\" title=\"Navigation\">\n" + + "<li><a href=\"../../testpkgnomodule/package-summary.html\">Package</a></li>"); + } } diff --git a/jdk/src/java.httpclient/share/classes/java/net/http/HttpHeaders1.java b/langtools/test/jdk/javadoc/doclet/testModules/testpkgnomodule/TestClassNoModule.java similarity index 85% rename from jdk/src/java.httpclient/share/classes/java/net/http/HttpHeaders1.java rename to langtools/test/jdk/javadoc/doclet/testModules/testpkgnomodule/TestClassNoModule.java index c9ff689a931..018413ec8a0 100644 --- a/jdk/src/java.httpclient/share/classes/java/net/http/HttpHeaders1.java +++ b/langtools/test/jdk/javadoc/doclet/testModules/testpkgnomodule/TestClassNoModule.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -20,10 +20,9 @@ * * 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 testpkgnomodule; -package java.net.http; - -public interface HttpHeaders1 extends HttpHeaders { - public void makeUnmodifiable(); +public class TestClassNoModule { } diff --git a/langtools/test/jdk/jshell/CompletionSuggestionTest.java b/langtools/test/jdk/jshell/CompletionSuggestionTest.java index 10b7b94a2aa..beb5a783a00 100644 --- a/langtools/test/jdk/jshell/CompletionSuggestionTest.java +++ b/langtools/test/jdk/jshell/CompletionSuggestionTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8141092 + * @bug 8141092 8153761 * @summary Test Completion * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -34,14 +34,20 @@ * @run testng CompletionSuggestionTest */ +import java.io.IOException; +import java.lang.reflect.Field; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Collections; import java.util.Set; import java.util.HashSet; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; import jdk.jshell.Snippet; +import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import static jdk.jshell.Snippet.Status.VALID; @@ -295,10 +301,11 @@ public class CompletionSuggestionTest extends KullaTesting { assertCompletion("import inner.|"); } - public void testDocumentation() { + public void testDocumentation() throws Exception { + dontReadParameterNamesFromClassFile(); assertDocumentation("System.getProperty(|", - "java.lang.System.getProperty(java.lang.String arg0)", - "java.lang.System.getProperty(java.lang.String arg0, java.lang.String arg1)"); + "java.lang.System.getProperty(java.lang.String key)", + "java.lang.System.getProperty(java.lang.String key, java.lang.String def)"); assertEval("char[] chars = null;"); assertDocumentation("new String(chars, |", "java.lang.String(char[] arg0, int arg1, int arg2)"); @@ -313,7 +320,8 @@ public class CompletionSuggestionTest extends KullaTesting { "java.lang.String.getBytes(java.nio.charset.Charset arg0)"); } - public void testMethodsWithNoArguments() { + public void testMethodsWithNoArguments() throws Exception { + dontReadParameterNamesFromClassFile(); assertDocumentation("System.out.println(|", "java.io.PrintStream.println()", "java.io.PrintStream.println(boolean arg0)", @@ -442,29 +450,30 @@ public class CompletionSuggestionTest extends KullaTesting { public void testDocumentationOfUserDefinedMethods() { assertEval("void f() {}"); assertDocumentation("f(|", "f()"); - assertEval("void f(int a) {}"); - assertDocumentation("f(|", "f()", "f(int arg0)"); - assertEval("<T> void f(T... a) {}", DiagCheck.DIAG_WARNING, DiagCheck.DIAG_OK); - assertDocumentation("f(|", "f()", "f(int arg0)", "f(T... arg0)"); + assertEval("void f(int i) {}"); + assertDocumentation("f(|", "f()", "f(int i)"); + assertEval("<T> void f(T... ts) {}", DiagCheck.DIAG_WARNING, DiagCheck.DIAG_OK); + assertDocumentation("f(|", "f()", "f(int i)", "f(T... ts)"); assertEval("class A {}"); assertEval("void f(A a) {}"); - assertDocumentation("f(|", "f()", "f(int arg0)", "f(T... arg0)", "f(A arg0)"); + assertDocumentation("f(|", "f()", "f(int i)", "f(T... ts)", "f(A a)"); } public void testDocumentationOfUserDefinedConstructors() { Snippet a = classKey(assertEval("class A {}")); assertDocumentation("new A(|", "A()"); - Snippet a2 = classKey(assertEval("class A { A() {} A(int a) {}}", + Snippet a2 = classKey(assertEval("class A { A() {} A(int i) {}}", ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET))); - assertDocumentation("new A(|", "A()", "A(int arg0)"); - assertEval("class A<T> { A(T a) {} A(int a) {}}", + assertDocumentation("new A(|", "A()", "A(int i)"); + assertEval("class A<T> { A(T t) {} A(int i) {}}", ste(MAIN_SNIPPET, VALID, VALID, true, null), ste(a2, VALID, OVERWRITTEN, false, MAIN_SNIPPET)); - assertDocumentation("new A(|", "A(T arg0)", "A(int arg0)"); + assertDocumentation("new A(|", "A(T t)", "A(int i)"); } - public void testDocumentationOfOverriddenMethods() { + public void testDocumentationOfOverriddenMethods() throws Exception { + dontReadParameterNamesFromClassFile(); assertDocumentation("\"\".wait(|", "java.lang.Object.wait(long arg0)", "java.lang.Object.wait(long arg0, int arg1)", @@ -502,13 +511,13 @@ public class CompletionSuggestionTest extends KullaTesting { assertEval("void method(int n, Object o) { }"); assertEval("void method(Object n, int o) { }"); assertDocumentation("method(primitive,|", - "method(int arg0, java.lang.Object arg1)", - "method(java.lang.Object arg0, int arg1)"); + "method(int n, java.lang.Object o)", + "method(java.lang.Object n, int o)"); assertDocumentation("method(boxed,|", - "method(int arg0, java.lang.Object arg1)", - "method(java.lang.Object arg0, int arg1)"); + "method(int n, java.lang.Object o)", + "method(java.lang.Object n, int o)"); assertDocumentation("method(object,|", - "method(java.lang.Object arg0, int arg1)"); + "method(java.lang.Object n, int o)"); } public void testVarArgs() { @@ -546,4 +555,36 @@ public class CompletionSuggestionTest extends KullaTesting { assertEval("class Foo { static void m(String str) {} static void m(Baz<String> baz) {} }"); assertCompletion("Foo.m(new Baz<>(|", true, "str"); } + + @BeforeMethod + public void setUp() { + super.setUp(); + + Path srcZip = Paths.get("src.zip"); + + try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(srcZip))) { + out.putNextEntry(new JarEntry("java/lang/System.java")); + out.write(("package java.lang;\n" + + "public class System {\n" + + " public String getProperty(String key) { return null; }\n" + + " public String getProperty(String key, String def) { return def; }\n" + + "}\n").getBytes()); + } catch (IOException ex) { + throw new IllegalStateException(ex); + } + + try { + Field availableSources = getAnalysis().getClass().getDeclaredField("availableSources"); + availableSources.setAccessible(true); + availableSources.set(getAnalysis(), Arrays.asList(srcZip)); + } catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException ex) { + throw new IllegalStateException(ex); + } + } + + private void dontReadParameterNamesFromClassFile() throws Exception { + Field keepParameterNames = getAnalysis().getClass().getDeclaredField("keepParameterNames"); + keepParameterNames.setAccessible(true); + keepParameterNames.set(getAnalysis(), new String[0]); + } } diff --git a/langtools/test/tools/javac/6330997/T6330997.java b/langtools/test/tools/javac/6330997/T6330997.java index c5de10eefba..8fa38415296 100644 --- a/langtools/test/tools/javac/6330997/T6330997.java +++ b/langtools/test/tools/javac/6330997/T6330997.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,8 +32,8 @@ * jdk.compiler/com.sun.tools.javac.main * jdk.compiler/com.sun.tools.javac.util * @clean T1 T2 - * @compile -source 8 -target 8 T1.java - * @compile -source 8 -target 8 T2.java + * @compile -source 9 -target 9 T1.java + * @compile -source 9 -target 9 T2.java * @run main/othervm T6330997 */ diff --git a/langtools/test/tools/javac/classfiles/ClassVersionChecker.java b/langtools/test/tools/javac/classfiles/ClassVersionChecker.java index 0ab5aee4a0a..419ec1313da 100644 --- a/langtools/test/tools/javac/classfiles/ClassVersionChecker.java +++ b/langtools/test/tools/javac/classfiles/ClassVersionChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016, 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 @@ -38,7 +38,7 @@ import java.util.regex.*; public class ClassVersionChecker { int errors; - String[] jdk = {"","1.6","1.7","1.8"}; + String[] jdk = {"", "1.6", "1.7", "1.8", "1.9"}; File javaFile = null; public static void main(String[] args) throws Throwable { @@ -58,10 +58,10 @@ public class ClassVersionChecker { * -1 => invalid combinations */ int[][] ver = - {{52, -1, -1, -1}, - {52, 50, 51, 52}, - {52, -1, 51, 52}, - {52, -1, -1, 52}}; + {{53, -1, -1, -1, -1}, + {53, 50, 51, 52, 53}, + {53, -1, 51, 52, 53}, + {53, -1, -1, 52, 53}}; // Loop to run all possible combinations of source/target values for (int i = 0; i< ver.length; i++) { diff --git a/langtools/test/tools/javac/importscope/TestDeepFinishClassStack.java b/langtools/test/tools/javac/importscope/TestDeepFinishClassStack.java new file mode 100644 index 00000000000..0b7bc3e18b3 --- /dev/null +++ b/langtools/test/tools/javac/importscope/TestDeepFinishClassStack.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2016, 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 8156097 + * @summary Check that nested TypeEnter.MembersPhase invocations don't cause StackOverflowError + * @library /tools/lib + * @modules jdk.compiler/com.sun.tools.javac.api + * jdk.compiler/com.sun.tools.javac.main + */ +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; + +import toolbox.JavacTask; +import toolbox.ToolBox; + +public class TestDeepFinishClassStack { + public static void main(String... args) throws IOException { + new TestDeepFinishClassStack().run(); + } + + int depth = 1000; + + void run() throws IOException { + Path src = Paths.get("src"); + + Files.createDirectories(src); + + ToolBox tb = new ToolBox(); + + for (int i = 0; i < depth; i++) { + tb.writeJavaFiles(src, "public class C" + i + " { public void test(C" + (i + 1) + " c) { } }"); + } + + tb.writeJavaFiles(src, "public class C" + depth + " { }"); + + new JavacTask(tb).files(src.resolve("C0.java")) + .sourcepath(src) + .outdir(".") + .run() + .writeAll(); + } + +} diff --git a/langtools/test/tools/javac/versions/Versions.java b/langtools/test/tools/javac/versions/Versions.java index f4a6eaeb26f..f90f44935c9 100644 --- a/langtools/test/tools/javac/versions/Versions.java +++ b/langtools/test/tools/javac/versions/Versions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2016, 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,16 +61,14 @@ public class Versions { void run() { - String jdk9cv = "52.0"; // class version.change when ./dev pushed to 53 - String TC = ""; System.out.println("Version.java: Starting"); - check("52.0"); - check("52.0", "-source 1.6"); - check("52.0", "-source 1.7"); - check("52.0", "-source 1.8"); - check(jdk9cv, "-source 1.9"); + check("53.0"); + check("53.0", "-source 1.6"); + check("53.0", "-source 1.7"); + check("53.0", "-source 1.8"); + check("53.0", "-source 1.9"); check_source_target("50.0", "6", "6"); check_source_target("51.0", "6", "7"); @@ -78,10 +76,10 @@ public class Versions { check_source_target("52.0", "6", "8"); check_source_target("52.0", "7", "8"); check_source_target("52.0", "8", "8"); - check_source_target(jdk9cv, "6", "9"); - check_source_target(jdk9cv, "7", "9"); - check_source_target(jdk9cv, "8", "9"); - check_source_target(jdk9cv, "9", "9"); + check_source_target("53.0", "6", "9"); + check_source_target("53.0", "7", "9"); + check_source_target("53.0", "8", "9"); + check_source_target("53.0", "9", "9"); checksrc16("-source 1.6"); checksrc16("-source 6"); diff --git a/make/Images.gmk b/make/Images.gmk index 302bc2b3e42..564f2b27ddb 100644 --- a/make/Images.gmk +++ b/make/Images.gmk @@ -114,8 +114,18 @@ JMODS := $(wildcard $(IMAGES_OUTPUTDIR)/jmods/*.jmod) # Use this file inside the image as target for make rule JIMAGE_TARGET_FILE := bin/java$(EXE_SUFFIX) +JLINK_ORDER_RESOURCES := \ + *module-info.class* \ + @$(SUPPORT_OUTPUTDIR)/classlist/classlist,/java.base/java/* \ + /java.base/jdk/* \ + /java.base/sun/* \ + /java.base/com/* \ + /jdk.localedata/* \ + # + JLINK_TOOL := $(JLINK) --modulepath $(IMAGES_OUTPUTDIR)/jmods \ --endian $(OPENJDK_BUILD_CPU_ENDIAN) \ + --order-resources=$(call CommaList, $(JLINK_ORDER_RESOURCES)) \ --release-info $(BASE_RELEASE_FILE) ifeq ($(JLINK_KEEP_PACKAGED_MODULES), true) diff --git a/make/common/NativeCompilation.gmk b/make/common/NativeCompilation.gmk index d595e044013..db09eb5bbf3 100644 --- a/make/common/NativeCompilation.gmk +++ b/make/common/NativeCompilation.gmk @@ -770,13 +770,20 @@ define SetupNativeCompilationBody $$(call ExecuteWithLog, $$@, \ $$($1_RC) $$($1_RC_FLAGS) $$($1_SYSROOT_CFLAGS) $(CC_OUT_OPTION)$$@ \ $$($1_VERSIONINFO_RESOURCE)) - # Windows RC compiler does not support -showIncludes, so we mis-use CL for this. + # Windows RC compiler does not support -showIncludes, so we mis-use CL + # for this. Filter out RC specific arguments that are unknown to CL. + # For some unknown reason, in this case CL actually outputs the show + # includes to stderr so need to redirect it to hide the output from the + # main log. $$(call ExecuteWithLog, $$($1_RES_DEP).obj, \ - $$($1_CC) $$($1_RC_FLAGS) $$($1_SYSROOT_CFLAGS) -showIncludes -nologo -TC \ - $(CC_OUT_OPTION)$$($1_RES_DEP).obj -P -Fi$$($1_RES_DEP).pp \ - $$($1_VERSIONINFO_RESOURCE)) > $$($1_RES_DEP).raw 2>&1 || true ; \ + $$($1_CC) $$(filter-out -l%, $$($1_RC_FLAGS)) \ + $$($1_SYSROOT_CFLAGS) -showIncludes -nologo -TC \ + $(CC_OUT_OPTION)$$($1_RES_DEP).obj -P -Fi$$($1_RES_DEP).pp \ + $$($1_VERSIONINFO_RESOURCE)) 2>&1 \ + | $(GREP) -v -e "^Note: including file:" \ + -e "^$$(notdir $$($1_VERSIONINFO_RESOURCE))$$$$" || test "$$$$?" = "1" ; \ $(ECHO) $$($1_RES): \\ > $$($1_RES_DEP) ; \ - $(SED) $(WINDOWS_SHOWINCLUDE_SED_PATTERN) $$($1_RES_DEP).raw >> $$($1_RES_DEP) ; \ + $(SED) $(WINDOWS_SHOWINCLUDE_SED_PATTERN) $$($1_RES_DEP).obj.log >> $$($1_RES_DEP) ; \ $(SED) $(DEPENDENCY_TARGET_SED_PATTERN) $$($1_RES_DEP) > $$($1_RES_DEP_TARGETS) endif endif diff --git a/make/idea/idea.gmk b/make/idea/idea.gmk new file mode 100644 index 00000000000..329c01cd5ea --- /dev/null +++ b/make/idea/idea.gmk @@ -0,0 +1,39 @@ +include Makefile +include make/MainSupport.gmk + +.PHONY: idea + +ifeq ($(SPEC),) + ifneq ($(words $(SPECS)),1) + @echo "Error: Multiple build specification files found. Please select one explicitly." + @exit 2 + endif + idea: + @cd $(topdir) + @$(MAKE) $(MFLAGS) $(MAKE_LOG_FLAGS) -r -R -j 1 -f $(topdir)/make/idea/idea.gmk SPEC=$(SPECS) HAS_SPEC=true ACTUAL_TOPDIR=$(topdir) MODULES="$(MODULES)" idea +else #with SPEC + include make/common/Modules.gmk + + ifeq ($(MODULES),) + SEL_MODULES := $(call FindAllModules) + else + SEL_MODULES := $(MODULES) + endif + + # Find all source dirs for a particular module + # $1 - Module to find source dirs for + FindIdeaModuleSrcDirs = \ + $(strip $(addsuffix /$(strip $1), $(GENERATED_SRC_DIRS) $(IMPORT_MODULES_SRC)) \ + $(wildcard $(foreach sub, $(SRC_SUBDIRS), $(addsuffix /$(strip $1)/$(sub), $(TOP_SRC_DIRS))))) + + + idea: + $(ECHO) "SUPPORT=$(SUPPORT_OUTPUTDIR)" >> $(OUT) + $(ECHO) "MODULE_ROOTS=\"$(foreach mod, $(SEL_MODULES), $(call FindIdeaModuleSrcDirs,$(mod)))\"" >> $(OUT) + $(ECHO) "MODULE_NAMES=\"$(strip $(foreach mod, $(SEL_MODULES), $(mod)))\"" >> $(OUT) + $(ECHO) "SEL_MODULES=\"$(SEL_MODULES)\"" >> $(OUT) + $(ECHO) "BOOT_JDK=\"$(BOOT_JDK)\"" >> $(OUT) + $(ECHO) "CYGPATH=\"$(CYGPATH)\"" >> $(OUT) + $(ECHO) "SPEC=\"$(SPEC)\"" >> $(OUT) + +endif diff --git a/make/idea/template/.name b/make/idea/template/.name new file mode 100644 index 00000000000..b4835685793 --- /dev/null +++ b/make/idea/template/.name @@ -0,0 +1 @@ +jdk diff --git a/make/idea/template/ant.xml b/make/idea/template/ant.xml new file mode 100644 index 00000000000..6e72e478cbc --- /dev/null +++ b/make/idea/template/ant.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="AntConfiguration"> + <buildFile url="file://$PROJECT_DIR$/.idea/build.xml"> + <properties> + <property name="boot.java.home" value="$JDKPath$" /> + <property name="jtreg.tests" value="$FilePath$" /> + <property name="jtreg.home" value="###" /> + <property name="build.target.dir" value="specDir" /> <!-- this will be replaced --> + <property name="jtreg.jpda.jvmargs" value="-agentlib:jdwp=transport=dt_socket,server=n,address=localhost:5900,suspend=y" /> + <property name="module.name" value="java.base" /> <!-- this will be replaced --> + </properties> + <executeOn event="afterCompilation" target="post-make" /> + </buildFile> + </component> +</project> diff --git a/make/idea/template/build.xml b/make/idea/template/build.xml new file mode 100644 index 00000000000..ed62f296726 --- /dev/null +++ b/make/idea/template/build.xml @@ -0,0 +1,126 @@ +<!-- importing.xml --> +<project name="jdk" basedir=".."> + + <script language="javascript" classpath=".idea/classes"> + var JdkLogger = Java.type("idea.JdkIdeaAntLogger"); + new JdkLogger(project) + </script> + + <!-- java.marker is set to a marker file to check for within a Java install dir. + The best file to check for across Solaris/Linux/Windows/MacOS is one of the + executables; regrettably, that is OS-specific. --> + <condition property="java.marker" value="bin/java"> + <os family="unix"/> + </condition> + <condition property="java.marker" value="bin/java.exe"> + <os family="windows"/> + </condition> + + <property name="test.dir" value="${basedir}/jdk/test"/> + + <macrodef name="call-make"> + <attribute name="dir"/> + <attribute name="args"/> + <sequential> + <exec executable="make" dir="@{dir}" failonerror="true"> + <arg line="@{args}"/> + <env key="CLASSPATH" value = ""/> + </exec> + </sequential> + </macrodef> + + <macrodef name="exec-target"> + <attribute name="antfile" default="${ant.file}" /> + <attribute name="target" /> + <sequential> + <java classname="org.apache.tools.ant.Main" fork="true" spawn="true"> + <arg value="-f"/> + <arg value="@{antfile}"/> + <arg value="-Dboot.java.home=${boot.java.home}"/> + <arg value="-Dbuild.target.dir=${build.target.dir}"/> + <arg value="-Djtreg.home=${jtreg.home}"/> + <arg value="-Djtreg.tests=${jtreg.tests}"/> + <arg value="-Djtreg.jpda.jvmargs=${jtreg.jpda.jvmargs}"/> + <arg value="@{target}"/> + <classpath> + <pathelement path="${java.class.path}"/> + </classpath> + </java> + </sequential> + </macrodef> + + <target name="post-make" depends="build-module"/> + + <!-- + **** Global JDK Build Targets + --> + + <target name="clean" depends="-do-configure"> + <echo message="base = ${basedir}"/> + <call-make dir = "${build.target.dir}" args = "clean"/> + </target> + + <target name="-do-configure"> + <echo message="base = ${basedir}"/> + <fail message="Not part of a full JDK forest"> + <condition> + <not> + <available file="${basedir}/configure" /> + </not> + </condition> + </fail> + <exec executable="sh" dir="${basedir}" failonerror="true"> + <arg line="configure --with-boot-jdk=${boot.java.home}"/> + </exec> + </target> + + <target name="images"> + <call-make dir = "${build.target.dir}" args = "images"/> + </target> + + <target name="jimages"> + <call-make dir = "${build.target.dir}" args = "jimages"/> + </target> + + <target name="check-env"> + <exec executable="env" dir="${basedir}"/> + </target> + + <target name="build-module"> + <call-make dir = "${build.target.dir}" args = "${module.name}"/> + </target> + + <target name="-check-boot.java.home" depends="-def-check"> + <check name="bootstrap java" property="boot.java.home" marker="${java.marker}"/> + </target> + + <target name="-def-check"> + <macrodef name="check"> + <attribute name="name"/> + <attribute name="property"/> + <attribute name="marker" default=""/> + <sequential> + <fail message="Cannot locate @{name}: please set @{property} to its location"> + <condition> + <not> + <isset property="@{property}"/> + </not> + </condition> + </fail> + <fail message="@{name} is not installed in ${@{property}}"> + <condition> + <and> + <not> + <equals arg1="@{marker}" arg2=""/> + </not> + <not> + <available file="${@{property}}/@{marker}"/> + </not> + </and> + </condition> + </fail> + </sequential> + </macrodef> + </target> +</project> + diff --git a/make/idea/template/compiler.xml b/make/idea/template/compiler.xml new file mode 100644 index 00000000000..f801895e7f7 --- /dev/null +++ b/make/idea/template/compiler.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="CompilerConfiguration"> + <option name="DEFAULT_COMPILER" value="Javac" /> + <excludeFromCompile> + <directory url="file://$PROJECT_DIR$/jdk/src" includeSubdirectories="true" /> + <directory url="file://$PROJECT_DIR$/langtools/src" includeSubdirectories="true" /> + <directory url="file://$PROJECT_DIR$/jaxp/src" includeSubdirectories="true" /> + <directory url="file://$PROJECT_DIR$/jaxws/src" includeSubdirectories="true" /> + <directory url="file://$PROJECT_DIR$/corba/src" includeSubdirectories="true" /> + <directory url="file://$PROJECT_DIR$/nashorn/src" includeSubdirectories="true" /> + <directory url="file://$PROJECT_DIR$/build" includeSubdirectories="true" /> + <directory url="file://$PROJECT_DIR$/jdk/test" includeSubdirectories="true" /> + <directory url="file://$PROJECT_DIR$/jaxp/test" includeSubdirectories="true" /> + <directory url="file://$PROJECT_DIR$/langtools/test" includeSubdirectories="true" /> + <directory url="file://$PROJECT_DIR$/langtools" includeSubdirectories="true" /> + </excludeFromCompile> + <resourceExtensions /> + <wildcardResourcePatterns> + <entry name="!?*.java" /> + <entry name="!?*.form" /> + <entry name="!?*.class" /> + <entry name="!?*.groovy" /> + <entry name="!?*.scala" /> + <entry name="!?*.flex" /> + <entry name="!?*.kt" /> + <entry name="!?*.clj" /> + </wildcardResourcePatterns> + <annotationProcessing> + <profile default="true" name="Default" enabled="false"> + <processorPath useClasspath="true" /> + </profile> + </annotationProcessing> + </component> +</project> \ No newline at end of file diff --git a/make/idea/template/copyright/profiles_settings.xml b/make/idea/template/copyright/profiles_settings.xml new file mode 100644 index 00000000000..7d61b5cdf1f --- /dev/null +++ b/make/idea/template/copyright/profiles_settings.xml @@ -0,0 +1,3 @@ +<component name="CopyrightManager"> + <settings default="" /> +</component> diff --git a/make/idea/template/jdk.iml b/make/idea/template/jdk.iml new file mode 100644 index 00000000000..5e1436c949a --- /dev/null +++ b/make/idea/template/jdk.iml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<module type="JAVA_MODULE" version="4"> + <component name="NewModuleRootManager" inherit-compiler-output="true"> + <exclude-output /> + <content url="file://$MODULE_DIR$"> + <sourceFolder url="file://$MODULE_DIR$/####" isTestSource="false" /> + <sourceFolder url="file://$MODULE_DIR$/jdk/test" isTestSource="true" /> + <sourceFolder url="file://$MODULE_DIR$/langtools/test" isTestSource="true" /> + <sourceFolder url="file://$MODULE_DIR$/jaxp/test" isTestSource="true" /> + <excludeFolder url="file://$MODULE_DIR$/####/buildtools" /> + <excludeFolder url="file://$MODULE_DIR$/####/configure-support" /> + <excludeFolder url="file://$MODULE_DIR$/####/hotspot" /> + <excludeFolder url="file://$MODULE_DIR$/####/images" /> + <excludeFolder url="file://$MODULE_DIR$/####/ide" /> + <excludeFolder url="file://$MODULE_DIR$/####/jdk" /> + <excludeFolder url="file://$MODULE_DIR$/####/make-support" /> + <excludeFolder url="file://$MODULE_DIR$/####/testoutput" /> + </content> + <orderEntry type="sourceFolder" forTests="false" /> + <orderEntry type="inheritedJdk" /> + </component> +</module> diff --git a/make/idea/template/misc.xml b/make/idea/template/misc.xml new file mode 100644 index 00000000000..e5caa22e0d6 --- /dev/null +++ b/make/idea/template/misc.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="EntryPointsManager"> + <entry_points version="2.0" /> + </component> + <component name="ProjectRootManager" version="2" languageLevel="JDK_1_9" assert-keyword="true" jdk-15="true"> + <output url="file://$PROJECT_DIR$/build/idea/out" /> + </component> +</project> diff --git a/make/idea/template/modules.xml b/make/idea/template/modules.xml new file mode 100644 index 00000000000..2d8401d0398 --- /dev/null +++ b/make/idea/template/modules.xml @@ -0,0 +1,9 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ProjectModuleManager"> + <modules> + <module fileurl="file://$PROJECT_DIR$/.idea/jdk.iml" filepath="$PROJECT_DIR$/.idea/jdk.iml" /> + </modules> + </component> +</project> + diff --git a/make/idea/template/scopes/scope_settings.xml b/make/idea/template/scopes/scope_settings.xml new file mode 100644 index 00000000000..db1b8ba4462 --- /dev/null +++ b/make/idea/template/scopes/scope_settings.xml @@ -0,0 +1,5 @@ +<component name="DependencyValidationManager"> + <state> + <option name="SKIP_IMPORT_STATEMENTS" value="false" /> + </state> +</component> diff --git a/make/idea/template/src/idea/JdkIdeaAntLogger.java b/make/idea/template/src/idea/JdkIdeaAntLogger.java new file mode 100644 index 00000000000..9913499e7a0 --- /dev/null +++ b/make/idea/template/src/idea/JdkIdeaAntLogger.java @@ -0,0 +1,373 @@ +/* + * Copyright (c) 2014, 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 idea; + +import org.apache.tools.ant.BuildEvent; +import org.apache.tools.ant.BuildListener; +import org.apache.tools.ant.DefaultLogger; +import org.apache.tools.ant.Project; + +import java.util.EnumSet; +import java.util.Stack; + +import static org.apache.tools.ant.Project.*; + +/** + * This class is used to wrap the IntelliJ ant logger in order to provide more meaningful + * output when building langtools. The basic ant output in IntelliJ can be quite cumbersome to + * work with, as it provides two separate views: (i) a tree view, which is good to display build task + * in a hierarchical fashion as they are processed; and a (ii) plain text view, which gives you + * the full ant output. The main problem is that javac-related messages are buried into the + * ant output (which is made very verbose by IntelliJ in order to support the tree view). It is + * not easy to figure out which node to expand in order to see the error message; switching + * to plain text doesn't help either, as now the output is totally flat. + * + * This logger class removes a lot of verbosity from the IntelliJ ant logger by not propagating + * all the events to the IntelliJ's logger. In addition, certain events are handled in a custom + * fashion, to generate better output during the build. + */ +public final class JdkIdeaAntLogger extends DefaultLogger { + + /** + * This is just a way to pass in customized binary string predicates; + * + * TODO: replace with @code{BiPredicate<String, String>} and method reference when moving to 8 + */ + enum StringBinaryPredicate { + CONTAINS() { + @Override + boolean apply(String s1, String s2) { + return s1.contains(s2); + } + }, + STARTS_WITH { + @Override + boolean apply(String s1, String s2) { + return s1.startsWith(s2); + } + }, + MATCHES { + @Override + boolean apply(String s1, String s2) { + return s1.matches(s2); + } + }; + + abstract boolean apply(String s1, String s2); + } + + /** + * Various kinds of ant messages that we shall intercept + */ + enum MessageKind { + + /** a make error */ + MAKE_ERROR(StringBinaryPredicate.CONTAINS, MSG_ERR, "error:", "compiler.err"), + /** a make warning */ + MAKE_WARNING(StringBinaryPredicate.CONTAINS, MSG_WARN, "warning:", "compiler.warn"), + /** a make note */ + MAKE_NOTE(StringBinaryPredicate.CONTAINS, MSG_INFO, "note:", "compiler.note"), + /** std make output */ + MAKE_OTHER(StringBinaryPredicate.MATCHES, MSG_INFO, ".*"), + /** a javac crash */ + JAVAC_CRASH(StringBinaryPredicate.STARTS_WITH, MSG_ERR, "An exception has occurred in the compiler"), + /** jtreg test success */ + JTREG_TEST_PASSED(StringBinaryPredicate.STARTS_WITH, MSG_INFO, "Passed: "), + /** jtreg test failure */ + JTREG_TEST_FAILED(StringBinaryPredicate.STARTS_WITH, MSG_ERR, "FAILED: "), + /** jtreg test error */ + JTREG_TEST_ERROR(StringBinaryPredicate.STARTS_WITH, MSG_ERR, "Error: "); + + StringBinaryPredicate sbp; + int priority; + String[] keys; + + MessageKind(StringBinaryPredicate sbp, int priority, String... keys) { + this.sbp = sbp; + this.priority = priority; + this.keys = keys; + } + + /** + * Does a given message string matches this kind? + */ + boolean matches(String s) { + for (String key : keys) { + if (sbp.apply(s, key)) { + return true; + } + } + return false; + } + } + + /** + * This enum is used to represent the list of tasks we need to keep track of during logging. + */ + enum Task { + /** javac task - invoked during compilation */ + MAKE("exec", MessageKind.MAKE_ERROR, MessageKind.MAKE_WARNING, MessageKind.MAKE_NOTE, + MessageKind.MAKE_OTHER, MessageKind.JAVAC_CRASH), + /** jtreg task - invoked during test execution */ + JTREG("jtreg", MessageKind.JTREG_TEST_PASSED, MessageKind.JTREG_TEST_FAILED, MessageKind.JTREG_TEST_ERROR), + /** initial synthetic task when the logger is created */ + ROOT("") { + @Override + boolean matches(String s) { + return false; + } + }, + /** synthetic task catching any other tasks not in this list */ + ANY("") { + @Override + boolean matches(String s) { + return true; + } + }; + + String taskName; + MessageKind[] msgs; + + Task(String taskName, MessageKind... msgs) { + this.taskName = taskName; + this.msgs = msgs; + } + + boolean matches(String s) { + return s.equals(taskName); + } + } + + /** + * This enum is used to represent the list of targets we need to keep track of during logging. + * A regular expression is used to match a given target name. + */ + enum Target { + /** jtreg target - executed when launching tests */ + JTREG("jtreg") { + @Override + String getDisplayMessage(BuildEvent e) { + return "Running jtreg tests: " + e.getProject().getProperty("jtreg.tests"); + } + }, + /** build selected modules */ + BUILD_MODULE("build-module") { + @Override + String getDisplayMessage(BuildEvent e) { + return "Building modules: " + e.getProject().getProperty("module.name") + "..."; + } + }, + /** build images */ + BUILD_IMAGES("images") { + @Override + String getDisplayMessage(BuildEvent e) { + return "Building images..."; + } + }, + /** build images */ + CONFIGURE("-do-configure") { + @Override + String getDisplayMessage(BuildEvent e) { + return "Configuring build..."; + } + }, + /** synthetic target catching any other target not in this list */ + ANY("") { + @Override + String getDisplayMessage(BuildEvent e) { + return "Executing Ant target(s): " + e.getProject().getProperty("ant.project.invoked-targets"); + } + @Override + boolean matches(String msg) { + return true; + } + }; + + String targetRegex; + + Target(String targetRegex) { + this.targetRegex = targetRegex; + } + + boolean matches(String msg) { + return msg.matches(targetRegex); + } + + abstract String getDisplayMessage(BuildEvent e); + } + + /** + * A custom build event used to represent status changes which should be notified inside + * Intellij + */ + static class StatusEvent extends BuildEvent { + + /** the target to which the status update refers */ + Target target; + + StatusEvent(BuildEvent e, Target target) { + super(new StatusTask(e, target.getDisplayMessage(e))); + this.target = target; + setMessage(getTask().getTaskName(), 2); + } + + /** + * A custom task used to channel info regarding a status change + */ + static class StatusTask extends org.apache.tools.ant.Task { + StatusTask(BuildEvent event, String msg) { + setProject(event.getProject()); + setOwningTarget(event.getTarget()); + setTaskName(msg); + } + } + } + + /** wrapped ant logger (IntelliJ's own logger) */ + DefaultLogger logger; + + /** flag - is this the first target we encounter? */ + boolean firstTarget = true; + + /** flag - should subsequenet failures be suppressed ? */ + boolean suppressTaskFailures = false; + + /** flag - have we ran into a javac crash ? */ + boolean crashFound = false; + + /** stack of status changes associated with pending targets */ + Stack<StatusEvent> statusEvents = new Stack<>(); + + /** stack of pending tasks */ + Stack<Task> tasks = new Stack<>(); + + public JdkIdeaAntLogger(Project project) { + for (Object o : project.getBuildListeners()) { + if (o instanceof DefaultLogger) { + this.logger = (DefaultLogger)o; + project.removeBuildListener((BuildListener)o); + project.addBuildListener(this); + } + } + tasks.push(Task.ROOT); + } + + @Override + public void buildStarted(BuildEvent event) { + //do nothing + } + + @Override + public void buildFinished(BuildEvent event) { + //do nothing + } + + @Override + public void targetStarted(BuildEvent event) { + EnumSet<Target> statusKinds = firstTarget ? + EnumSet.allOf(Target.class) : + EnumSet.complementOf(EnumSet.of(Target.ANY)); + + String targetName = event.getTarget().getName(); + + for (Target statusKind : statusKinds) { + if (statusKind.matches(targetName)) { + StatusEvent statusEvent = new StatusEvent(event, statusKind); + statusEvents.push(statusEvent); + logger.taskStarted(statusEvent); + firstTarget = false; + return; + } + } + } + + @Override + public void targetFinished(BuildEvent event) { + if (!statusEvents.isEmpty()) { + StatusEvent lastEvent = statusEvents.pop(); + if (lastEvent.target.matches(event.getTarget().getName())) { + logger.taskFinished(lastEvent); + } + } + } + + @Override + public void taskStarted(BuildEvent event) { + String taskName = event.getTask().getTaskName(); + System.err.println("task started " + taskName); + for (Task task : Task.values()) { + if (task.matches(taskName)) { + tasks.push(task); + return; + } + } + } + + @Override + public void taskFinished(BuildEvent event) { + if (tasks.peek() == Task.ROOT) { + //we need to 'close' the root task to get nicer output + logger.taskFinished(event); + } else if (!suppressTaskFailures && event.getException() != null) { + //the first (innermost) task failure should always be logged + event.setMessage(event.getException().toString(), 0); + event.setException(null); + //note: we turn this into a plain message to avoid stack trace being logged by Idea + logger.messageLogged(event); + suppressTaskFailures = true; + } + tasks.pop(); + } + + @Override + public void messageLogged(BuildEvent event) { + String msg = event.getMessage(); + + boolean processed = false; + + if (!tasks.isEmpty()) { + Task task = tasks.peek(); + for (MessageKind messageKind : task.msgs) { + if (messageKind.matches(msg)) { + event.setMessage(msg, messageKind.priority); + processed = true; + if (messageKind == MessageKind.JAVAC_CRASH) { + crashFound = true; + } + break; + } + } + } + + if (event.getPriority() == MSG_ERR || crashFound) { + //we log errors regardless of owning task + logger.messageLogged(event); + suppressTaskFailures = true; + } else if (processed) { + logger.messageLogged(event); + } + } +} diff --git a/make/idea/template/vcs.xml b/make/idea/template/vcs.xml new file mode 100644 index 00000000000..876d3cd2ef8 --- /dev/null +++ b/make/idea/template/vcs.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="VcsDirectoryMappings"> + <mapping directory="$PROJECT_DIR$" vcs="hg4idea" /> + <mapping directory="$PROJECT_DIR$/jdk" vcs="hg4idea" /> + <mapping directory="$PROJECT_DIR$/langtools" vcs="hg4idea" /> + <mapping directory="$PROJECT_DIR$/hotspot" vcs="hg4idea" /> + <mapping directory="$PROJECT_DIR$/nashorn" vcs="hg4idea" /> + <mapping directory="$PROJECT_DIR$/jaxp" vcs="hg4idea" /> + <mapping directory="$PROJECT_DIR$/jaxws" vcs="hg4idea" /> + <mapping directory="$PROJECT_DIR$/corba" vcs="hg4idea" /> + </component> +</project> + diff --git a/make/idea/template/workspace.xml b/make/idea/template/workspace.xml new file mode 100644 index 00000000000..2423c3d41fb --- /dev/null +++ b/make/idea/template/workspace.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="ChangeListManager"> + <ignored path="jdk.iws" /> + <ignored path="$PROJECT_DIR$/build/idea/out/" /> + <ignored path=".idea/" /> + </component> + <component name="StructureViewFactory"> + <option name="ACTIVE_ACTIONS" value=",ALPHA_COMPARATOR" /> + </component> + <component name="antWorkspaceConfiguration"> + <option name="IS_AUTOSCROLL_TO_SOURCE" value="false" /> + <option name="FILTER_TARGETS" value="false" /> + <buildFile url="file://$PROJECT_DIR$/.idea/build.xml"> + <runInBackground value="false" /> + <targetFilters> + <filter targetName="post-make" isVisible="false" /> + <filter targetName="clean" isVisible="true" /> + <filter targetName="-do-configure" isVisible="false" /> + <filter targetName="images" isVisible="true" /> + <filter targetName="build-module" isVisible="true" /> + <filter targetName="jtreg-debug" isVisible="false" /> + <filter targetName="jtreg-debug-internal" isVisible="false" /> + <filter targetName="jtreg" isVisible="false" /> + <filter targetName="-check-jtreg.home" isVisible="false" /> + <filter targetName="-def-check" isVisible="false" /> + <filter targetName="-def-jtreg" isVisible="false" /> + <filter targetName="-check-boot.java.home" isVisible="false" /> + <filter targetName="-check-target.java.home" isVisible="false" /> + <filter targetName="find-jdk-build-dir" isVisible="false" /> + <filter targetName="check-env" isVisible="false" /> + </targetFilters> + <treeView value="false" /> + <expanded value="true" /> + </buildFile> + </component> + <component name="ProjectView"> + <navigator currentView="PackagesPane" proportions="" version="1"> + <flattenPackages /> + <showMembers /> + <showModules /> + <showLibraryContents /> + <hideEmptyPackages /> + <abbreviatePackageNames /> + <autoscrollToSource /> + <autoscrollFromSource /> + <sortByType /> + </navigator> + <panes> + <pane id="ProjectPane"> + <subPane> + <PATH> + <PATH_ELEMENT> + <option name="myItemId" value="jdk" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" /> + </PATH_ELEMENT> + </PATH> + </subPane> + </pane> + <pane id="PackagesPane"> + <subPane> + <PATH> + <PATH_ELEMENT> + <option name="myItemId" value="jdk" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewProjectNode" /> + </PATH_ELEMENT> + <PATH_ELEMENT> + <option name="myItemId" value="jdk" /> + <option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PackageViewModuleNode" /> + </PATH_ELEMENT> + </PATH> + </subPane> + </pane> + <pane id="Scope" /> + </panes> + </component> +</project> diff --git a/nashorn/.hgtags b/nashorn/.hgtags index 3a4c6daf2fb..2140054b988 100644 --- a/nashorn/.hgtags +++ b/nashorn/.hgtags @@ -351,3 +351,4 @@ ba21793a0e4816283cc0ecdab5142a4959363529 jdk-9+114 295ac208a4443d433214d0c1f32d2ea45a3a32d2 jdk-9+115 208388a5622dcca8227d6ad6c268f2c88087d283 jdk-9+116 5267e91811614bac129817e566f730e9d63cf22a jdk-9+117 +05679aac2f7ec3d8dd2a96d7e7899906224bf5cf jdk-9+118 diff --git a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinker.java b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinker.java index be981997107..703fd6ced2c 100644 --- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinker.java +++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 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 @@ -83,6 +83,7 @@ package jdk.dynalink; +import java.lang.StackWalker.StackFrame; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; @@ -172,6 +173,8 @@ public final class DynamicLinker { private static final String INITIAL_LINK_METHOD_NAME = "linkCallSite"; private static final String INVOKE_PACKAGE_PREFIX = "java.lang.invoke."; + private static final StackWalker stackWalker = StackWalker.getInstance(StackWalker.Option.SHOW_HIDDEN_FRAMES); + private final LinkerServices linkerServices; private final GuardedInvocationTransformer prelinkTransformer; private final boolean syncOnRelink; @@ -300,21 +303,16 @@ public final class DynamicLinker { * site is being linked. */ public static StackTraceElement getLinkedCallSiteLocation() { - final StackTraceElement[] trace = new Throwable().getStackTrace(); - for(int i = 0; i < trace.length - 1; ++i) { - final StackTraceElement frame = trace[i]; - // If we found any of our linking entry points on the stack... - if(isRelinkFrame(frame) || isInitialLinkFrame(frame)) { + return stackWalker.walk(s -> s + // Find one of our linking entry points on the stack... + .dropWhile(f -> !(isRelinkFrame(f) || isInitialLinkFrame(f))) + .skip(1) // ... then look for the first thing calling it that isn't j.l.invoke - for (int j = i + 1; j < trace.length; ++j) { - final StackTraceElement frame2 = trace[j]; - if (!frame2.getClassName().startsWith(INVOKE_PACKAGE_PREFIX)) { - return frame2; - } - } - } - } - return null; + .dropWhile(f -> f.getClassName().startsWith(INVOKE_PACKAGE_PREFIX)) + .findFirst() + .map(StackFrame::toStackTraceElement) + .orElse(null) + ); } /** @@ -326,7 +324,7 @@ public final class DynamicLinker { * * @return {@code true} if this frame represents {@code MethodHandleNatives.linkCallSite()}. */ - private static boolean isInitialLinkFrame(final StackTraceElement frame) { + private static boolean isInitialLinkFrame(final StackFrame frame) { return testFrame(frame, INITIAL_LINK_METHOD_NAME, INITIAL_LINK_CLASS_NAME); } @@ -339,11 +337,11 @@ public final class DynamicLinker { * * @return {@code true} if this frame represents {@code DynamicLinker.relink()}. */ - private static boolean isRelinkFrame(final StackTraceElement frame) { + private static boolean isRelinkFrame(final StackFrame frame) { return testFrame(frame, RELINK_METHOD_NAME, CLASS_NAME); } - private static boolean testFrame(final StackTraceElement frame, final String methodName, final String className) { + private static boolean testFrame(final StackFrame frame, final String methodName, final String className) { return methodName.equals(frame.getMethodName()) && className.equals(frame.getClassName()); } } diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornException.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornException.java index fc1a7464df0..b082076e593 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornException.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/api/scripting/NashornException.java @@ -174,10 +174,8 @@ public abstract class NashornException extends RuntimeException { String methodName = st.getMethodName(); if (methodName.equals(CompilerConstants.PROGRAM.symbolName())) { methodName = "<program>"; - } - - if (methodName.contains(CompilerConstants.ANON_FUNCTION_PREFIX.symbolName())) { - methodName = "<anonymous>"; + } else { + methodName = stripMethodName(methodName); } filtered.add(new StackTraceElement(className, methodName, @@ -187,6 +185,22 @@ public abstract class NashornException extends RuntimeException { return filtered.toArray(new StackTraceElement[0]); } + private static String stripMethodName(final String methodName) { + String name = methodName; + + final int nestedSeparator = name.lastIndexOf(CompilerConstants.NESTED_FUNCTION_SEPARATOR.symbolName()); + if (nestedSeparator >= 0) { + name = name.substring(nestedSeparator + 1); + } + + final int idSeparator = name.indexOf(CompilerConstants.ID_FUNCTION_SEPARATOR.symbolName()); + if (idSeparator >= 0) { + name = name.substring(0, idSeparator); + } + + return name.contains(CompilerConstants.ANON_FUNCTION_PREFIX.symbolName()) ? "<anonymous>" : name; + } + /** * Return a formatted script stack trace string with frames information separated by '\n' * diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilerConstants.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilerConstants.java index 0d64ac2ef64..28bd19f8709 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilerConstants.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/CompilerConstants.java @@ -78,6 +78,12 @@ public enum CompilerConstants { /** function prefix for anonymous functions */ ANON_FUNCTION_PREFIX("L:"), + /** separator for method names of nested functions */ + NESTED_FUNCTION_SEPARATOR("#"), + + /** separator for making method names unique by appending numeric ids */ + ID_FUNCTION_SEPARATOR("-"), + /** method name for Java method that is the program entry point */ PROGRAM(":program"), diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Namespace.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Namespace.java index 17304a905ab..08ae356ed64 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Namespace.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/codegen/Namespace.java @@ -68,7 +68,7 @@ public class Namespace { } /** - * Create a uniqueName name in the namespace in the form base$n where n varies. + * Create a uniqueName name in the namespace in the form base-n where n varies. * Also truncates very long names that would otherwise break ASM. * * @param base Base of name. Base will be returned if uniqueName. @@ -83,7 +83,7 @@ public class Namespace { if (counter != null) { final int count = counter + 1; namespaceDirectory.put(truncatedBase, count); - return truncatedBase + '-' + count; + return truncatedBase + CompilerConstants.ID_FUNCTION_SEPARATOR.symbolName() + count; } } diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/AbstractParser.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/AbstractParser.java index da61ff7ff5a..1b239da48aa 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/AbstractParser.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/AbstractParser.java @@ -203,8 +203,10 @@ public abstract class AbstractParser { * @return tokenType of next token. */ private TokenType nextToken() { - // Capture last token tokenType. - last = type; + // Capture last token type, but ignore comments (which are irrelevant for the purpose of newline detection). + if (type != COMMENT) { + last = type; + } if (type != EOF) { // Set up next token. diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java index dde20817853..6527f6be8d0 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/parser/Parser.java @@ -534,7 +534,7 @@ public class Parser extends AbstractParser implements Loggable { final ParserContextFunctionNode parentFunction = lc.getCurrentFunction(); if (parentFunction != null && !parentFunction.isProgram()) { - sb.append(parentFunction.getName()).append('$'); + sb.append(parentFunction.getName()).append(CompilerConstants.NESTED_FUNCTION_SEPARATOR.symbolName()); } assert ident.getName() != null; @@ -1827,7 +1827,7 @@ public class Parser extends AbstractParser implements Loggable { /** * ExpressionStatement : - * Expression ; // [lookahead ~( or function )] + * Expression ; // [lookahead ~({ or function )] * * See 12.4 * diff --git a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptRuntime.java b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptRuntime.java index 767989531e1..9ac75ecd217 100644 --- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptRuntime.java +++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptRuntime.java @@ -313,18 +313,8 @@ public final class ScriptRuntime { } } - /** - * Returns an iterator over property values used in the {@code for each...in} statement. Aside from built-in JS - * objects, it also operates on Java arrays, any {@link Iterable}, as well as on {@link Map} objects, iterating over - * map values. - * @param obj object to iterate on. - * @return iterator over the object's property values. - */ - public static Iterator<?> toValueIterator(final Object obj) { - if (obj instanceof ScriptObject) { - return ((ScriptObject)obj).valueIterator(); - } - + // value Iterator for important Java objects - arrays, maps, iterables. + private static Iterator<?> iteratorForJavaArrayOrList(final Object obj) { if (obj != null && obj.getClass().isArray()) { final Object array = obj; final int length = Array.getLength(obj); @@ -352,16 +342,36 @@ public final class ScriptRuntime { }; } + if (obj instanceof Iterable) { + return ((Iterable<?>)obj).iterator(); + } + + return null; + } + + /** + * Returns an iterator over property values used in the {@code for each...in} statement. Aside from built-in JS + * objects, it also operates on Java arrays, any {@link Iterable}, as well as on {@link Map} objects, iterating over + * map values. + * @param obj object to iterate on. + * @return iterator over the object's property values. + */ + public static Iterator<?> toValueIterator(final Object obj) { + if (obj instanceof ScriptObject) { + return ((ScriptObject)obj).valueIterator(); + } + if (obj instanceof JSObject) { return ((JSObject)obj).values().iterator(); } - if (obj instanceof Map) { - return ((Map<?,?>)obj).values().iterator(); + final Iterator<?> itr = iteratorForJavaArrayOrList(obj); + if (itr != null) { + return itr; } - if (obj instanceof Iterable) { - return ((Iterable<?>)obj).iterator(); + if (obj instanceof Map) { + return ((Map<?,?>)obj).values().iterator(); } final Object wrapped = Global.instance().wrapAsObject(obj); @@ -380,6 +390,14 @@ public final class ScriptRuntime { * @return iterator based on the ECMA 6 Iterator interface. */ public static Iterator<?> toES6Iterator(final Object obj) { + // if not a ScriptObject, try convenience iterator for Java objects! + if (!(obj instanceof ScriptObject)) { + final Iterator<?> itr = iteratorForJavaArrayOrList(obj); + if (itr != null) { + return itr; + } + } + final Global global = Global.instance(); final Object iterator = AbstractIterator.getIterator(Global.toObject(obj), global); diff --git a/nashorn/test/Makefile b/nashorn/test/Makefile new file mode 100644 index 00000000000..d4f5afe6da1 --- /dev/null +++ b/nashorn/test/Makefile @@ -0,0 +1,371 @@ +# +# Copyright (c) 1995, 2015, 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. +# + +# +# Makefile to run various nashorn tests +# + +.DEFAULT : all + +# Empty these to get rid of some default rules +.SUFFIXES: +.SUFFIXES: .java +CO= +GET= + +# Utilities used +AWK = awk +CAT = cat +CD = cd +CHMOD = chmod +CP = cp +CUT = cut +DIRNAME = dirname +ECHO = echo +EGREP = egrep +EXPAND = expand +FIND = find +MKDIR = mkdir +PWD = pwd +SED = sed +SORT = sort +TEE = tee +UNAME = uname +UNIQ = uniq +WC = wc +ZIP = zip + +# Get OS name from uname (Cygwin inexplicably adds _NT-5.1) +UNAME_S := $(shell $(UNAME) -s | $(CUT) -f1 -d_) + +# Commands to run on paths to make mixed paths for java on windows +ifeq ($(UNAME_S), CYGWIN) + # Location of developer shared files + SLASH_JAVA = J: + GETMIXEDPATH = cygpath -m +else + # Location of developer shared files + SLASH_JAVA = /java + + GETMIXEDPATH=$(ECHO) +endif + +# Root of this test area (important to use full paths in some places) +TEST_ROOT := $(shell $(PWD)) + +# Root of all test results +ifdef TEST_OUTPUT_DIR + $(shell $(MKDIR) -p $(TEST_OUTPUT_DIR)/jtreg) + ABS_TEST_OUTPUT_DIR := \ + $(shell $(CD) $(TEST_OUTPUT_DIR)/jtreg && $(PWD)) +else + ifdef ALT_OUTPUTDIR + ABS_OUTPUTDIR = $(shell $(CD) $(ALT_OUTPUTDIR) && $(PWD)) + else + ABS_OUTPUTDIR = $(shell $(CD) $(TEST_ROOT)/.. && $(PWD)) + endif + + ABS_PLATFORM_BUILD_ROOT = $(ABS_OUTPUTDIR) + ABS_TEST_OUTPUT_DIR := $(ABS_PLATFORM_BUILD_ROOT)/testoutput/$(UNIQUE_DIR) +endif + +# Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test) +ifndef PRODUCT_HOME + # Try to use images/jdk if it exists + ABS_JDK_IMAGE = $(ABS_PLATFORM_BUILD_ROOT)/images/jdk + PRODUCT_HOME := \ + $(shell \ + if [ -d $(ABS_JDK_IMAGE) ] ; then \ + $(ECHO) "$(ABS_JDK_IMAGE)"; \ + else \ + $(ECHO) "$(ABS_PLATFORM_BUILD_ROOT)"; \ + fi) + PRODUCT_HOME := $(PRODUCT_HOME) +endif + +# Expect JPRT to set JPRT_PRODUCT_ARGS (e.g. -server etc.) +# Should be passed into 'java' only. +# Could include: -d64 -server -client OR any java option +ifdef JPRT_PRODUCT_ARGS + JAVA_ARGS = $(JPRT_PRODUCT_ARGS) +endif + +# Expect JPRT to set JPRT_PRODUCT_VM_ARGS (e.g. -Xcomp etc.) +# Should be passed into anything running the vm (java, javac, javadoc, ...). +ifdef JPRT_PRODUCT_VM_ARGS + JAVA_VM_ARGS = $(JPRT_PRODUCT_VM_ARGS) +endif + +# jtreg -nativepath <dir> +# +# Local make tests will be TEST_IMAGE_DIR and JPRT with jprt.use.reg.test.bundle=true +# should be JPRT_TESTNATIVE_PATH +ifdef TEST_IMAGE_DIR + TESTNATIVE_DIR = $(TEST_IMAGE_DIR) +else ifdef JPRT_TESTNATIVE_PATH + TESTNATIVE_DIR = $(JPRT_TESTNATIVE_PATH) +endif +ifdef TESTNATIVE_DIR + JTREG_NATIVE_PATH = -nativepath:$(shell $(GETMIXEDPATH) "$(TESTNATIVE_DIR)/nashorn/jtreg/native") +endif + +# jtreg failure handler config +ifeq ($(FAILURE_HANDLER_DIR), ) + ifneq ($(TESTNATIVE_DIR), ) + FAILURE_HANDLER_DIR := $(TESTNATIVE_DIR)/failure_handler + endif +endif +ifneq ($(FAILURE_HANDLER_DIR), ) + FAILURE_HANDLER_DIR_MIXED := $(shell $(GETMIXEDPATH) "$(FAILURE_HANDLER_DIR)") + JTREG_FAILURE_HANDLER_OPTIONS := \ + -timeoutHandlerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \ + -observerDir:$(FAILURE_HANDLER_DIR_MIXED)/jtregFailureHandler.jar \ + -timeoutHandler:jdk.test.failurehandler.jtreg.GatherProcessInfoTimeoutHandler \ + -observer:jdk.test.failurehandler.jtreg.GatherDiagnosticInfoObserver + ifeq ($(UNAME_S), CYGWIN) + JTREG_FAILURE_HANDLER_OPTIONS += -J-Djava.library.path="$(FAILURE_HANDLER_DIR_MIXED)" + endif +endif + +# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results) +ifdef JPRT_ARCHIVE_BUNDLE + ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE) +else + ARCHIVE_BUNDLE = $(ABS_TEST_OUTPUT_DIR)/ARCHIVE_BUNDLE.zip +endif + +# How to create the test bundle (pass or fail, we want to create this) +# Follow command with ";$(BUNDLE_UP_AND_EXIT)", so it always gets executed. +ZIP_UP_RESULTS = ( $(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)` \ + && $(CD) $(ABS_TEST_OUTPUT_DIR) \ + && $(CHMOD) -R a+r . \ + && $(ZIP) -q -r $(ARCHIVE_BUNDLE) . ) + +# important results files +SUMMARY_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport/text/summary.txt") +STATS_TXT_NAME = Stats.txt +STATS_TXT = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/$(STATS_TXT_NAME)") +RUNLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/runlist.txt") +PASSLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/passlist.txt") +FAILLIST = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/faillist.txt") +EXITCODE = $(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/exitcode.txt") + +TESTEXIT = \ + if [ ! -s $(EXITCODE) ] ; then \ + $(ECHO) "ERROR: EXITCODE file not filled in."; \ + $(ECHO) "1" > $(EXITCODE); \ + fi ; \ + testExitCode=`$(CAT) $(EXITCODE)`; \ + $(ECHO) "EXIT CODE: $${testExitCode}"; \ + exit $${testExitCode} + +BUNDLE_UP_AND_EXIT = \ +( \ + jtregExitCode=$$? && \ + _summary="$(SUMMARY_TXT)"; \ + $(RM) -f $(STATS_TXT) $(RUNLIST) $(PASSLIST) $(FAILLIST) $(EXITCODE); \ + $(ECHO) "$${jtregExitCode}" > $(EXITCODE); \ + if [ -r "$${_summary}" ] ; then \ + $(ECHO) "Summary: $(UNIQUE_DIR)" > $(STATS_TXT); \ + $(EXPAND) $${_summary} | $(EGREP) -v ' Not run\.' > $(RUNLIST); \ + $(EGREP) ' Passed\.' $(RUNLIST) \ + | $(EGREP) -v ' Error\.' \ + | $(EGREP) -v ' Failed\.' > $(PASSLIST); \ + ( $(EGREP) ' Failed\.' $(RUNLIST); \ + $(EGREP) ' Error\.' $(RUNLIST); \ + $(EGREP) -v ' Passed\.' $(RUNLIST) ) \ + | $(SORT) | $(UNIQ) > $(FAILLIST); \ + if [ $${jtregExitCode} != 0 -o -s $(FAILLIST) ] ; then \ + $(EXPAND) $(FAILLIST) \ + | $(CUT) -d' ' -f1 \ + | $(SED) -e 's@^@FAILED: @' >> $(STATS_TXT); \ + if [ $${jtregExitCode} = 0 ] ; then \ + jtregExitCode=1; \ + fi; \ + fi; \ + runc="`$(CAT) $(RUNLIST) | $(WC) -l | $(AWK) '{print $$1;}'`"; \ + passc="`$(CAT) $(PASSLIST) | $(WC) -l | $(AWK) '{print $$1;}'`"; \ + failc="`$(CAT) $(FAILLIST) | $(WC) -l | $(AWK) '{print $$1;}'`"; \ + exclc="FIXME CODETOOLS-7900176"; \ + $(ECHO) "TEST STATS: name=$(UNIQUE_DIR) run=$${runc} pass=$${passc} fail=$${failc}" \ + >> $(STATS_TXT); \ + else \ + $(ECHO) "Missing file: $${_summary}" >> $(STATS_TXT); \ + fi; \ + if [ -f $(STATS_TXT) ] ; then \ + $(CAT) $(STATS_TXT); \ + fi; \ + $(ZIP_UP_RESULTS) ; \ + $(TESTEXIT) \ +) + +################################################################ + +# Default make rule (runs default nashorn tests) +all: nashorn_default + @$(ECHO) "Testing completed successfully" + +# Prep for output +# Change execute permissions on shared library files. +# Files in repositories should never have execute permissions, but +# there are some tests that have pre-built shared libraries, and these +# windows dll files must have execute permission. Adding execute +# permission may happen automatically on windows when using certain +# versions of mercurial but it cannot be guaranteed. And blindly +# adding execute permission might be seen as a mercurial 'change', so +# we avoid adding execute permission to repository files. But testing +# from a plain source tree needs the chmod a+rx. Applying the chmod to +# all shared libraries not just dll files. And with CYGWIN and sshd +# service, you may need CYGWIN=ntsec for this to work. +prep: + @$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR) + @$(MKDIR) -p `$(DIRNAME) $(ARCHIVE_BUNDLE)` + @if [ ! -d $(TEST_ROOT)/../.hg ] ; then \ + $(FIND) $(TEST_ROOT) \( -name \*.dll -o -name \*.DLL -o -name \*.so \) \ + -exec $(CHMOD) a+rx {} \; ; \ + fi + +# Cleanup +clean: + @$(RM) -r $(ABS_TEST_OUTPUT_DIR) + @$(RM) $(ARCHIVE_BUNDLE) + +################################################################ + +# jtreg tests + +# Expect JT_HOME to be set for jtreg tests. (home for jtreg) +ifndef JT_HOME + JT_HOME = $(SLASH_JAVA)/re/jtreg/4.2/promoted/latest/binaries/jtreg + ifdef JPRT_JTREG_HOME + JT_HOME = $(JPRT_JTREG_HOME) + endif +endif + +# Problematic tests to be excluded +PROBLEM_LISTS=$(call MixedDirs,$(wildcard ProblemList.txt closed/ProblemList.txt)) + +# Create exclude list for this platform and arch +ifdef NO_EXCLUDES + JTREG_EXCLUSIONS = +else + JTREG_EXCLUSIONS = $(PROBLEM_LISTS:%=-exclude:%) +endif + +# convert list of directories to dos paths +define MixedDirs +$(foreach i,$1,$(shell $(GETMIXEDPATH) "${i}")) +endef + +define SummaryInfo +$(ECHO) "########################################################" +$(CAT) $(?:%=$(ABS_TEST_OUTPUT_DIR)/%/$(STATS_TXT_NAME)) +$(ECHO) "########################################################" +endef + +# ------------------------------------------------------------------ + +nashorn_%: + $(ECHO) "Running tests: $@" + for each in $@; do \ + $(MAKE) -j 1 TEST_SELECTION=":$$each" UNIQUE_DIR=$$each jtreg_tests; \ + done + +# ------------------------------------------------------------------ + +# When called from JPRT the TESTDIRS variable is set to the jtreg tests to run +ifdef TESTDIRS + TEST_SELECTION = $(TESTDIRS) +endif + +ifdef CONCURRENCY + EXTRA_JTREG_OPTIONS += -concurrency:$(CONCURRENCY) +endif + +# Default JTREG to run +JTREG = $(JT_HOME)/bin/jtreg +# run in agentvm mode +JTREG_BASIC_OPTIONS += -agentvm +# Only run automatic tests +JTREG_BASIC_OPTIONS += -a +# Always turn on assertions +JTREG_ASSERT_OPTION = -ea -esa +JTREG_BASIC_OPTIONS += $(JTREG_ASSERT_OPTION) +# Report details on all failed or error tests, times too +JTREG_BASIC_OPTIONS += -v:fail,error,time +# Retain all files for failing tests +JTREG_BASIC_OPTIONS += -retain:fail,error +# Ignore tests are not run and completely silent about it +JTREG_IGNORE_OPTION = -ignore:quiet +JTREG_BASIC_OPTIONS += $(JTREG_IGNORE_OPTION) +# Multiple by 4 the timeout numbers +JTREG_TIMEOUT_OPTION = -timeoutFactor:4 +JTREG_BASIC_OPTIONS += $(JTREG_TIMEOUT_OPTION) +# Set the max memory for jtreg control vm +JTREG_MEMORY_OPTION = -J-Xmx512m +JTREG_BASIC_OPTIONS += $(JTREG_MEMORY_OPTION) +# Give tests access to JT_JAVA, see JDK-8141609 +JTREG_BASIC_OPTIONS += -e:JDK8_HOME=${JT_JAVA} +# Add any extra options +JTREG_BASIC_OPTIONS += $(EXTRA_JTREG_OPTIONS) +# Set other vm and test options +JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_VM_ARGS:%=-vmoption:%) +# Set the GC options for test vms +#JTREG_GC_OPTION = -vmoption:-XX:+UseSerialGC +#JTREG_TEST_OPTIONS += $(JTREG_GC_OPTION) +# Set the max memory for jtreg target test vms +JTREG_TESTVM_MEMORY_OPTION = -vmoption:-Xmx512m +JTREG_TEST_OPTIONS += $(JTREG_TESTVM_MEMORY_OPTION) + +# Make sure jtreg exists +$(JTREG): $(JT_HOME) + +# Run jtreg +jtreg_tests: prep $(PRODUCT_HOME) $(JTREG) + ( \ + ( JT_HOME=$(shell $(GETMIXEDPATH) "$(JT_HOME)"); \ + export JT_HOME; \ + $(shell $(GETMIXEDPATH) "$(JTREG)") \ + $(JTREG_BASIC_OPTIONS) \ + -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTreport") \ + -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)/JTwork") \ + -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)") \ + $(JTREG_NATIVE_PATH) \ + $(JTREG_FAILURE_HANDLER_OPTIONS) \ + $(JTREG_EXCLUSIONS) \ + $(JTREG_TEST_OPTIONS) \ + $(TEST_SELECTION) \ + ) ; \ + $(BUNDLE_UP_AND_EXIT) \ + ) 2>&1 | $(TEE) $(ABS_TEST_OUTPUT_DIR)/output.txt ; $(TESTEXIT) + +PHONY_LIST += jtreg_tests + +################################################################ + +# Phony targets (e.g. these are not filenames) +.PHONY: all clean prep $(PHONY_LIST) + +################################################################ diff --git a/nashorn/test/script/basic/JDK-8025515.js b/nashorn/test/script/basic/JDK-8025515.js index b88897b654b..6538f54f247 100644 --- a/nashorn/test/script/basic/JDK-8025515.js +++ b/nashorn/test/script/basic/JDK-8025515.js @@ -61,8 +61,8 @@ testMethodName(function() { throw new Error() }, "L:59"); var f = (function() { return function() { a.b.c; }; })(); -testMethodName(f, "f$L:62"); +testMethodName(f, "f#L:62"); testMethodName((function() { return function() { return a.b.c; }; -})(), "L:66$L:67"); +})(), "L:66#L:67"); diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PluginContext.java b/nashorn/test/script/basic/JDK-8156714.js similarity index 69% rename from jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PluginContext.java rename to nashorn/test/script/basic/JDK-8156714.js index 9e5a4a7df61..93a4e906f5f 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/PluginContext.java +++ b/nashorn/test/script/basic/JDK-8156714.js @@ -1,37 +1,50 @@ /* * Copyright (c) 2016, 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. - * + * published by the Free Software Foundation. + * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). - * + * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * + * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.tools.jlink.plugin; - -import java.util.Properties; /** - * Interface to plugin (container) context. + * JDK-8156714: Parsing issue with automatic semicolon insertion + * + * @test + * @run */ -public interface PluginContext { - /** - * Returns 'release' properties - */ - public Properties getReleaseProperties(); + +a = function() { +} + +/* */ function b() { +} + +c = function() { +} /* + +*/ function d() { +} + +try { + eval("x = function() {} /* */ function y() {}"); + throw new Error("Error expected"); +} catch (e) { + if (!(e instanceof SyntaxError)) { + throw new Error("Unexpected error: " + e); + } } diff --git a/nashorn/test/script/basic/JDK-8156896.js b/nashorn/test/script/basic/JDK-8156896.js new file mode 100644 index 00000000000..fc71f07c941 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8156896.js @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016, 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. + */ + +/** + * JDK-8156896: Script stack trace should display function names + * + * @test + * @run + */ + +function checkNamedFunction(stack) { + Assert.assertTrue(stack.indexOf("Error\n\tat bar (") === 0); +} + +function checkAnonymousFunction(stack) { + Assert.assertTrue(stack.indexOf("Error\n\tat <anonymous> (") === 0); +} + +// Named functions +function bar() { try { throw new Error(); } catch(e) { return e.stack; } } +checkNamedFunction(bar()); + +bar = function() { try { throw new Error(); } catch(e) { return e.stack; } }; +checkNamedFunction(bar()); + +f = (function() {return function bar() { try { throw new Error(); } catch(e) { return e.stack; } } })(); +checkNamedFunction(f()); + +f = new Function("return function bar() { try { throw new Error(); } catch(e) { return e.stack; } }")(); +checkNamedFunction(f()); + +// Anonymous functions +checkAnonymousFunction((function() { try { throw new Error(); } catch(e) { return e.stack; } })()); + +f = (function() {return function() { try { throw new Error(); } catch(e) { return e.stack; } } })(); +checkAnonymousFunction(f()); + +f = new Function("return function() { try { throw new Error(); } catch(e) { return e.stack; } }")(); +checkAnonymousFunction(f()); diff --git a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PluginContextImpl.java b/nashorn/test/script/basic/es6/JDK-8156665.js similarity index 65% rename from jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PluginContextImpl.java rename to nashorn/test/script/basic/es6/JDK-8156665.js index 7fe7dcea36e..d405b188be5 100644 --- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/PluginContextImpl.java +++ b/nashorn/test/script/basic/es6/JDK-8156665.js @@ -1,37 +1,40 @@ /* * Copyright (c) 2016, 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. - * + * published by the Free Software Foundation. + * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). - * + * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * + * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ -package jdk.tools.jlink.internal; -import java.util.Properties; +/** + * JDK-8156665: ES6 for..of should work on Java Iterables and Java arrays + * + * @test + * @run + * @option --language=es6 + */ -import jdk.tools.jlink.plugin.PluginContext; +var ca = new (Java.type("char[]"))(3); +ca[0] = 'a', ca[1] = 'b', ca[2] = 'c'; +for (i of ca) print(i); -public final class PluginContextImpl implements PluginContext { - private final Properties releaseProps = new Properties(); +var al = new java.util.ArrayList(); +al.add("hello"); +al.add("world"); - public Properties getReleaseProperties() { - return releaseProps; - } -} +for (i of al) print(i); diff --git a/nashorn/test/script/basic/es6/JDK-8156665.js.EXPECTED b/nashorn/test/script/basic/es6/JDK-8156665.js.EXPECTED new file mode 100644 index 00000000000..ddf6f6d20ba --- /dev/null +++ b/nashorn/test/script/basic/es6/JDK-8156665.js.EXPECTED @@ -0,0 +1,5 @@ +a +b +c +hello +world diff --git a/nashorn/test/script/nosecurity/parserapi.js.EXPECTED b/nashorn/test/script/nosecurity/parserapi.js.EXPECTED index 8fbd95117da..82f4506ed69 100644 --- a/nashorn/test/script/nosecurity/parserapi.js.EXPECTED +++ b/nashorn/test/script/nosecurity/parserapi.js.EXPECTED @@ -4864,7 +4864,7 @@ "kind": "COMPILATION_UNIT", "sourceElements": [ { - "endPosition": "1242", + "endPosition": "1222", "kind": "FUNCTION", "name": "Parser", "body": { @@ -5419,7 +5419,7 @@ }, "startPosition": "1809" }, - "endPosition": "1973", + "endPosition": "1901", "kind": "EXPRESSION_STATEMENT", "startPosition": "1809" }, @@ -6310,7 +6310,7 @@ "startPosition": "1974" }, { - "endPosition": "3767", + "endPosition": "3726", "kind": "FUNCTION", "name": "processFiles", "body": { diff --git a/nashorn/test/src/jdk/dynalink/test/LinkedCallSiteLocationTest.java b/nashorn/test/src/jdk/dynalink/test/LinkedCallSiteLocationTest.java new file mode 100644 index 00000000000..8e2b03b6a67 --- /dev/null +++ b/nashorn/test/src/jdk/dynalink/test/LinkedCallSiteLocationTest.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2016, 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.dynalink.test; + +import static jdk.dynalink.StandardOperation.CALL_METHOD; + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import jdk.dynalink.CallSiteDescriptor; +import jdk.dynalink.DynamicLinker; +import jdk.dynalink.DynamicLinkerFactory; +import jdk.dynalink.NamedOperation; +import jdk.dynalink.linker.GuardingDynamicLinker; +import jdk.dynalink.support.SimpleRelinkableCallSite; +import org.testng.Assert; +import org.testng.annotations.Test; + +public class LinkedCallSiteLocationTest { + @Test + public void testLinkedCallSiteLocation() throws Throwable { + final StackTraceElement[] lastLinked = new StackTraceElement[1]; + + final GuardingDynamicLinker testLinker = + (r, s) -> { lastLinked[0] = DynamicLinker.getLinkedCallSiteLocation(); return null; }; + + final DynamicLinkerFactory factory = new DynamicLinkerFactory(); + factory.setPrioritizedLinker(testLinker); + final DynamicLinker linker = factory.createLinker(); + final SimpleRelinkableCallSite callSite = new SimpleRelinkableCallSite( + new CallSiteDescriptor( + MethodHandles.lookup(), + new NamedOperation(CALL_METHOD, "foo"), + MethodType.methodType(void.class, Object.class))); + linker.link(callSite); + + // Test initial linking + callSite.dynamicInvoker().invoke(new TestClass1()); final int l1 = getLineNumber(); + assertLocation(lastLinked[0], l1); + + // Test relinking + callSite.dynamicInvoker().invoke(new TestClass2()); final int l2 = getLineNumber(); + assertLocation(lastLinked[0], l2); + } + + private void assertLocation(final StackTraceElement frame, final int lineNumber) { + Assert.assertNotNull(frame); + Assert.assertEquals(frame.getLineNumber(), lineNumber); + Assert.assertEquals(frame.getClassName(), this.getClass().getName()); + } + + private static int getLineNumber() { + return StackWalker.getInstance().walk(s -> s.skip(1).findFirst().get().getLineNumber()); + } + + public static class TestClass1 { + public void foo() { + } + } + + public static class TestClass2 { + public void foo() { + } + } +} diff --git a/test/Makefile b/test/Makefile index e31dbedea87..41a20170e0e 100644 --- a/test/Makefile +++ b/test/Makefile @@ -87,7 +87,7 @@ hotspot_%: # # Invocation: # -# make jtreg_tests TESTDIRS=<test-dirs> +# make jtreg_tests TESTDIRS=<test-dirs> TEST_SELECTION=<path to test or jtreg group> TEST_OUTPUT_DIR=<path> # # where <test-dirs> is something like '../<component>/test/runtime', # <component> in turn being one of the top level directories (for diff --git a/test/make/TestIdea.gmk b/test/make/TestIdea.gmk new file mode 100644 index 00000000000..39d93c5cdaf --- /dev/null +++ b/test/make/TestIdea.gmk @@ -0,0 +1,46 @@ + +# Copyright (c) 2014, 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. +# + +include $(SPEC) +include MakeBase.gmk + +default: all + +IDEA_OUTPUT_DIR := $(TESTMAKE_OUTPUTDIR)/verify-idea + +clean-idea: + $(RM) -r $(IDEA_OUTPUT_DIR) + +verify-idea: + $(MKDIR) -p $(IDEA_OUTPUT_DIR) + $(BASH) $(TOPDIR)/common/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea1 + $(BASH) $(TOPDIR)/common/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea2 java.base + $(BASH) $(TOPDIR)/common/bin/idea.sh -o $(IDEA_OUTPUT_DIR)/idea3 java.base jdk.compiler + +TEST_TARGETS += verify-idea + +all: $(TEST_TARGETS) + +.PHONY: default all verify-idea diff --git a/test/make/TestMake.gmk b/test/make/TestMake.gmk index 1f33e1786a7..f3676a00153 100644 --- a/test/make/TestMake.gmk +++ b/test/make/TestMake.gmk @@ -33,7 +33,10 @@ make-base: java-compilation: +$(MAKE) -f TestJavaCompilation.gmk $(TEST_SUBTARGET) +test-idea: + +$(MAKE) -f TestIdea.gmk $(TEST_SUBTARGET) -all: make-base java-compilation -.PHONY: default all make-base java-compilation +all: make-base java-compilation test-idea + +.PHONY: default all make-base java-compilation test-idea