--- a/.hgtags Thu Feb 16 17:12:58 2017 +0000
+++ b/.hgtags Wed Jul 05 22:52:22 2017 +0200
@@ -399,3 +399,5 @@
8c70d170e62c0c58b5bc3ba666bd140399b98c9c jdk-10+0
45b751afd11e6c05991cf4913c5a0ac3304fcc4e jdk-9+154
f4aff695ffe05cfdb69d8af25a4ddc6a029754ea jdk-9+155
+06bce0388880b5ff8e040e4a9d72a3ea11dac321 jdk-9+156
+fa3e76b477829afc4476f0b725cfaa440a6fd917 jdk-9+157
--- a/.hgtags-top-repo Thu Feb 16 17:12:58 2017 +0000
+++ b/.hgtags-top-repo Wed Jul 05 22:52:22 2017 +0200
@@ -398,3 +398,5 @@
816a6d03a7c44edfbd8780110529f1bdc3964fb9 jdk-9+153
8d26916eaa21b689835ffc1c0dbf12470aa9be61 jdk-9+154
688a3863c00ebc089ab17ee1fc46272cbbd96815 jdk-9+155
+783ec7542cf7154e5d2b87f55bb97d28f81e9ada jdk-9+156
+4eb77fb98952dc477a4229575c81d2263a9ce711 jdk-9+157
--- a/common/autoconf/basics.m4 Thu Feb 16 17:12:58 2017 +0000
+++ b/common/autoconf/basics.m4 Wed Jul 05 22:52:22 2017 +0200
@@ -1202,6 +1202,18 @@
# Check for support for specific options in bash
AC_DEFUN_ONCE([BASIC_CHECK_BASH_OPTIONS],
[
+ # Check bash version
+ # Extra [ ] to stop m4 mangling
+ [ BASH_VER=`$BASH --version | $SED -n -e 's/^.*bash.*ersion *\([0-9.]*\).*$/\1/ p'` ]
+ AC_MSG_CHECKING([bash version])
+ AC_MSG_RESULT([$BASH_VER])
+
+ BASH_MAJOR=`$ECHO $BASH_VER | $CUT -d . -f 1`
+ BASH_MINOR=`$ECHO $BASH_VER | $CUT -d . -f 2`
+ if test $BASH_MAJOR -lt 3 || (test $BASH_MAJOR -eq 3 && test $BASH_MINOR -lt 2); then
+ AC_MSG_ERROR([bash version 3.2 or better is required])
+ fi
+
# Test if bash supports pipefail.
AC_MSG_CHECKING([if bash supports pipefail])
if ${BASH} -c 'set -o pipefail'; then
--- a/common/autoconf/generated-configure.sh Thu Feb 16 17:12:58 2017 +0000
+++ b/common/autoconf/generated-configure.sh Wed Jul 05 22:52:22 2017 +0200
@@ -5170,7 +5170,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1486175373
+DATE_WHEN_GENERATED=1486679715
###############################################################################
#
@@ -24092,6 +24092,20 @@
fi
+ # Check bash version
+ # Extra [ ] to stop m4 mangling
+ BASH_VER=`$BASH --version | $SED -n -e 's/^.*bash.*ersion *\([0-9.]*\).*$/\1/ p'`
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking bash version" >&5
+$as_echo_n "checking bash version... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BASH_VER" >&5
+$as_echo "$BASH_VER" >&6; }
+
+ BASH_MAJOR=`$ECHO $BASH_VER | $CUT -d . -f 1`
+ BASH_MINOR=`$ECHO $BASH_VER | $CUT -d . -f 2`
+ if test $BASH_MAJOR -lt 3 || (test $BASH_MAJOR -eq 3 && test $BASH_MINOR -lt 2); then
+ as_fn_error $? "bash version 3.2 or better is required" "$LINENO" 5
+ fi
+
# Test if bash supports pipefail.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if bash supports pipefail" >&5
$as_echo_n "checking if bash supports pipefail... " >&6; }
--- a/common/bin/unshuffle_list.txt Thu Feb 16 17:12:58 2017 +0000
+++ b/common/bin/unshuffle_list.txt Wed Jul 05 22:52:22 2017 +0200
@@ -361,8 +361,8 @@
jdk/src/java.base/share/native/libverify/check_format.c : jdk/src/share/native/common/check_format.c
jdk/src/java.base/share/native/libverify/opcodes.in_out : jdk/src/share/native/common/opcodes.in_out
jdk/src/java.base/share/native/libzip : jdk/src/share/native/java/util/zip
-jdk/src/java.base/share/native/libzip/zlib-1.2.8 : jdk/src/share/native/java/util/zip/zlib-1.2.8
-jdk/src/java.base/share/native/libzip/zlib-1.2.8/patches/ChangeLog_java : jdk/src/share/native/java/util/zip/zlib-1.2.8/patches/ChangeLog_java
+jdk/src/java.base/share/native/libzip/zlib : jdk/src/share/native/java/util/zip/zlib
+jdk/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java : jdk/src/share/native/java/util/zip/zlib/patches/ChangeLog_java
jdk/src/java.base/unix/classes/java/io : jdk/src/solaris/classes/java/io
jdk/src/java.base/unix/classes/java/lang : jdk/src/solaris/classes/java/lang
jdk/src/java.base/unix/classes/java/net : jdk/src/solaris/classes/java/net
--- a/common/nb_native/nbproject/configurations.xml Thu Feb 16 17:12:58 2017 +0000
+++ b/common/nb_native/nbproject/configurations.xml Wed Jul 05 22:52:22 2017 +0200
@@ -1223,7 +1223,7 @@
<in>check_format.c</in>
</df>
<df name="libzip">
- <df name="zlib-1.2.8">
+ <df name="zlib">
<in>compress.c</in>
<in>deflate.c</in>
<in>gzclose.c</in>
@@ -38283,7 +38283,7 @@
<pElem>../../jdk/src/java.base/unix/native/include</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../build/support/headers/java.base</pElem>
<pElem>../../make</pElem>
</incDir>
@@ -38304,7 +38304,7 @@
<pElem>../../jdk/src/java.base/unix/native/include</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../build/support/headers/java.base</pElem>
<pElem>../../make</pElem>
</incDir>
@@ -38325,7 +38325,7 @@
<pElem>../../jdk/src/java.base/unix/native/include</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../build/support/headers/java.base</pElem>
<pElem>../../make</pElem>
</incDir>
@@ -38346,7 +38346,7 @@
<pElem>../../jdk/src/java.base/unix/native/include</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../build/support/headers/java.base</pElem>
<pElem>../../make</pElem>
</incDir>
@@ -38367,7 +38367,7 @@
<pElem>../../jdk/src/java.base/unix/native/include</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../build/support/headers/java.base</pElem>
<pElem>../../make</pElem>
</incDir>
@@ -38377,14 +38377,14 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/compress.c"
- ex="false"
- tool="0"
- flavor2="0">
- <cTool flags="4">
- </cTool>
- </item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/deflate.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/compress.c"
+ ex="false"
+ tool="0"
+ flavor2="0">
+ <cTool flags="4">
+ </cTool>
+ </item>
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/deflate.c"
ex="false"
tool="0"
flavor2="0">
@@ -38394,7 +38394,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/gzclose.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/gzclose.c"
ex="false"
tool="0"
flavor2="0">
@@ -38404,7 +38404,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/gzlib.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/gzlib.c"
ex="false"
tool="0"
flavor2="0">
@@ -38414,7 +38414,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/gzread.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/gzread.c"
ex="false"
tool="0"
flavor2="0">
@@ -38424,7 +38424,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/gzwrite.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/gzwrite.c"
ex="false"
tool="0"
flavor2="0">
@@ -38434,7 +38434,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/infback.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/infback.c"
ex="false"
tool="0"
flavor2="0">
@@ -38444,7 +38444,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/inffast.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/inffast.c"
ex="false"
tool="0"
flavor2="0">
@@ -38454,7 +38454,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/inflate.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/inflate.c"
ex="false"
tool="0"
flavor2="0">
@@ -38464,7 +38464,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/inftrees.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/inftrees.c"
ex="false"
tool="0"
flavor2="0">
@@ -38474,7 +38474,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/trees.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/trees.c"
ex="false"
tool="0"
flavor2="0">
@@ -38484,7 +38484,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/uncompr.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/uncompr.c"
ex="false"
tool="0"
flavor2="0">
@@ -38494,7 +38494,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/zadler32.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/zadler32.c"
ex="false"
tool="0"
flavor2="0">
@@ -38504,7 +38504,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/zcrc32.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/zcrc32.c"
ex="false"
tool="0"
flavor2="0">
@@ -38514,7 +38514,7 @@
</preprocessorList>
</cTool>
</item>
- <item path="../../jdk/src/java.base/share/native/libzip/zlib-1.2.8/zutil.c"
+ <item path="../../jdk/src/java.base/share/native/libzip/zlib/zutil.c"
ex="false"
tool="0"
flavor2="0">
@@ -41203,7 +41203,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41232,7 +41232,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41261,7 +41261,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41290,7 +41290,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41319,7 +41319,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41348,7 +41348,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41377,7 +41377,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41406,7 +41406,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41435,7 +41435,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41464,7 +41464,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41493,7 +41493,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41522,7 +41522,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41551,7 +41551,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41580,7 +41580,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41609,7 +41609,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41638,7 +41638,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41667,7 +41667,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41696,7 +41696,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41725,7 +41725,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41754,7 +41754,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41783,7 +41783,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41812,7 +41812,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41841,7 +41841,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41870,7 +41870,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41899,7 +41899,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41928,7 +41928,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41957,7 +41957,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -41986,7 +41986,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42015,7 +42015,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42044,7 +42044,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42073,7 +42073,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42102,7 +42102,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42131,7 +42131,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42160,7 +42160,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42189,7 +42189,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42218,7 +42218,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42247,7 +42247,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42276,7 +42276,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42305,7 +42305,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42334,7 +42334,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42363,7 +42363,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42413,7 +42413,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42442,7 +42442,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -42471,7 +42471,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -46557,7 +46557,7 @@
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjli</pElem>
<pElem>../../jdk/src/java.base/share/native/libjli</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../make</pElem>
</incDir>
<preprocessorList>
@@ -46639,15 +46639,15 @@
</preprocessorList>
</cTool>
</folder>
- <folder path="0/jdk/src/java.base/share/native/libzip/zlib-1.2.8">
- <cTool>
- <incDir>
- <pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/giflib</pElem>
- <pElem>../../jdk/src/java.desktop/share/native/libjavajpeg</pElem>
- <pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
- <pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <folder path="0/jdk/src/java.base/share/native/libzip/zlib">
+ <cTool>
+ <incDir>
+ <pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/giflib</pElem>
+ <pElem>../../jdk/src/java.desktop/share/native/libjavajpeg</pElem>
+ <pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
+ <pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
+ <pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -46712,7 +46712,7 @@
<incDir>
<pElem>../../jdk/src/java.base/unix/native/libjli</pElem>
<pElem>../../jdk/src/java.base/share/native/libjli</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../make</pElem>
</incDir>
<preprocessorList>
@@ -47250,7 +47250,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -47598,7 +47598,7 @@
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen</pElem>
<pElem>../../jdk/src/java.desktop/share/native/libsplashscreen/libpng</pElem>
<pElem>../../jdk/src/java.desktop/unix/native/libsplashscreen</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/linux/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
@@ -47996,7 +47996,7 @@
<pElem>../../jdk/src/jdk.pack/share/native/common-unpack</pElem>
<pElem>../../jdk/src/java.base/share/native/libjava</pElem>
<pElem>../../jdk/src/java.base/unix/native/libjava</pElem>
- <pElem>../../jdk/src/java.base/share/native/libzip/zlib-1.2.8</pElem>
+ <pElem>../../jdk/src/java.base/share/native/libzip/zlib</pElem>
<pElem>../../jdk/src/java.base/share/native/include</pElem>
<pElem>../../jdk/src/java.base/linux/native/include</pElem>
<pElem>../../jdk/src/java.base/unix/native/include</pElem>
--- a/corba/.hgtags Thu Feb 16 17:12:58 2017 +0000
+++ b/corba/.hgtags Wed Jul 05 22:52:22 2017 +0200
@@ -398,3 +398,4 @@
68a8e8658511093b322a46ed04b2a321e1da2a43 jdk-9+153
078ebe23b584466dc8346e620d7821d91751e5a9 jdk-9+154
a545f54babfa31aa7eb611f36031609acd617cbc jdk-9+155
+907c26240cd481579e919bfd23740797ff8ce1c8 jdk-9+156
--- a/corba/src/java.corba/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/corba/src/java.corba/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the Java binding of the OMG CORBA APIs, and the RMI-IIOP API.
+ *
+ * @since 9
*/
@Deprecated(since="9", forRemoval=true)
module java.corba {
--- a/corba/src/java.corba/share/classes/org/omg/CORBA/ORB.java Thu Feb 16 17:12:58 2017 +0000
+++ b/corba/src/java.corba/share/classes/org/omg/CORBA/ORB.java Wed Jul 05 22:52:22 2017 +0200
@@ -106,13 +106,13 @@
*
* <LI>check in properties parameter, if any
*
- * <LI>check in the System properties
+ * <LI>check in the System properties, if any
*
* <LI>check in the orb.properties file located in the user.home
- * directory (if any)
+ * directory, if any
*
- * <LI>check in the orb.properties file located in the java.home/lib
- * directory (if any)
+ * <LI>check in the orb.properties file located in the run-time image,
+ * if any
*
* <LI>fall back on a hardcoded default behavior (use the Java IDL
* implementation)
@@ -170,9 +170,15 @@
* Thus, where appropriate, it is necessary that
* the classes for this alternative ORBSingleton are available on the application's class path.
* It should be noted that the singleton ORB is system wide.
- *
+ * <P>
* When a per-application ORB is created via the 2-arg init methods,
* then it will be located using the thread context class loader.
+ * <P>
+ * The IDL to Java Language OMG specification documents the ${java.home}/lib directory as the location,
+ * in the Java run-time image, to search for orb.properties.
+ * This location is not intended for user editable configuration files.
+ * Therefore, the implementation first checks the ${java.home}/conf directory for orb.properties,
+ * and thereafter the ${java.home}/lib directory.
*
* @since JDK1.2
*/
@@ -271,14 +277,25 @@
}
String javaHome = System.getProperty("java.home");
- fileName = javaHome + File.separator
- + "lib" + File.separator + "orb.properties";
- props = getFileProperties( fileName ) ;
+
+ fileName = javaHome + File.separator + "conf"
+ + File.separator + "orb.properties";
+ props = getFileProperties(fileName);
+
+ if (props != null) {
+ String value = props.getProperty(name);
+ if (value != null)
+ return value;
+ }
+
+ fileName = javaHome + File.separator + "lib"
+ + File.separator + "orb.properties";
+ props = getFileProperties(fileName);
if (props == null)
- return null ;
+ return null;
else
- return props.getProperty( name ) ;
+ return props.getProperty(name);
}
}
);
--- a/jaxp/.hgtags Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxp/.hgtags Wed Jul 05 22:52:22 2017 +0200
@@ -398,3 +398,4 @@
1384504d2cd0e55c5e0becaeaf40ab05cae959d6 jdk-9+153
7fa738305436d14c0926df0f04892890cacc766b jdk-9+154
48fa77af153288b08ba794e1616a7b0685f3b67e jdk-9+155
+e930c373aaa4e0e712c9a25ba4b03d473b48c294 jdk-9+156
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java Wed Jul 05 22:52:22 2017 +0200
@@ -438,7 +438,7 @@
Layer bootLayer = Layer.boot();
Configuration cf = bootLayer.configuration()
- .resolveRequires(finder, ModuleFinder.of(), Set.of(mn));
+ .resolve(finder, ModuleFinder.of(), Set.of(mn));
PrivilegedAction<Layer> pa = () -> bootLayer.defineModules(cf, name -> loader);
Layer layer = AccessController.doPrivileged(pa);
@@ -483,10 +483,11 @@
String pn = _tfactory.getPackageName();
assert pn != null && pn.length() > 0;
- ModuleDescriptor descriptor = ModuleDescriptor.module(mn)
- .requires("java.xml")
- .exports(pn)
- .build();
+ ModuleDescriptor descriptor =
+ ModuleDescriptor.newModule(mn, Set.of(ModuleDescriptor.Modifier.SYNTHETIC))
+ .requires("java.xml")
+ .exports(pn)
+ .build();
Module m = createModule(descriptor, loader);
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToHTMLStream.java Wed Jul 05 22:52:22 2017 +0200
@@ -717,7 +717,9 @@
*/
public final void endDocument() throws org.xml.sax.SAXException
{
- flushCharactersBuffer();
+ if (m_doIndent) {
+ flushCharactersBuffer();
+ }
flushPending();
if (m_doIndent && !m_isprevtext)
{
@@ -776,9 +778,11 @@
Attributes atts)
throws SAXException
{
- // will add extra one if having namespace but no matter
- m_childNodeNum++;
- flushCharactersBuffer();
+ if (m_doIndent) {
+ // will add extra one if having namespace but no matter
+ m_childNodeNum++;
+ flushCharactersBuffer();
+ }
ElemContext elemContext = m_elemContext;
// clean up any pending things first
@@ -839,8 +843,10 @@
writer.write('<');
writer.write(name);
- m_childNodeNumStack.push(m_childNodeNum);
- m_childNodeNum = 0;
+ if (m_doIndent) {
+ m_childNodeNumStack.add(m_childNodeNum);
+ m_childNodeNum = 0;
+ }
if (m_tracer != null)
firePseudoAttributes();
@@ -915,7 +921,9 @@
final String name)
throws org.xml.sax.SAXException
{
- flushCharactersBuffer();
+ if (m_doIndent) {
+ flushCharactersBuffer();
+ }
// deal with any pending issues
if (m_cdataTagOpen)
closeCDATA();
@@ -997,12 +1005,11 @@
}
}
- m_childNodeNum = m_childNodeNumStack.pop();
- // clean up because the element has ended
- if ((elemFlags & ElemDesc.WHITESPACESENSITIVE) != 0)
- m_ispreserve = true;
- m_isprevtext = false;
-
+ if (m_doIndent) {
+ m_childNodeNum = m_childNodeNumStack.remove(m_childNodeNumStack.size() - 1);
+ // clean up because the element has ended
+ m_isprevtext = false;
+ }
// fire off the end element event
if (m_tracer != null)
super.fireEndElem(name);
@@ -1018,11 +1025,6 @@
}
// some more clean because the element has ended.
- if (!elemContext.m_startTagOpen)
- {
- if (m_doIndent && !m_preserves.isEmpty())
- m_preserves.pop();
- }
m_elemContext = elemContext.m_prev;
// m_isRawStack.pop();
}
@@ -1525,7 +1527,6 @@
closeStartTag();
m_elemContext.m_startTagOpen = false;
}
- m_ispreserve = true;
// With m_ispreserve just set true it looks like shouldIndent()
// will always return false, so drop any possible indentation.
@@ -1602,8 +1603,6 @@
m_elemContext.m_startTagOpen = false;
}
- m_ispreserve = true;
-
if (shouldIndent())
indent();
@@ -1640,8 +1639,10 @@
public void processingInstruction(String target, String data)
throws org.xml.sax.SAXException
{
- m_childNodeNum++;
- flushCharactersBuffer();
+ if (m_doIndent) {
+ m_childNodeNum++;
+ flushCharactersBuffer();
+ }
// Process any pending starDocument and startElement first.
flushPending();
@@ -1790,11 +1791,6 @@
*/
if (m_StringOfCDATASections != null)
m_elemContext.m_isCdataSection = isCdataSection();
- if (m_doIndent)
- {
- m_isprevtext = false;
- m_preserves.push(m_ispreserve);
- }
}
catch(IOException e)
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToStream.java Wed Jul 05 22:52:22 2017 +0200
@@ -20,34 +20,36 @@
package com.sun.org.apache.xml.internal.serializer;
-import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
-import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
-import com.sun.org.apache.xml.internal.serializer.utils.Utils;
-import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
-import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.Deque;
import java.util.EmptyStackException;
import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.List;
import java.util.Properties;
-import java.util.Queue;
import java.util.Set;
import java.util.StringTokenizer;
+
import javax.xml.transform.ErrorListener;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
+
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
+import com.sun.org.apache.xalan.internal.utils.SecuritySupport;
+import com.sun.org.apache.xml.internal.serializer.utils.MsgKey;
+import com.sun.org.apache.xml.internal.serializer.utils.Utils;
+import com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException;
+
/**
* This abstract class is a base class for other stream
* serializers (xml, html, text ...) that write output to a stream.
@@ -103,7 +105,7 @@
* If m_childNodeNum > 1, the text node will be indented.
*
*/
- protected Deque<Integer> m_childNodeNumStack = new ArrayDeque<>();
+ protected List<Integer> m_childNodeNumStack = new ArrayList<>();
protected int m_childNodeNum = 0;
@@ -115,26 +117,6 @@
protected boolean m_ispreserveSpace = false;
- /**
- * Stack to keep track of whether or not we need to
- * preserve whitespace.
- *
- * Used to push/pop values used for the field m_ispreserve, but
- * m_ispreserve is only relevant if m_doIndent is true.
- * If m_doIndent is false this field has no impact.
- *
- */
- protected BoolStack m_preserves = new BoolStack();
-
- /**
- * State flag to tell if preservation of whitespace
- * is important.
- *
- * Used only in shouldIndent() but only if m_doIndent is true.
- * If m_doIndent is false this flag has no impact.
- *
- */
- protected boolean m_ispreserve = false;
/**
* State flag that tells if the previous node processed
@@ -1267,7 +1249,6 @@
closeStartTag();
m_elemContext.m_startTagOpen = false;
}
- m_ispreserve = true;
if (shouldIndent())
indent();
@@ -1357,8 +1338,6 @@
m_elemContext.m_startTagOpen = false;
}
- m_ispreserve = true;
-
m_writer.write(ch, start, length);
}
catch (IOException e)
@@ -1405,8 +1384,8 @@
if (length == 0 || (isInEntityRef()))
return;
- final boolean shouldFormat = shouldFormatOutput();
- if (m_elemContext.m_startTagOpen && !shouldFormat)
+ final boolean shouldNotFormat = !shouldFormatOutput();
+ if (m_elemContext.m_startTagOpen && shouldNotFormat)
{
closeStartTag();
m_elemContext.m_startTagOpen = false;
@@ -1441,16 +1420,16 @@
return;
}
- if (m_elemContext.m_startTagOpen && !shouldFormat)
+ if (m_elemContext.m_startTagOpen && shouldNotFormat)
{
closeStartTag();
m_elemContext.m_startTagOpen = false;
}
- if (shouldFormat) {
+ if (shouldNotFormat) {
+ outputCharacters(chars, start, length);
+ } else {
m_charactersBuffer.addText(chars, start, length);
- } else {
- outputCharacters(chars, start, length);
}
// time to fire off characters generation event
@@ -1465,7 +1444,7 @@
* @return True if the content should be formatted.
*/
protected boolean shouldFormatOutput() {
- return !m_ispreserveSpace && m_doIndent;
+ return m_doIndent && !m_ispreserveSpace;
}
/**
@@ -1506,12 +1485,6 @@
i = lastDirty;
}
}
- /* If there is some non-whitespace, mark that we may need
- * to preserve this. This is only important if we have indentation on.
- */
- if (i < end)
- m_ispreserve = true;
-
// int lengthClean; // number of clean characters in a row
// final boolean[] isAsciiClean = m_charInfo.getASCIIClean();
@@ -1858,8 +1831,10 @@
if (isInEntityRef())
return;
- m_childNodeNum++;
- flushCharactersBuffer();
+ if (m_doIndent) {
+ m_childNodeNum++;
+ flushCharactersBuffer();
+ }
if (m_needToCallStartDocument)
{
@@ -1890,8 +1865,6 @@
if (namespaceURI != null)
ensurePrefixIsDeclared(namespaceURI, name);
- m_ispreserve = false;
-
if (shouldIndent() && m_startNewLine)
{
indent();
@@ -1912,11 +1885,13 @@
if (atts != null)
addAttributes(atts);
- m_ispreserveSpace = m_preserveSpaces.peekOrFalse();
- m_preserveSpaces.push(m_ispreserveSpace);
-
- m_childNodeNumStack.push(m_childNodeNum);
- m_childNodeNum = 0;
+ if (m_doIndent) {
+ m_ispreserveSpace = m_preserveSpaces.peekOrFalse();
+ m_preserveSpaces.push(m_ispreserveSpace);
+
+ m_childNodeNumStack.add(m_childNodeNum);
+ m_childNodeNum = 0;
+ }
m_elemContext = m_elemContext.push(namespaceURI,localName,name);
m_isprevtext = false;
@@ -2128,7 +2103,9 @@
if (isInEntityRef())
return;
- flushCharactersBuffer();
+ if (m_doIndent) {
+ flushCharactersBuffer();
+ }
// namespaces declared at the current depth are no longer valid
// so get rid of them
m_prefixMap.popNamespaces(m_elemContext.m_currentElemDepth, null);
@@ -2175,16 +2152,13 @@
throw new SAXException(e);
}
- if (!m_elemContext.m_startTagOpen && m_doIndent)
- {
- m_ispreserve = m_preserves.isEmpty() ? false : m_preserves.pop();
+ if (m_doIndent) {
+ m_ispreserveSpace = m_preserveSpaces.popAndTop();
+ m_childNodeNum = m_childNodeNumStack.remove(m_childNodeNumStack.size() - 1);
+
+ m_isprevtext = false;
}
- m_ispreserveSpace = m_preserveSpaces.popAndTop();
- m_childNodeNum = m_childNodeNumStack.pop();
-
- m_isprevtext = false;
-
// fire off the end element event
if (m_tracer != null)
super.fireEndElem(name);
@@ -2320,8 +2294,10 @@
int start_old = start;
if (isInEntityRef())
return;
- m_childNodeNum++;
- flushCharactersBuffer();
+ if (m_doIndent) {
+ m_childNodeNum++;
+ flushCharactersBuffer();
+ }
if (m_elemContext.m_startTagOpen)
{
closeStartTag();
@@ -2501,8 +2477,10 @@
*/
public void startCDATA() throws org.xml.sax.SAXException
{
- m_childNodeNum++;
- flushCharactersBuffer();
+ if (m_doIndent) {
+ m_childNodeNum++;
+ flushCharactersBuffer();
+ }
m_cdataStartCalled = true;
}
@@ -2588,12 +2566,6 @@
*/
if (m_StringOfCDATASections != null)
m_elemContext.m_isCdataSection = isCdataSection();
-
- if (m_doIndent)
- {
- m_isprevtext = false;
- m_preserves.push(m_ispreserve);
- }
}
}
@@ -2943,7 +2915,9 @@
String value,
boolean xslAttribute)
{
- if (m_charactersBuffer.isAnyCharactersBuffered()) {
+ if (m_charactersBuffer.isNoCharactersBuffered()) {
+ return doAddAttributeAlways(uri, localName, rawName, type, value, xslAttribute);
+ } else {
/*
* If stylesheet includes xsl:copy-of an attribute node, XSLTC will
* fire an addAttribute event. When a text node is handling in
@@ -2954,8 +2928,6 @@
*
*/
return m_attributes.getIndex(rawName) < 0;
- } else {
- return doAddAttributeAlways(uri, localName, rawName, type, value, xslAttribute);
}
}
@@ -3086,7 +3058,7 @@
}
}
- if (rawName.equals("xml:space")) {
+ if (m_doIndent && rawName.equals("xml:space")) {
if (value.equals("preserve")) {
m_ispreserveSpace = true;
if (m_preserveSpaces.size() > 0)
@@ -3227,8 +3199,6 @@
// Leave m_format alone for now - Brian M.
// this.m_format = null;
this.m_inDoctype = false;
- this.m_ispreserve = false;
- this.m_preserves.clear();
this.m_ispreserveSpace = false;
this.m_preserveSpaces.clear();
this.m_childNodeNum = 0;
@@ -3411,6 +3381,7 @@
}
}
+
/**
* This inner class is used to buffer the text nodes and the entity
* reference nodes if indentation is on. There is only one CharacterBuffer
@@ -3438,7 +3409,7 @@
abstract char[] toChars();
}
- private Queue<GenericCharacters> bufferedCharacters = new ArrayDeque<>();
+ private List<GenericCharacters> bufferedCharacters = new ArrayList<>();
/**
* Append a text node to the buffer.
@@ -3495,35 +3466,44 @@
}
/**
- * @return True if any GenericCharacters is already buffered.
+ * @return True if no GenericCharacters are buffered.
*/
- public boolean isAnyCharactersBuffered() {
- return !bufferedCharacters.isEmpty();
+ public boolean isNoCharactersBuffered() {
+ return bufferedCharacters.isEmpty();
}
/**
* @return True if any buffered GenericCharacters has content.
*/
public boolean hasContent() {
- return bufferedCharacters.stream().anyMatch(GenericCharacters::hasContent);
+ for (GenericCharacters element : bufferedCharacters) {
+ if (element.hasContent())
+ return true;
+ }
+ return false;
}
/**
* Flush all buffered GenericCharacters.
*/
public void flush() throws SAXException {
- GenericCharacters element;
- while ((element = bufferedCharacters.poll()) != null)
+ Iterator<GenericCharacters> itr = bufferedCharacters.iterator();
+ while (itr.hasNext()) {
+ GenericCharacters element = itr.next();
element.flush();
+ itr.remove();
+ }
}
/**
* Converts all buffered GenericCharacters to a new character array.
*/
public char[] toChars() {
- return bufferedCharacters.stream().map(GenericCharacters::toChars)
- .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).toString()
- .toCharArray();
+ StringBuilder sb = new StringBuilder();
+ for (GenericCharacters element : bufferedCharacters) {
+ sb.append(element.toChars());
+ }
+ return sb.toString().toCharArray();
}
/**
@@ -3534,6 +3514,7 @@
}
}
+
// Implement DTDHandler
/**
* If this method is called, the serializer is used as a
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/ToXMLStream.java Wed Jul 05 22:52:22 2017 +0200
@@ -88,8 +88,6 @@
setOmitXMLDeclaration(xmlListener.getOmitXMLDeclaration());
- m_ispreserve = xmlListener.m_ispreserve;
- m_preserves = xmlListener.m_preserves;
m_ispreserveSpace = xmlListener.m_ispreserveSpace;
m_preserveSpaces = xmlListener.m_preserveSpaces;
m_childNodeNum = xmlListener.m_childNodeNum;
@@ -201,7 +199,9 @@
*/
public void endDocument() throws org.xml.sax.SAXException
{
- flushCharactersBuffer();
+ if (m_doIndent) {
+ flushCharactersBuffer();
+ }
flushPending();
if (m_doIndent && !m_isprevtext)
{
@@ -235,11 +235,6 @@
*/
public void startPreserving() throws org.xml.sax.SAXException
{
-
- // Not sure this is really what we want. -sb
- m_preserves.push(true);
-
- m_ispreserve = true;
}
/**
@@ -251,9 +246,6 @@
*/
public void endPreserving() throws org.xml.sax.SAXException
{
-
- // Not sure this is really what we want. -sb
- m_ispreserve = m_preserves.isEmpty() ? false : m_preserves.pop();
}
/**
@@ -273,8 +265,10 @@
if (isInEntityRef())
return;
- m_childNodeNum++;
- flushCharactersBuffer();
+ if (m_doIndent) {
+ m_childNodeNum++;
+ flushCharactersBuffer();
+ }
flushPending();
if (target.equals(Result.PI_DISABLE_OUTPUT_ESCAPING))
--- a/jaxp/src/java.xml/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxp/src/java.xml/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,6 +26,8 @@
/**
* Defines the Java API for XML Processing (JAXP), the Streaming API for XML (StAX),
* the Simple API for XML (SAX), and the W3C Document Object Model (DOM) API.
+ *
+ * @since 9
*/
module java.xml {
exports javax.xml;
--- a/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/LayerModularXMLParserTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxp/test/javax/xml/jaxp/module/ServiceProviderTest/LayerModularXMLParserTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -96,7 +96,7 @@
public void testOneLayer() throws Exception {
ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1);
Configuration cf1 = Layer.boot().configuration()
- .resolveRequiresAndUses(finder1, ModuleFinder.of(), Set.of("test"));
+ .resolveAndBind(finder1, ModuleFinder.of(), Set.of("test"));
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, scl);
ClassLoader cl1 = layer1.findLoader("test");
@@ -126,12 +126,12 @@
public void testTwoLayer() throws Exception {
ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1);
Configuration cf1 = Layer.boot().configuration()
- .resolveRequiresAndUses(finder1, ModuleFinder.of(), Set.of("test"));
+ .resolveAndBind(finder1, ModuleFinder.of(), Set.of("test"));
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, scl);
ModuleFinder finder2 = ModuleFinder.of(MOD_DIR2);
- Configuration cf2 = cf1.resolveRequiresAndUses(finder2, ModuleFinder.of(), Set.of("test"));
+ Configuration cf2 = cf1.resolveAndBind(finder2, ModuleFinder.of(), Set.of("test"));
Layer layer2 = layer1.defineModulesWithOneLoader(cf2, layer1.findLoader("test"));
ClassLoader cl2 = layer2.findLoader("test");
@@ -160,12 +160,12 @@
public void testTwoLayerWithDuplicate() throws Exception {
ModuleFinder finder1 = ModuleFinder.of(MOD_DIR1, MOD_DIR2);
Configuration cf1 = Layer.boot().configuration()
- .resolveRequiresAndUses(finder1, ModuleFinder.of(), Set.of("test"));
+ .resolveAndBind(finder1, ModuleFinder.of(), Set.of("test"));
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, scl);
ModuleFinder finder2 = ModuleFinder.of(MOD_DIR2);
- Configuration cf2 = cf1.resolveRequiresAndUses(finder2, ModuleFinder.of(), Set.of("test"));
+ Configuration cf2 = cf1.resolveAndBind(finder2, ModuleFinder.of(), Set.of("test"));
Layer layer2 = layer1.defineModulesWithOneLoader(cf2, layer1.findLoader("test"));
ClassLoader cl2 = layer2.findLoader("test");
--- a/jaxws/.hgtags Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxws/.hgtags Wed Jul 05 22:52:22 2017 +0200
@@ -401,3 +401,4 @@
7a532a9a227137155b905341d4b99939db51220e jdk-9+153
34af95c7dbff74f3448fcdb7d745524e8a1cc88a jdk-9+154
9b9918656c97724fd89c04a8547043bbd37f5935 jdk-9+155
+7c829eba781409b4fe15392639289af1553dcf63 jdk-9+156
--- a/jaxws/src/java.activation/share/classes/META-INF/mimetypes.default Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxws/src/java.activation/share/classes/META-INF/mimetypes.default Wed Jul 05 22:52:22 2017 +0200
@@ -7,6 +7,7 @@
image/ief ief
image/jpeg jpeg jpg jpe JPG
image/tiff tiff tif
+image/png png PNG
image/x-xwindowdump xwd
application/postscript ai eps ps
application/rtf rtf
--- a/jaxws/src/java.activation/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxws/src/java.activation/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the JavaBeans Activation Framework (JAF) API.
+ *
+ * @since 9
*/
module java.activation {
requires transitive java.datatransfer;
--- a/jaxws/src/java.xml.bind/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxws/src/java.xml.bind/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the Java Architecture for XML Binding (JAXB) API.
+ *
+ * @since 9
*/
module java.xml.bind {
requires transitive java.activation;
--- a/jaxws/src/java.xml.ws.annotation/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxws/src/java.xml.ws.annotation/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,6 +26,8 @@
/**
* Defines a subset of the Common Annotations API to support programs running
* on the Java SE Platform.
+ *
+ * @since 9
*/
module java.xml.ws.annotation {
exports javax.annotation;
--- a/jaxws/src/java.xml.ws/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jaxws/src/java.xml.ws/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,6 +26,8 @@
/**
* Defines the Java API for XML-Based Web Services (JAX-WS), and
* the Web Services Metadata API.
+ *
+ * @since 9
*/
module java.xml.ws {
requires transitive java.activation;
--- a/jdk/.hgtags Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/.hgtags Wed Jul 05 22:52:22 2017 +0200
@@ -398,3 +398,4 @@
1c4411322327aea3f91011ec3977a12a05b09629 jdk-9+153
c97e7a8b8da062b9070df442f9cf308e10845fb7 jdk-9+154
e170c858888e83d5c0994504599b6ed7a1fb0cfc jdk-9+155
+7d64e541a6c04c714bcad4c8b553db912f827cd5 jdk-9+156
--- a/jdk/make/src/classes/build/tools/jigsaw/GenGraphs.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/make/src/classes/build/tools/jigsaw/GenGraphs.java Wed Jul 05 22:52:22 2017 +0200
@@ -153,9 +153,9 @@
*/
void genDotFile(String name, Set<String> roots) throws IOException {
Configuration cf =
- Configuration.empty().resolveRequires(ModuleFinder.ofSystem(),
- ModuleFinder.of(),
- roots);
+ Configuration.empty().resolve(ModuleFinder.ofSystem(),
+ ModuleFinder.of(),
+ roots);
Set<ModuleDescriptor> mds = cf.modules().stream()
.map(ResolvedModule::reference)
--- a/jdk/make/src/classes/build/tools/jigsaw/ModuleSummary.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/make/src/classes/build/tools/jigsaw/ModuleSummary.java Wed Jul 05 22:52:22 2017 +0200
@@ -291,9 +291,9 @@
static Configuration resolve(Set<String> roots) {
return Configuration.empty()
- .resolveRequires(ModuleFinder.ofSystem(),
- ModuleFinder.of(),
- roots);
+ .resolve(ModuleFinder.ofSystem(),
+ ModuleFinder.of(),
+ roots);
}
static class HtmlDocument {
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Wed Jul 05 22:52:22 2017 +0200
@@ -425,6 +425,7 @@
* </ul>
*
* @since 9
+ * @spec JPMS
*/
@CallerSensitive
public static Class<?> forName(Module module, String name) {
@@ -819,6 +820,7 @@
* @return the module that this class or interface is a member of
*
* @since 9
+ * @spec JPMS
*/
public Module getModule() {
return module;
@@ -924,6 +926,8 @@
* this method returns {@code null}.
*
* @return the package of this class.
+ * @revised 9
+ * @spec JPMS
*/
public Package getPackage() {
if (isPrimitive() || isArray()) {
@@ -951,20 +955,30 @@
* declaring class} of the {@link #getEnclosingMethod enclosing method} or
* {@link #getEnclosingConstructor enclosing constructor}.
*
- * <p> This method returns {@code null} if this class represents an array type,
- * a primitive type or void.
+ * <p> If this class represents an array type then this method returns the
+ * package name of the element type. If this class represents a primitive
+ * type or void then the package name "{@code java.lang}" is returned.
*
* @return the fully qualified package name
*
* @since 9
+ * @spec JPMS
* @jls 6.7 Fully Qualified Names
*/
public String getPackageName() {
String pn = this.packageName;
- if (pn == null && !isArray() && !isPrimitive()) {
- String cn = getName();
- int dot = cn.lastIndexOf('.');
- pn = (dot != -1) ? cn.substring(0, dot).intern() : "";
+ if (pn == null) {
+ Class<?> c = this;
+ while (c.isArray()) {
+ c = c.getComponentType();
+ }
+ if (c.isPrimitive()) {
+ pn = "java.lang";
+ } else {
+ String cn = c.getName();
+ int dot = cn.lastIndexOf('.');
+ pn = (dot != -1) ? cn.substring(0, dot).intern() : "";
+ }
this.packageName = pn;
}
return pn;
@@ -2491,10 +2505,16 @@
* Finds a resource with a given name.
*
* <p> If this class is in a named {@link Module Module} then this method
- * will attempt to find the resource in the module by means of the absolute
- * resource name, subject to the rules for encapsulation specified in the
- * {@code Module} {@link Module#getResourceAsStream getResourceAsStream}
- * method.
+ * will attempt to find the resource in the module. This is done by
+ * delegating to the module's class loader {@link
+ * ClassLoader#findResource(String,String) findResource(String,String)}
+ * method, invoking it with the module name and the absolute name of the
+ * resource. Resources in named modules are subject to the rules for
+ * encapsulation specified in the {@code Module} {@link
+ * Module#getResourceAsStream getResourceAsStream} method and so this
+ * method returns {@code null} when the resource is a
+ * non-"{@code .class}" resource in a package that is not open to the
+ * caller's module.
*
* <p> Otherwise, if this class is not in a named module then the rules for
* searching resources associated with a given class are implemented by the
@@ -2503,9 +2523,8 @@
* the bootstrap class loader, the method delegates to {@link
* ClassLoader#getSystemResourceAsStream}.
*
- * <p> Before finding a resource in the caller's module or delegation to a
- * class loader, an absolute resource name is constructed from the given
- * resource name using this algorithm:
+ * <p> Before delegation, an absolute resource name is constructed from the
+ * given resource name using this algorithm:
*
* <ul>
*
@@ -2532,7 +2551,11 @@
* least the caller module, or access to the resource is denied
* by the security manager.
* @throws NullPointerException If {@code name} is {@code null}
+ *
+ * @see Module#getResourceAsStream(String)
* @since 1.1
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public InputStream getResourceAsStream(String name) {
@@ -2585,10 +2608,16 @@
* Finds a resource with a given name.
*
* <p> If this class is in a named {@link Module Module} then this method
- * will attempt to find the resource in the module by means of the absolute
- * resource name, subject to the rules for encapsulation specified in the
- * {@code Module} {@link Module#getResourceAsStream getResourceAsStream}
- * method.
+ * will attempt to find the resource in the module. This is done by
+ * delegating to the module's class loader {@link
+ * ClassLoader#findResource(String,String) findResource(String,String)}
+ * method, invoking it with the module name and the absolute name of the
+ * resource. Resources in named modules are subject to the rules for
+ * encapsulation specified in the {@code Module} {@link
+ * Module#getResourceAsStream getResourceAsStream} method and so this
+ * method returns {@code null} when the resource is a
+ * non-"{@code .class}" resource in a package that is not open to the
+ * caller's module.
*
* <p> Otherwise, if this class is not in a named module then the rules for
* searching resources associated with a given class are implemented by the
@@ -2627,6 +2656,8 @@
* manager.
* @throws NullPointerException If {@code name} is {@code null}
* @since 1.1
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public URL getResource(String name) {
--- a/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/ClassLoader.java Wed Jul 05 22:52:22 2017 +0200
@@ -207,6 +207,8 @@
* @jls 13.1 The Form of a Binary
* @see #resolveClass(Class)
* @since 1.0
+ * @revised 9
+ * @spec JPMS
*/
public abstract class ClassLoader {
@@ -380,12 +382,12 @@
* method doesn't allow creation of a new class loader.
*
* @since 9
+ * @spec JPMS
*/
protected ClassLoader(String name, ClassLoader parent) {
this(checkCreateClassLoader(name), name, parent);
}
-
/**
* Creates a new class loader using the specified parent class loader for
* delegation.
@@ -440,6 +442,7 @@
* this class loader is not named.
*
* @since 9
+ * @spec JPMS
*/
public String getName() {
return name;
@@ -710,6 +713,7 @@
* if the class could not be found.
*
* @since 9
+ * @spec JPMS
*/
protected Class<?> findClass(String moduleName, String name) {
if (moduleName == null) {
@@ -834,6 +838,8 @@
* @see java.security.SecureClassLoader
*
* @since 1.1
+ * @revised 9
+ * @spec JPMS
*/
protected final Class<?> defineClass(String name, byte[] b, int off, int len)
throws ClassFormatError
@@ -967,6 +973,9 @@
* certificates than this class, or if {@code name} begins with
* "{@code java.}" and this class loader is not the platform
* class loader or its ancestor.
+ *
+ * @revised 9
+ * @spec JPMS
*/
protected final Class<?> defineClass(String name, byte[] b, int off, int len,
ProtectionDomain protectionDomain)
@@ -1041,6 +1050,8 @@
* @see #defineClass(String, byte[], int, int, ProtectionDomain)
*
* @since 1.5
+ * @revised 9
+ * @spec JPMS
*/
protected final Class<?> defineClass(String name, java.nio.ByteBuffer b,
ProtectionDomain protectionDomain)
@@ -1264,11 +1275,11 @@
* Class loader implementations that support the loading from modules
* should override this method.
*
- * @apiNote This method is the basis for the {@code Class} {@link
- * Class#getResource getResource} and {@link Class#getResourceAsStream
- * getResourceAsStream} methods. It is not subject to the rules for
- * encapsulation specified by {@code Module} {@link
- * Module#getResourceAsStream getResourceAsStream}.
+ * @apiNote This method is the basis for the {@link
+ * Class#getResource Class.getResource}, {@link Class#getResourceAsStream
+ * Class.getResourceAsStream}, and {@link Module#getResourceAsStream
+ * Module.getResourceAsStream} methods. It is not subject to the rules for
+ * encapsulation specified by {@code Module.getResourceAsStream}.
*
* @implSpec The default implementation attempts to find the resource by
* invoking {@link #findResource(String)} when the {@code moduleName} is
@@ -1292,6 +1303,7 @@
*
* @see java.lang.module.ModuleReader#find(String)
* @since 9
+ * @spec JPMS
*/
protected URL findResource(String moduleName, String name) throws IOException {
if (moduleName == null) {
@@ -1342,6 +1354,8 @@
* @throws NullPointerException If {@code name} is {@code null}
*
* @since 1.1
+ * @revised 9
+ * @spec JPMS
*/
public URL getResource(String name) {
Objects.requireNonNull(name);
@@ -1403,6 +1417,8 @@
* @see #findResources(String)
*
* @since 1.2
+ * @revised 9
+ * @spec JPMS
*/
public Enumeration<URL> getResources(String name) throws IOException {
Objects.requireNonNull(name);
@@ -1499,6 +1515,8 @@
* denied by the security manager.
*
* @since 1.2
+ * @revised 9
+ * @spec JPMS
*/
protected URL findResource(String name) {
return null;
@@ -1531,6 +1549,8 @@
* If I/O errors occur
*
* @since 1.2
+ * @revised 9
+ * @spec JPMS
*/
protected Enumeration<URL> findResources(String name) throws IOException {
return Collections.emptyEnumeration();
@@ -1601,6 +1621,8 @@
* denied by the security manager.
*
* @since 1.1
+ * @revised 9
+ * @spec JPMS
*/
public static URL getSystemResource(String name) {
return getSystemClassLoader().getResource(name);
@@ -1636,6 +1658,8 @@
* If I/O errors occur
*
* @since 1.2
+ * @revised 9
+ * @spec JPMS
*/
public static Enumeration<URL> getSystemResources(String name)
throws IOException
@@ -1667,6 +1691,8 @@
* @throws NullPointerException If {@code name} is {@code null}
*
* @since 1.1
+ * @revised 9
+ * @spec JPMS
*/
public InputStream getResourceAsStream(String name) {
Objects.requireNonNull(name);
@@ -1699,6 +1725,8 @@
* denied by the security manager.
*
* @since 1.1
+ * @revised 9
+ * @spec JPMS
*/
public static InputStream getSystemResourceAsStream(String name) {
URL url = getSystemResource(name);
@@ -1749,6 +1777,7 @@
*
* @see Module#isNamed()
* @since 9
+ * @spec JPMS
*/
public final Module getUnnamedModule() {
return unnamedModule;
@@ -1772,6 +1801,7 @@
* {@link RuntimePermission}{@code ("getClassLoader")}
*
* @since 9
+ * @spec JPMS
*/
@CallerSensitive
public static ClassLoader getPlatformClassLoader() {
@@ -1847,6 +1877,8 @@
* {@link Throwable#getCause()} method.
*
* @revised 1.4
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public static ClassLoader getSystemClassLoader() {
@@ -2101,6 +2133,8 @@
* defined by this class loader
*
* @since 1.2
+ * @revised 9
+ * @spec JPMS
*
* @see <a href="../../../technotes/guides/jar/jar.html#versioning">
* The JAR File Specification: Package Versioning</a>
@@ -2138,6 +2172,7 @@
* if {@code name} is {@code null}.
*
* @since 9
+ * @spec JPMS
*/
public final Package getDefinedPackage(String name) {
Objects.requireNonNull(name, "name cannot be null");
@@ -2160,6 +2195,7 @@
* or an zero length array if no package has been defined by this class loader.
*
* @since 9
+ * @spec JPMS
*/
public final Package[] getDefinedPackages() {
return packages().toArray(Package[]::new);
@@ -2196,6 +2232,8 @@
* a {@code Package} for the specified class loader.
*
* @since 1.2
+ * @revised 9
+ * @spec JPMS
*/
@Deprecated(since="9")
protected Package getPackage(String name) {
@@ -2220,6 +2258,8 @@
* class loader and its ancestors
*
* @since 1.2
+ * @revised 9
+ * @spec JPMS
*/
protected Package[] getPackages() {
Stream<Package> pkgs = packages();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/IllegalCallerException.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 java.lang;
+
+/**
+ * Thrown to indicate that a method has been called by an inappropriate caller.
+ *
+ * @since 9
+ * @spec JPMS
+ * @see StackWalker#getCallerClass
+ */
+public class IllegalCallerException extends RuntimeException {
+ /**
+ * Constructs an IllegalCallerException with no detail message.
+ */
+ public IllegalCallerException() {
+ super();
+ }
+
+ /**
+ * Constructs an IllegalCallerException with the specified detail
+ * message.
+ *
+ * @param s the String that contains a detailed message (can be null)
+ */
+ public IllegalCallerException(String s) {
+ super(s);
+ }
+
+ /**
+ * Constructs a new exception with the specified detail message and
+ * cause.
+ *
+ * @param message the detail message (can be null)
+ * @param cause the cause (can be null)
+ */
+ public IllegalCallerException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Constructs a new exception with the specified cause and a detail
+ * message of {@code (cause==null ? null : cause.toString())} (which
+ * typically contains the class and detail message of {@code cause}).
+ *
+ * @param cause the cause (can be null)
+ */
+ public IllegalCallerException(Throwable cause) {
+ super(cause);
+ }
+
+ static final long serialVersionUID = -2349421918363102232L;
+}
--- a/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrame.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -55,14 +55,36 @@
*
* <p>A single local variable can hold a value of type boolean, byte, char,
* short, int, float, reference or returnAddress. A pair of local variables
- * can hold a value of type long or double. In other words,
- * a value of type long or type double occupies two consecutive local
- * variables. For a value of primitive type, the element in the
- * local variable array is an {@link PrimitiveValue} object;
- * otherwise, the element is an {@code Object}.
+ * can hold a value of type long or double (JVMS section 2.6.1). Primitive
+ * locals are represented in the returned array as {@code PrimitiveSlot}s,
+ * with longs and doubles occupying a pair of consecutive
+ * {@code PrimitiveSlot}s.
+ *
+ * <p>The current VM implementation does not provide specific type
+ * information for primitive locals. This method simply returns the raw
+ * contents of the VM's primitive locals on a best-effort basis, without
+ * indicating a specific type.
+ *
+ * <p>The returned array may contain null entries for local variables that
+ * are not live.
*
- * <p>The returned array may contain null entries if a local variable is not
- * live.
+ * @implNote
+ * <p> The specific subclass of {@code PrimitiveSlot} will reflect the
+ * underlying architecture, and will be either {@code PrimitiveSlot32} or
+ * {@code PrimitiveSlot64}.
+ *
+ * <p>How a long or double value is stored in the pair of
+ * {@code PrimitiveSlot}s can vary based on the underlying architecture and
+ * VM implementation. On 32-bit architectures, long/double values are split
+ * between the two {@code PrimitiveSlot32}s.
+ * On 64-bit architectures, the entire value may be stored in one of the
+ * {@code PrimitiveSlot64}s, with the other {@code PrimitiveSlot64} being
+ * unused.
+ *
+ * <p>The contents of the unused, high-order portion of a
+ * {@code PrimitiveSlot64} (when storing a primitive other than a long or
+ * double) is unspecified. In particular, the unused bits are not
+ * necessarily zeroed out.
*
* @return the local variable array of this stack frame.
*/
@@ -78,7 +100,7 @@
* <p>Each entry on the operand stack can hold a value of any Java Virtual
* Machine Type.
* For a value of primitive type, the element in the returned array is
- * an {@link PrimitiveValue} object; otherwise, the element is the {@code Object}
+ * a {@link PrimitiveSlot} object; otherwise, the element is the {@code Object}
* on the operand stack.
*
* @return the operand stack of this stack frame.
@@ -87,107 +109,37 @@
/**
* <em>UNSUPPORTED</em> This interface is intended to be package-private
- * or move to an internal package.<p>
+ * or moved to an internal package.<p>
*
- * Represents a local variable or an entry on the operand whose value is
+ * Represents a local variable or an entry on the operand stack whose value is
* of primitive type.
*/
- public abstract class PrimitiveValue {
+ public abstract class PrimitiveSlot {
/**
- * Returns the base type of this primitive value, one of
- * {@code B, D, C, F, I, J, S, Z}.
- *
- * @return Name of a base type
- * @jvms table 4.3-A
+ * Returns the size, in bytes, of the slot.
*/
- abstract char type();
+ public abstract int size();
/**
- * Returns the boolean value if this primitive value is of type boolean.
- * @return the boolean value if this primitive value is of type boolean.
+ * Returns the int value if this primitive value is of size 4
+ * @return the int value if this primitive value is of size 4
*
* @throws UnsupportedOperationException if this primitive value is not
- * of type boolean.
- */
- public boolean booleanValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the int value if this primitive value is of type int.
- * @return the int value if this primitive value is of type int.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type int.
+ * of size 4.
*/
public int intValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the long value if this primitive value is of type long.
- * @return the long value if this primitive value is of type long.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type long.
- */
- public long longValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
+ throw new UnsupportedOperationException("this " + size() + "-byte primitive");
}
/**
- * Returns the char value if this primitive value is of type char.
- * @return the char value if this primitive value is of type char.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type char.
- */
- public char charValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the byte value if this primitive value is of type byte.
- * @return the byte value if this primitive value is of type byte.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type byte.
- */
- public byte byteValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the short value if this primitive value is of type short.
- * @return the short value if this primitive value is of type short.
+ * Returns the long value if this primitive value is of size 8
+ * @return the long value if this primitive value is of size 8
*
* @throws UnsupportedOperationException if this primitive value is not
- * of type short.
- */
- public short shortValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the float value if this primitive value is of type float.
- * @return the float value if this primitive value is of type float.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type float.
+ * of size 8.
*/
- public float floatValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
- }
-
- /**
- * Returns the double value if this primitive value is of type double.
- * @return the double value if this primitive value is of type double.
- *
- * @throws UnsupportedOperationException if this primitive value is not
- * of type double.
- */
- public double doubleValue() {
- throw new UnsupportedOperationException("this primitive of type " + type());
+ public long longValue() {
+ throw new UnsupportedOperationException("this " + size() + "-byte primitive");
}
}
--- a/jdk/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/LiveStackFrameInfo.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,15 +24,13 @@
*/
package java.lang;
-import java.lang.StackWalker.Option;
-import java.util.EnumSet;
-import java.util.Set;
-
-import static java.lang.StackWalker.ExtendedOption.*;
-
final class LiveStackFrameInfo extends StackFrameInfo implements LiveStackFrame {
private static Object[] EMPTY_ARRAY = new Object[0];
+ // These flags must match the values maintained in the VM
+ private static final int MODE_INTERPRETED = 0x01;
+ private static final int MODE_COMPILED = 0x02;
+
LiveStackFrameInfo(StackWalker walker) {
super(walker);
}
@@ -41,6 +39,7 @@
private Object[] monitors = EMPTY_ARRAY;
private Object[] locals = EMPTY_ARRAY;
private Object[] operands = EMPTY_ARRAY;
+ private int mode = 0;
@Override
public Object[] getMonitors() {
@@ -57,51 +56,44 @@
return operands;
}
- /*
- * Convert primitive value to {@code Primitive} object to represent
- * a local variable or an element on the operand stack of primitive type.
- */
- static PrimitiveValue asPrimitive(boolean value) {
- return new BooleanPrimitive(value);
- }
-
- static PrimitiveValue asPrimitive(int value) {
- return new IntPrimitive(value);
- }
-
- static PrimitiveValue asPrimitive(short value) {
- return new ShortPrimitive(value);
- }
-
- static PrimitiveValue asPrimitive(char value) {
- return new CharPrimitive(value);
+ @Override
+ public String toString() {
+ StringBuilder retVal = new StringBuilder(super.toString());
+ if (mode != 0) {
+ retVal.append("(");
+ if ((mode & MODE_INTERPRETED) == MODE_INTERPRETED) {
+ retVal.append(" interpreted ");
+ }
+ if ((mode & MODE_COMPILED) == MODE_COMPILED) {
+ retVal.append(" compiled ");
+ }
+ retVal.append(")");
+ }
+ return retVal.toString();
}
- static PrimitiveValue asPrimitive(byte value) {
- return new BytePrimitive(value);
- }
+ /*
+ * Convert primitive value to {@code PrimitiveSlot} object to represent
+ * a local variable or an element on the operand stack of primitive type.
+ */
- static PrimitiveValue asPrimitive(long value) {
- return new LongPrimitive(value);
+ static PrimitiveSlot asPrimitive(int value) {
+ return new PrimitiveSlot32(value);
}
- static PrimitiveValue asPrimitive(float value) {
- return new FloatPrimitive(value);
+ static PrimitiveSlot asPrimitive(long value) {
+ return new PrimitiveSlot64(value);
}
- static PrimitiveValue asPrimitive(double value) {
- return new DoublePrimitive(value);
- }
-
- private static class IntPrimitive extends PrimitiveValue {
+ private static class PrimitiveSlot32 extends PrimitiveSlot {
final int value;
- IntPrimitive(int value) {
+ PrimitiveSlot32(int value) {
this.value = value;
}
@Override
- public char type() {
- return 'I';
+ public int size() {
+ return 4;
}
@Override
@@ -115,103 +107,15 @@
}
}
- private static class ShortPrimitive extends PrimitiveValue {
- final short value;
- ShortPrimitive(short value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'S';
- }
-
- @Override
- public short shortValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class BooleanPrimitive extends PrimitiveValue {
- final boolean value;
- BooleanPrimitive(boolean value) {
+ private static class PrimitiveSlot64 extends PrimitiveSlot {
+ final long value;
+ PrimitiveSlot64(long value) {
this.value = value;
}
@Override
- public char type() {
- return 'Z';
- }
-
- @Override
- public boolean booleanValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class CharPrimitive extends PrimitiveValue {
- final char value;
- CharPrimitive(char value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'C';
- }
-
- @Override
- public char charValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class BytePrimitive extends PrimitiveValue {
- final byte value;
- BytePrimitive(byte value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'B';
- }
-
- @Override
- public byte byteValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class LongPrimitive extends PrimitiveValue {
- final long value;
- LongPrimitive(long value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'J';
+ public int size() {
+ return 8;
}
@Override
@@ -224,48 +128,4 @@
return String.valueOf(value);
}
}
-
- private static class FloatPrimitive extends PrimitiveValue {
- final float value;
- FloatPrimitive(float value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'F';
- }
-
- @Override
- public float floatValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
-
- private static class DoublePrimitive extends PrimitiveValue {
- final double value;
- DoublePrimitive(double value) {
- this.value = value;
- }
-
- @Override
- public char type() {
- return 'D';
- }
-
- @Override
- public double doubleValue() {
- return value;
- }
-
- @Override
- public String toString() {
- return String.valueOf(value);
- }
- }
}
--- a/jdk/src/java.base/share/classes/java/lang/Package.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/Package.java Wed Jul 05 22:52:22 2017 +0200
@@ -111,6 +111,8 @@
* @see ClassLoader#definePackage(String, String, String, String, String, String, String, URL)
*
* @since 1.2
+ * @revised 9
+ * @spec JPMS
*/
public class Package extends NamedPackage implements java.lang.reflect.AnnotatedElement {
/**
@@ -207,6 +209,9 @@
* is returned if it is not known.
* @return the vendor that implemented this package, {@code null}
* is returned if it is not known.
+ *
+ * @revised 9
+ * @spec JPMS
*/
public String getImplementationVendor() {
return versionInfo.implVendor;
@@ -334,6 +339,9 @@
* a {@code Package} for the specified class loader.
*
* @see ClassLoader#getDefinedPackage
+ *
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
@Deprecated(since="9")
@@ -356,6 +364,9 @@
* class loader and its ancestors
*
* @see ClassLoader#getDefinedPackages
+ *
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public static Package[] getPackages() {
--- a/jdk/src/java.base/share/classes/java/lang/SecurityManager.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/SecurityManager.java Wed Jul 05 22:52:22 2017 +0200
@@ -1458,6 +1458,18 @@
}
/**
+ * Called by java.security.Security
+ */
+ static void invalidatePackageAccessCache() {
+ synchronized (packageAccessLock) {
+ packageAccessValid = false;
+ }
+ synchronized (packageDefinitionLock) {
+ packageDefinitionValid = false;
+ }
+ }
+
+ /**
* Returns true if the module's loader is the boot or platform loader.
*/
private static boolean isBootOrPlatformModule(Module m) {
--- a/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StackStreamFactory.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,11 +25,13 @@
package java.lang;
import jdk.internal.reflect.MethodAccessor;
+import jdk.internal.reflect.ConstructorAccessor;
import java.lang.StackWalker.Option;
import java.lang.StackWalker.StackFrame;
import java.lang.annotation.Native;
import java.lang.reflect.Method;
+import java.lang.reflect.Constructor;
import java.util.HashSet;
import java.util.NoSuchElementException;
import java.util.Objects;
@@ -684,7 +686,7 @@
frames[n++] = caller;
}
if (frames[1] == null) {
- throw new IllegalStateException("no caller frame");
+ throw new IllegalCallerException("no caller frame");
}
return n;
}
@@ -922,7 +924,8 @@
*/
final void setBatch(int depth, int startIndex, int endIndex) {
if (startIndex <= 0 || endIndex <= 0)
- throw new IllegalArgumentException("startIndex=" + startIndex + " endIndex=" + endIndex);
+ throw new IllegalArgumentException("startIndex=" + startIndex
+ + " endIndex=" + endIndex);
this.origin = startIndex;
this.fence = endIndex;
@@ -980,13 +983,18 @@
private static boolean isReflectionFrame(Class<?> c) {
if (c.getName().startsWith("jdk.internal.reflect") &&
- !MethodAccessor.class.isAssignableFrom(c)) {
- throw new InternalError("Not jdk.internal.reflect.MethodAccessor: " + c.toString());
+ !MethodAccessor.class.isAssignableFrom(c) &&
+ !ConstructorAccessor.class.isAssignableFrom(c)) {
+ throw new InternalError("Not jdk.internal.reflect.MethodAccessor"
+ + " or jdk.internal.reflect.ConstructorAccessor: "
+ + c.toString());
}
// ## should filter all @Hidden frames?
return c == Method.class ||
- MethodAccessor.class.isAssignableFrom(c) ||
- c.getName().startsWith("java.lang.invoke.LambdaForm");
+ c == Constructor.class ||
+ MethodAccessor.class.isAssignableFrom(c) ||
+ ConstructorAccessor.class.isAssignableFrom(c) ||
+ c.getName().startsWith("java.lang.invoke.LambdaForm");
}
}
--- a/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java Wed Jul 05 22:52:22 2017 +0200
@@ -92,6 +92,8 @@
* @throws NullPointerException if {@code declaringClass} or
* {@code methodName} is null
* @since 1.5
+ * @revised 9
+ * @spec JPMS
*/
public StackTraceElement(String declaringClass, String methodName,
String fileName, int lineNumber) {
@@ -128,6 +130,7 @@
* or {@code methodName} is {@code null}
*
* @since 9
+ * @spec JPMS
*/
public StackTraceElement(String classLoaderName,
String moduleName, String moduleVersion,
@@ -187,6 +190,7 @@
* point represented by this stack trace element; {@code null}
* if the module name is not available.
* @since 9
+ * @spec JPMS
* @see java.lang.reflect.Module#getName()
*/
public String getModuleName() {
@@ -201,6 +205,7 @@
* point represented by this stack trace element; {@code null}
* if the module version is not available.
* @since 9
+ * @spec JPMS
* @see java.lang.module.ModuleDescriptor.Version
*/
public String getModuleVersion() {
@@ -216,6 +221,7 @@
* if the class loader is not named.
*
* @since 9
+ * @spec JPMS
* @see java.lang.ClassLoader#getName()
*/
public String getClassLoaderName() {
@@ -329,6 +335,8 @@
* {@link java.lang.StackWalker.StackFrame}, where an implementation may
* choose to omit some element in the returned string.
*
+ * @revised 9
+ * @spec JPMS
* @see Throwable#printStackTrace()
*/
public String toString() {
@@ -376,6 +384,9 @@
* @return true if the specified object is another
* {@code StackTraceElement} instance representing the same
* execution point as this instance.
+ *
+ * @revised 9
+ * @spec JPMS
*/
public boolean equals(Object obj) {
if (obj==this)
--- a/jdk/src/java.base/share/classes/java/lang/StackWalker.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/StackWalker.java Wed Jul 05 22:52:22 2017 +0200
@@ -29,6 +29,7 @@
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
+import java.util.function.Predicate;
import java.util.stream.Stream;
/**
@@ -207,13 +208,23 @@
/**
* Shows all reflection frames.
*
- * <p>By default, reflection frames are hidden. This includes the
- * {@link java.lang.reflect.Method#invoke} method
- * and the reflection implementation classes. A {@code StackWalker} with
- * this {@code SHOW_REFLECT_FRAMES} option will show all reflection frames.
- * The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
+ * <p>By default, reflection frames are hidden. A {@code StackWalker}
+ * configured with this {@code SHOW_REFLECT_FRAMES} option
+ * will show all reflection frames that
+ * include {@link java.lang.reflect.Method#invoke} and
+ * {@link java.lang.reflect.Constructor#newInstance(Object...)}
+ * and their reflection implementation classes.
+ *
+ * <p>The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
* reflection frames and it will also show other hidden frames that
* are implementation-specific.
+ *
+ * @apiNote
+ * This option includes the stack frames representing the invocation of
+ * {@code Method} and {@code Constructor}. Any utility methods that
+ * are equivalent to calling {@code Method.invoke} or
+ * {@code Constructor.newInstance} such as {@code Class.newInstance}
+ * are not filtered or controlled by any stack walking option.
*/
SHOW_REFLECT_FRAMES,
/**
@@ -465,28 +476,31 @@
}
/**
- * Gets the {@code Class} object of the caller invoking the method
- * that calls this {@code getCallerClass} method.
+ * Gets the {@code Class} object of the caller who invoked the method
+ * that invoked {@code getCallerClass}.
*
- * <p> Reflection frames, {@link java.lang.invoke.MethodHandle}, and
- * hidden frames are filtered regardless of the
+ * <p> This method filters {@linkplain Option#SHOW_REFLECT_FRAMES reflection
+ * frames}, {@link java.lang.invoke.MethodHandle}, and
+ * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} regardless of the
* {@link Option#SHOW_REFLECT_FRAMES SHOW_REFLECT_FRAMES}
* and {@link Option#SHOW_HIDDEN_FRAMES SHOW_HIDDEN_FRAMES} options
* this {@code StackWalker} has been configured with.
*
+ * <p> This method should be called when a caller frame is present. If
+ * it is called from the bottom most frame on the stack,
+ * {@code IllegalCallerException} will be thrown.
+ *
* <p> This method throws {@code UnsupportedOperationException}
* if this {@code StackWalker} is not configured with the
* {@link Option#RETAIN_CLASS_REFERENCE RETAIN_CLASS_REFERENCE} option.
- * This method should be called when a caller frame is present. If
- * it is called from the last frame on the stack,
- * {@code IllegalStateException} will be thrown.
*
* @apiNote
* For example, {@code Util::getResourceBundle} loads a resource bundle
- * on behalf of the caller. It calls this {@code getCallerClass} method
- * to find the method calling {@code Util::getResourceBundle} and uses the caller's
- * class loader to load the resource bundle. The caller class in this example
- * is the {@code MyTool} class.
+ * on behalf of the caller. It invokes {@code getCallerClass} to identify
+ * the class whose method called {@code Util::getResourceBundle}.
+ * Then, it obtains the class loader of that class, and uses
+ * the class loader to load the resource bundle. The caller class
+ * in this example is {@code MyTool}.
*
* <pre>{@code
* class Util {
@@ -517,17 +531,17 @@
* }</pre>
*
* When the {@code getCallerClass} method is called from a method that
- * is the last frame on the stack,
+ * is the bottom most frame on the stack,
* for example, {@code static public void main} method launched by the
* {@code java} launcher, or a method invoked from a JNI attached thread,
- * {@code IllegalStateException} is thrown.
+ * {@code IllegalCallerException} is thrown.
*
* @return {@code Class} object of the caller's caller invoking this method.
*
* @throws UnsupportedOperationException if this {@code StackWalker}
* is not configured with {@link Option#RETAIN_CLASS_REFERENCE
* Option.RETAIN_CLASS_REFERENCE}.
- * @throws IllegalStateException if there is no caller frame, i.e.
+ * @throws IllegalCallerException if there is no caller frame, i.e.
* when this {@code getCallerClass} method is called from a method
* which is the last frame on the stack.
*/
--- a/jdk/src/java.base/share/classes/java/lang/System.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/System.java Wed Jul 05 22:52:22 2017 +0200
@@ -1942,13 +1942,12 @@
* the application classpath or modulepath.
*/
private static void initPhase3() {
- // Initialize publicLookup early, to avoid bootstrapping circularities
- // with security manager using java.lang.invoke infrastructure.
- java.lang.invoke.MethodHandles.publicLookup();
-
// set security manager
String cn = System.getProperty("java.security.manager");
if (cn != null) {
+ // ensure image reader for java.base is initialized before security manager
+ Object.class.getResource("module-info.class");
+
if (cn.isEmpty() || "default".equals(cn)) {
System.setSecurityManager(new SecurityManager());
} else {
@@ -2053,6 +2052,9 @@
public String fastUUID(long lsb, long msb) {
return Long.fastUUID(lsb, msb);
}
+ public void invalidatePackageAccessCache() {
+ SecurityManager.invalidatePackageAccessCache();
+ }
});
}
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/AbstractValidatingLambdaMetafactory.java Wed Jul 05 22:52:22 2017 +0200
@@ -141,6 +141,18 @@
this.markerInterfaces = markerInterfaces;
this.additionalBridges = additionalBridges;
+ if (samMethodName.isEmpty() ||
+ samMethodName.indexOf('.') >= 0 ||
+ samMethodName.indexOf(';') >= 0 ||
+ samMethodName.indexOf('[') >= 0 ||
+ samMethodName.indexOf('/') >= 0 ||
+ samMethodName.indexOf('<') >= 0 ||
+ samMethodName.indexOf('>') >= 0) {
+ throw new LambdaConversionException(String.format(
+ "Method name '%s' is not legal",
+ samMethodName));
+ }
+
if (!samBase.isInterface()) {
throw new LambdaConversionException(String.format(
"Functional interface %s is not an interface",
@@ -275,25 +287,39 @@
(implKind == MethodHandleInfo.REF_newInvokeSpecial)
? implDefiningClass
: implMethodType.returnType();
- Class<?> samReturnType = samMethodType.returnType();
if (!isAdaptableToAsReturn(actualReturnType, expectedType)) {
throw new LambdaConversionException(
String.format("Type mismatch for lambda return: %s is not convertible to %s",
actualReturnType, expectedType));
}
- if (!isAdaptableToAsReturnStrict(expectedType, samReturnType)) {
- throw new LambdaConversionException(
- String.format("Type mismatch for lambda expected return: %s is not convertible to %s",
- expectedType, samReturnType));
+
+ // Check descriptors of generated methods
+ checkDescriptor(samMethodType);
+ for (MethodType bridgeMT : additionalBridges) {
+ checkDescriptor(bridgeMT);
}
- for (MethodType bridgeMT : additionalBridges) {
- if (!isAdaptableToAsReturnStrict(expectedType, bridgeMT.returnType())) {
- throw new LambdaConversionException(
- String.format("Type mismatch for lambda expected return: %s is not convertible to %s",
- expectedType, bridgeMT.returnType()));
+ }
+
+ /** Validate that the given descriptor's types are compatible with {@code instantiatedMethodType} **/
+ private void checkDescriptor(MethodType descriptor) throws LambdaConversionException {
+ for (int i = 0; i < instantiatedMethodType.parameterCount(); i++) {
+ Class<?> instantiatedParamType = instantiatedMethodType.parameterType(i);
+ Class<?> descriptorParamType = descriptor.parameterType(i);
+ if (!descriptorParamType.isAssignableFrom(instantiatedParamType)) {
+ String msg = String.format("Type mismatch for instantiated parameter %d: %s is not a subtype of %s",
+ i, instantiatedParamType, descriptorParamType);
+ throw new LambdaConversionException(msg);
}
}
- }
+
+ Class<?> instantiatedReturnType = instantiatedMethodType.returnType();
+ Class<?> descriptorReturnType = descriptor.returnType();
+ if (!isAdaptableToAsReturnStrict(instantiatedReturnType, descriptorReturnType)) {
+ String msg = String.format("Type mismatch for lambda expected return: %s is not convertible to %s",
+ instantiatedReturnType, descriptorReturnType);
+ throw new LambdaConversionException(msg);
+ }
+ }
/**
* Check type adaptability for parameter types.
@@ -345,8 +371,8 @@
|| !fromType.equals(void.class) && isAdaptableTo(fromType, toType, false);
}
private boolean isAdaptableToAsReturnStrict(Class<?> fromType, Class<?> toType) {
- if (fromType.equals(void.class)) return toType.equals(void.class);
- return isAdaptableTo(fromType, toType, true);
+ if (fromType.equals(void.class) || toType.equals(void.class)) return fromType.equals(toType);
+ else return isAdaptableTo(fromType, toType, true);
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/MethodHandles.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,8 +25,6 @@
package java.lang.invoke;
-import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.internal.org.objectweb.asm.Opcodes;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import jdk.internal.vm.annotation.ForceInline;
@@ -111,13 +109,17 @@
/**
* Returns a {@link Lookup lookup object} which is trusted minimally.
- * It can only be used to create method handles to public members in
+ * The lookup has the {@code PUBLIC} and {@code UNCONDITIONAL} modes.
+ * It can only be used to create method handles to public members of
* public classes in packages that are exported unconditionally.
* <p>
- * For now, the {@linkplain Lookup#lookupClass lookup class} of this lookup
- * object is in an unnamed module.
- * Consequently, the lookup context of this lookup object will be the bootstrap
- * class loader, which means it cannot find user classes.
+ * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
+ * of this lookup object will be {@link java.lang.Object}.
+ *
+ * @apiNote The use of Object is conventional, and because the lookup modes are
+ * limited, there is no special access provided to the internals of Object, its package
+ * or its module. Consequently, the lookup context of this lookup object will be the
+ * bootstrap class loader, which means it cannot find user classes.
*
* <p style="font-size:smaller;">
* <em>Discussion:</em>
@@ -129,17 +131,12 @@
* Also, it cannot access
* <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
* @return a lookup object which is trusted minimally
+ *
+ * @revised 9
+ * @spec JPMS
*/
public static Lookup publicLookup() {
- // During VM startup then only classes in the java.base module can be
- // loaded and linked. This is because java.base exports aren't setup until
- // the module system is initialized, hence types in the unnamed module
- // (or any named module) can't link to java/lang/Object.
- if (!jdk.internal.misc.VM.isModuleSystemInited()) {
- return new Lookup(Object.class, Lookup.PUBLIC);
- } else {
- return LookupHelper.PUBLIC_LOOKUP;
- }
+ return Lookup.PUBLIC_LOOKUP;
}
/**
@@ -172,6 +169,7 @@
* @throws IllegalAccessException if the access check specified above fails
* @throws SecurityException if denied by the security manager
* @since 9
+ * @spec JPMS
* @see Lookup#dropLookupMode
*/
public static Lookup privateLookupIn(Class<?> targetClass, Lookup lookup) throws IllegalAccessException {
@@ -183,11 +181,11 @@
throw new IllegalArgumentException(targetClass + " is an array class");
Module targetModule = targetClass.getModule();
Module callerModule = lookup.lookupClass().getModule();
- if (callerModule != targetModule && targetModule.isNamed()) {
- if (!callerModule.canRead(targetModule))
- throw new IllegalAccessException(callerModule + " does not read " + targetModule);
+ if (!callerModule.canRead(targetModule))
+ throw new IllegalAccessException(callerModule + " does not read " + targetModule);
+ if (targetModule.isNamed()) {
String pn = targetClass.getPackageName();
- assert pn != null && pn.length() > 0 : "unnamed package cannot be in named module";
+ assert pn.length() > 0 : "unnamed package cannot be in named module";
if (!targetModule.isOpen(pn, callerModule))
throw new IllegalAccessException(targetModule + " does not open " + pn + " to " + callerModule);
}
@@ -601,6 +599,8 @@
* so that there can be a secure foundation for lookups.
* Nearly all other methods in the JSR 292 API rely on lookup
* objects to check access requests.
+ *
+ * @revised 9
*/
public static final
class Lookup {
@@ -647,15 +647,33 @@
* lookup class and public types in packages exported by other modules
* to the module of the lookup class.
* @since 9
+ * @spec JPMS
*/
public static final int MODULE = PACKAGE << 1;
- private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE | MODULE);
+ /** A single-bit mask representing {@code unconditional} access
+ * which may contribute to the result of {@link #lookupModes lookupModes}.
+ * The value is {@code 0x20}, which does not correspond meaningfully to
+ * any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
+ * A {@code Lookup} with this lookup mode assumes {@linkplain
+ * java.lang.reflect.Module#canRead(java.lang.reflect.Module) readability}.
+ * In conjunction with the {@code PUBLIC} modifier bit, a {@code Lookup}
+ * with this lookup mode can access all public members of public types
+ * of all modules where the type is in a package that is {@link
+ * java.lang.reflect.Module#isExported(String) exported unconditionally}.
+ * @since 9
+ * @spec JPMS
+ * @see #publicLookup()
+ */
+ public static final int UNCONDITIONAL = PACKAGE << 2;
+
+ private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE | MODULE | UNCONDITIONAL);
+ private static final int FULL_POWER_MODES = (ALL_MODES & ~UNCONDITIONAL);
private static final int TRUSTED = -1;
private static int fixmods(int mods) {
- mods &= (ALL_MODES - PACKAGE - MODULE);
- return (mods != 0) ? mods : (PACKAGE | MODULE);
+ mods &= (ALL_MODES - PACKAGE - MODULE - UNCONDITIONAL);
+ return (mods != 0) ? mods : (PACKAGE | MODULE | UNCONDITIONAL);
}
/** Tells which class is performing the lookup. It is this class against
@@ -682,13 +700,14 @@
* {@linkplain #PRIVATE PRIVATE (0x02)},
* {@linkplain #PROTECTED PROTECTED (0x04)},
* {@linkplain #PACKAGE PACKAGE (0x08)},
- * and {@linkplain #MODULE MODULE (0x10)}.
+ * {@linkplain #MODULE MODULE (0x10)},
+ * and {@linkplain #UNCONDITIONAL UNCONDITIONAL (0x20)}.
* <p>
* A freshly-created lookup object
- * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
- * has all possible bits set, since the caller class can access all its own members,
- * all public types in the caller's module, and all public types in packages exported
- * by other modules to the caller's module.
+ * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class} has
+ * all possible bits set, except {@code UNCONDITIONAL}. The lookup can be used to
+ * access all members of the caller's class, all public types in the caller's module,
+ * and all public types in packages exported by other modules to the caller's module.
* A lookup object on a new lookup class
* {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
* may have some mode bits set to zero.
@@ -701,6 +720,9 @@
* @return the lookup modes, which limit the kinds of access performed by this lookup object
* @see #in
* @see #dropLookupMode
+ *
+ * @revised 9
+ * @spec JPMS
*/
public int lookupModes() {
return allowedModes & ALL_MODES;
@@ -712,9 +734,9 @@
* which in turn is called by a method not in this package.
*/
Lookup(Class<?> lookupClass) {
- this(lookupClass, ALL_MODES);
+ this(lookupClass, FULL_POWER_MODES);
// make sure we haven't accidentally picked up a privileged class:
- checkUnprivilegedlookupClass(lookupClass, ALL_MODES);
+ checkUnprivilegedlookupClass(lookupClass, FULL_POWER_MODES);
}
private Lookup(Class<?> lookupClass, int allowedModes) {
@@ -730,19 +752,20 @@
* However, the resulting {@code Lookup} object is guaranteed
* to have no more access capabilities than the original.
* In particular, access capabilities can be lost as follows:<ul>
- * <li>If the lookup class for this {@code Lookup} is not in a named module,
- * and the new lookup class is in a named module {@code M}, then no members in
- * {@code M}'s non-exported packages will be accessible.
- * <li>If the lookup for this {@code Lookup} is in a named module, and the
- * new lookup class is in a different module {@code M}, then no members, not even
- * public members in {@code M}'s exported packages, will be accessible.
- * <li>If the new lookup class differs from the old one,
- * protected members will not be accessible by virtue of inheritance.
- * (Protected members may continue to be accessible because of package sharing.)
+ * <li>If the old lookup class is in a {@link Module#isNamed() named} module, and
+ * the new lookup class is in a different module {@code M}, then no members, not
+ * even public members in {@code M}'s exported packages, will be accessible.
+ * The exception to this is when this lookup is {@link #publicLookup()
+ * publicLookup}, in which case {@code PUBLIC} access is not lost.
+ * <li>If the old lookup class is in an unnamed module, and the new lookup class
+ * is a different module then {@link #MODULE MODULE} access is lost.
+ * <li>If the new lookup class differs from the old one then {@code UNCONDITIONAL} is lost.
* <li>If the new lookup class is in a different package
* than the old one, protected and default (package) members will not be accessible.
* <li>If the new lookup class is not within the same package member
- * as the old one, private members will not be accessible.
+ * as the old one, private members will not be accessible, and protected members
+ * will not be accessible by virtue of inheritance.
+ * (Protected members may continue to be accessible because of package sharing.)
* <li>If the new lookup class is not accessible to the old lookup class,
* then no members, not even public members, will be accessible.
* (In all other cases, public members will continue to be accessible.)
@@ -757,32 +780,34 @@
* @return a lookup object which reports the desired lookup class, or the same object
* if there is no change
* @throws NullPointerException if the argument is null
+ *
+ * @revised 9
+ * @spec JPMS
*/
public Lookup in(Class<?> requestedLookupClass) {
Objects.requireNonNull(requestedLookupClass);
if (allowedModes == TRUSTED) // IMPL_LOOKUP can make any lookup at all
- return new Lookup(requestedLookupClass, ALL_MODES);
+ return new Lookup(requestedLookupClass, FULL_POWER_MODES);
if (requestedLookupClass == this.lookupClass)
return this; // keep same capabilities
-
- int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
+ int newModes = (allowedModes & FULL_POWER_MODES);
if (!VerifyAccess.isSameModule(this.lookupClass, requestedLookupClass)) {
- // Allowed to teleport from an unnamed to a named module but resulting
- // Lookup has no access to module private members
- if (this.lookupClass.getModule().isNamed()) {
+ // Need to drop all access when teleporting from a named module to another
+ // module. The exception is publicLookup where PUBLIC is not lost.
+ if (this.lookupClass.getModule().isNamed()
+ && (this.allowedModes & UNCONDITIONAL) == 0)
newModes = 0;
- } else {
- newModes &= ~MODULE;
- }
+ else
+ newModes &= ~(MODULE|PACKAGE|PRIVATE|PROTECTED);
}
if ((newModes & PACKAGE) != 0
&& !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
- newModes &= ~(PACKAGE|PRIVATE);
+ newModes &= ~(PACKAGE|PRIVATE|PROTECTED);
}
// Allow nestmate lookups to be created without special privilege:
if ((newModes & PRIVATE) != 0
&& !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
- newModes &= ~PRIVATE;
+ newModes &= ~(PRIVATE|PROTECTED);
}
if ((newModes & PUBLIC) != 0
&& !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
@@ -801,28 +826,29 @@
* finds members, but with a lookup mode that has lost the given lookup mode.
* The lookup mode to drop is one of {@link #PUBLIC PUBLIC}, {@link #MODULE
* MODULE}, {@link #PACKAGE PACKAGE}, {@link #PROTECTED PROTECTED} or {@link #PRIVATE PRIVATE}.
- * {@link #PROTECTED PROTECTED} is always dropped and so the resulting lookup
- * mode will never have this access capability. When dropping {@code PACKAGE}
- * then the resulting lookup will not have {@code PACKAGE} or {@code PRIVATE}
- * access. When dropping {@code MODULE} then the resulting lookup will not
- * have {@code MODULE}, {@code PACKAGE}, or {@code PRIVATE} access. If {@code
- * PUBLIC} is dropped then the resulting lookup has no access.
+ * {@link #PROTECTED PROTECTED} and {@link #UNCONDITIONAL UNCONDITIONAL} are always
+ * dropped and so the resulting lookup mode will never have these access capabilities.
+ * When dropping {@code PACKAGE} then the resulting lookup will not have {@code PACKAGE}
+ * or {@code PRIVATE} access. When dropping {@code MODULE} then the resulting lookup will
+ * not have {@code MODULE}, {@code PACKAGE}, or {@code PRIVATE} access. If {@code PUBLIC}
+ * is dropped then the resulting lookup has no access.
* @param modeToDrop the lookup mode to drop
* @return a lookup object which lacks the indicated mode, or the same object if there is no change
* @throws IllegalArgumentException if {@code modeToDrop} is not one of {@code PUBLIC},
- * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED} or {@code PRIVATE}
+ * {@code MODULE}, {@code PACKAGE}, {@code PROTECTED}, {@code PRIVATE} or {@code UNCONDITIONAL}
+ * @see MethodHandles#privateLookupIn
* @since 9
- * @see MethodHandles#privateLookupIn
*/
public Lookup dropLookupMode(int modeToDrop) {
int oldModes = lookupModes();
- int newModes = oldModes & ~(modeToDrop | PROTECTED);
+ int newModes = oldModes & ~(modeToDrop | PROTECTED | UNCONDITIONAL);
switch (modeToDrop) {
case PUBLIC: newModes &= ~(ALL_MODES); break;
case MODULE: newModes &= ~(PACKAGE | PRIVATE); break;
case PACKAGE: newModes &= ~(PRIVATE); break;
case PROTECTED:
- case PRIVATE: break;
+ case PRIVATE:
+ case UNCONDITIONAL: break;
default: throw new IllegalArgumentException(modeToDrop + " is not a valid mode to drop");
}
if (newModes == oldModes) return this; // return self if no change
@@ -835,6 +861,12 @@
/** Package-private version of lookup which is trusted. */
static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
+ /** Version of lookup which is trusted minimally.
+ * It can only be used to create method handles to publicly accessible
+ * members in packages that are exported unconditionally.
+ */
+ static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, (PUBLIC|UNCONDITIONAL));
+
private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
String name = lookupClass.getName();
if (name.startsWith("java.lang.invoke."))
@@ -845,7 +877,7 @@
// TODO replace with a more formal and less fragile mechanism
// that does not bluntly restrict classes under packages within
// java.base from looking up MethodHandles or VarHandles.
- if (allowedModes == ALL_MODES && lookupClass.getClassLoader() == null) {
+ if (allowedModes == FULL_POWER_MODES && lookupClass.getClassLoader() == null) {
if ((name.startsWith("java.") &&
!name.equals("java.lang.Thread") &&
!name.startsWith("java.util.concurrent.")) ||
@@ -866,6 +898,7 @@
* <ul>
* <li>If no access is allowed, the suffix is "/noaccess".
* <li>If only public access to types in exported packages is allowed, the suffix is "/public".
+ * <li>If only public access and unconditional access are allowed, the suffix is "/publicLookup".
* <li>If only public and module access are allowed, the suffix is "/module".
* <li>If only public, module and package access are allowed, the suffix is "/package".
* <li>If only public, module, package, and private access are allowed, the suffix is "/private".
@@ -884,6 +917,9 @@
* because it requires a direct subclass relationship between
* caller and callee.)
* @see #in
+ *
+ * @revised 9
+ * @spec JPMS
*/
@Override
public String toString() {
@@ -893,13 +929,15 @@
return cname + "/noaccess";
case PUBLIC:
return cname + "/public";
+ case PUBLIC|UNCONDITIONAL:
+ return cname + "/publicLookup";
case PUBLIC|MODULE:
return cname + "/module";
case PUBLIC|MODULE|PACKAGE:
return cname + "/package";
- case ALL_MODES & ~PROTECTED:
+ case FULL_POWER_MODES & ~PROTECTED:
return cname + "/private";
- case ALL_MODES:
+ case FULL_POWER_MODES:
return cname;
case TRUSTED:
return "/trusted"; // internal only; not exported
@@ -1580,6 +1618,7 @@
if (refKind == REF_invokeSpecial)
refKind = REF_invokeVirtual;
assert(method.isMethod());
+ @SuppressWarnings("deprecation")
Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
return lookup.getDirectMethodNoSecurityManager(refKind, method.getDeclaringClass(), method, findBoundCallerClass(method));
}
@@ -1662,6 +1701,7 @@
public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
MemberName ctor = new MemberName(c);
assert(ctor.isConstructor());
+ @SuppressWarnings("deprecation")
Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);
}
@@ -1692,6 +1732,7 @@
assert(isSetter
? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
: MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
+ @SuppressWarnings("deprecation")
Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field);
}
@@ -2033,9 +2074,9 @@
(defc == refc ||
Modifier.isPublic(refc.getModifiers())));
if (!classOK && (allowedModes & PACKAGE) != 0) {
- classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), ALL_MODES) &&
+ classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), FULL_POWER_MODES) &&
(defc == refc ||
- VerifyAccess.isClassAccessible(refc, lookupClass(), ALL_MODES)));
+ VerifyAccess.isClassAccessible(refc, lookupClass(), FULL_POWER_MODES)));
}
if (!classOK)
return "class is not public";
@@ -2348,53 +2389,6 @@
}
/**
- * Helper class used to lazily create PUBLIC_LOOKUP with a lookup class
- * in an <em>unnamed module</em>.
- *
- * @see Lookup#publicLookup
- */
- private static class LookupHelper {
- private static final String UNNAMED = "Unnamed";
- private static final String OBJECT = "java/lang/Object";
-
- private static Class<?> createClass() {
- try {
- ClassWriter cw = new ClassWriter(0);
- cw.visit(Opcodes.V1_8,
- Opcodes.ACC_FINAL + Opcodes.ACC_SUPER,
- UNNAMED,
- null,
- OBJECT,
- null);
- cw.visitSource(UNNAMED, null);
- cw.visitEnd();
- byte[] bytes = cw.toByteArray();
- ClassLoader loader = new ClassLoader(null) {
- @Override
- protected Class<?> findClass(String cn) throws ClassNotFoundException {
- if (cn.equals(UNNAMED))
- return super.defineClass(UNNAMED, bytes, 0, bytes.length);
- throw new ClassNotFoundException(cn);
- }
- };
- return loader.loadClass(UNNAMED);
- } catch (Exception e) {
- throw new InternalError(e);
- }
- }
-
- private static final Class<?> PUBLIC_LOOKUP_CLASS = createClass();
-
- /**
- * Lookup that is trusted minimally. It can only be used to create
- * method handles to publicly accessible members in exported packages.
- *
- * @see MethodHandles#publicLookup
- */
- static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_LOOKUP_CLASS, Lookup.PUBLIC);
- }
-
- /**
* Produces a method handle constructing arrays of a desired type.
* The return type of the method handle will be the array type.
* The type of its sole argument will be {@code int}, which specifies the size of the array.
--- a/jdk/src/java.base/share/classes/java/lang/module/Configuration.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/Configuration.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,126 +42,48 @@
import java.util.stream.Stream;
/**
- * The configuration that is the result of resolution or resolution with
- * service binding.
- *
- * <h2><a name="resolution">Resolution</a></h2>
- *
- * <p> Resolution is the process of computing the transitive closure of a set
- * of root modules over a set of observable modules by resolving the
- * dependences expressed by {@code requires} clauses.
- *
- * The <em>dependence graph</em> is augmented with edges that take account of
- * implicitly declared dependences ({@code requires transitive}) to create a
- * <em>readability graph</em>. A {@code Configuration} encapsulates the
- * resulting graph of {@link ResolvedModule resolved modules}.
- *
- * <p> Suppose we have the following observable modules: </p>
- * <pre> {@code
- * module m1 { requires m2; }
- * module m2 { requires transitive m3; }
- * module m3 { }
- * module m4 { }
- * } </pre>
+ * A configuration that is the result of <a href="package-summary.html#resolution">
+ * resolution</a> or resolution with <a href="package-summary.html#servicebinding">
+ * service binding</a>.
*
- * <p> If the module {@code m1} is resolved then the resulting configuration
- * contains three modules ({@code m1}, {@code m2}, {@code m3}). The edges in
- * its readability graph are: </p>
- * <pre> {@code
- * m1 --> m2 (meaning m1 reads m2)
- * m1 --> m3
- * m2 --> m3
- * } </pre>
- *
- * <p> Resolution is an additive process. When computing the transitive closure
- * then the dependence relation may include dependences on modules in parent
- * configurations. The result is a <em>relative configuration</em> that is
- * relative to one or more parent configurations and where the readability graph
- * may have edges from modules in the configuration to modules in parent
- * configurations.
- *
- * </p>
- *
- * <p> Suppose we have the following observable modules: </p>
- * <pre> {@code
- * module m1 { requires m2; requires java.xml; }
- * module m2 { }
- * } </pre>
+ * <p> A configuration encapsulates the <em>readability graph</em> that is the
+ * output of resolution. A readability graph is a directed graph where the nodes
+ * are of type {@link ResolvedModule} and the edges represent the readability
+ * amongst the modules. {@code Configuration} defines the {@link #modules()
+ * modules()} method to get the set of resolved modules in the graph. {@code
+ * ResolvedModule} defines the {@link ResolvedModule#reads() reads()} method to
+ * get the set of modules that a resolved module reads. The modules that are
+ * read may be in the same configuration or may be in {@link #parents() parent}
+ * configurations. </p>
*
- * <p> If module {@code m1} is resolved with the configuration for the {@link
- * java.lang.reflect.Layer#boot() boot} layer as the parent then the resulting
- * configuration contains two modules ({@code m1}, {@code m2}). The edges in
- * its readability graph are:
- * <pre> {@code
- * m1 --> m2
- * m1 --> java.xml
- * } </pre>
- * where module {@code java.xml} is in the parent configuration. For
- * simplicity, this example omits the implicitly declared dependence on the
- * {@code java.base} module.
- *
- * <a name="automaticmoduleresolution"></a>
- * <p> {@link ModuleDescriptor#isAutomatic() Automatic} modules receive special
- * treatment during resolution. Each automatic module is resolved so that it
- * reads all other modules in the configuration and all parent configurations.
- * Each automatic module is also resolved as if it {@code requires transitive}
- * all other automatic modules in the configuration (and all automatic modules
- * in parent configurations). </p>
-
- * <h2><a name="servicebinding">Service binding</a></h2>
+ * <p> Configuration defines the {@link #resolve(ModuleFinder,List,ModuleFinder,Collection)
+ * resolve} method to resolve a collection of root modules, and the {@link
+ * #resolveAndBind(ModuleFinder,List,ModuleFinder,Collection) resolveAndBind}
+ * method to do resolution with service binding. There are instance and
+ * static variants of both methods. The instance methods create a configuration
+ * with the receiver as the parent configuration. The static methods are for
+ * more advanced cases where there can be more than one parent configuration. </p>
*
- * <p> Service binding is the process of augmenting a graph of resolved modules
- * from the set of observable modules induced by the service-use dependence
- * ({@code uses} and {@code provides} clauses). Any module that was not
- * previously in the graph requires resolution to compute its transitive
- * closure. Service binding is an iterative process in that adding a module
- * that satisfies some service-use dependence may introduce new service-use
- * dependences. </p>
- *
- * <p> Suppose we have the following observable modules: </p>
- * <pre> {@code
- * module m1 { exports p; uses p.S; }
- * module m2 { requires m1; provides p.S with p2.S2; }
- * module m3 { requires m1; requires m4; provides p.S with p3.S3; }
- * module m4 { }
- * } </pre>
- *
- * <p> If the module {@code m1} is resolved then the resulting graph of modules
- * has one module ({@code m1}). If the graph is augmented with modules induced
- * by the service-use dependence relation then the configuration will contain
- * four modules ({@code m1}, {@code m2}, {@code m3}, {@code m4}). The edges in
- * its readability graph are: </p>
- * <pre> {@code
- * m2 --> m1
- * m3 --> m1
- * m3 --> m4
- * } </pre>
- * <p> The edges in the conceptual service-use graph are: </p>
- * <pre> {@code
- * m1 --> m2 (meaning m1 uses a service that is provided by m2)
- * m1 --> m3
- * } </pre>
- *
- * <p> If this configuration is instantiated as a {@code Layer}, and if code in
- * module {@code m1} uses {@link java.util.ServiceLoader ServiceLoader} to
- * iterate over implementations of {@code p.S.class}, then it will iterate over
- * an instance of {@code p2.S2} and {@code p3.S3}. </p>
+ * <p> Each {@link java.lang.reflect.Layer layer} of modules in the Java virtual
+ * machine is created from a configuration. The configuration for the {@link
+ * java.lang.reflect.Layer#boot() boot} layer is obtained by invoking {@code
+ * Layer.boot().configuration()}. The configuration for the boot layer will
+ * often be the parent when creating new configurations. </p>
*
* <h3> Example </h3>
*
- * <p> The following example uses the {@code resolveRequires} method to resolve
- * a module named <em>myapp</em> with the configuration for the boot layer as
- * the parent configuration. It prints the name of each resolved module and
- * the names of the modules that each module reads. </p>
+ * <p> The following example uses the {@link
+ * #resolve(ModuleFinder,ModuleFinder,Collection) resolve} method to resolve a
+ * module named <em>myapp</em> with the configuration for the boot layer as the
+ * parent configuration. It prints the name of each resolved module and the
+ * names of the modules that each module reads. </p>
*
* <pre>{@code
* ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
*
* Configuration parent = Layer.boot().configuration();
*
- * Configuration cf = parent.resolveRequires(finder,
- * ModuleFinder.of(),
- * Set.of("myapp"));
+ * Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("myapp"));
* cf.modules().forEach(m -> {
* System.out.format("%s -> %s%n",
* m.name(),
@@ -172,6 +94,7 @@
* }</pre>
*
* @since 9
+ * @spec JPMS
* @see java.lang.reflect.Layer
*/
public final class Configuration {
@@ -186,11 +109,23 @@
private final Set<ResolvedModule> modules;
private final Map<String, ResolvedModule> nameToModule;
+ // module constraints on target
+ private final String osName;
+ private final String osArch;
+ private final String osVersion;
+
+ String osName() { return osName; }
+ String osArch() { return osArch; }
+ String osVersion() { return osVersion; }
+
private Configuration() {
this.parents = Collections.emptyList();
this.graph = Collections.emptyMap();
this.modules = Collections.emptySet();
this.nameToModule = Collections.emptyMap();
+ this.osName = null;
+ this.osArch = null;
+ this.osVersion = null;
}
private Configuration(List<Configuration> parents,
@@ -214,27 +149,30 @@
this.graph = g;
this.modules = Set.of(moduleArray);
this.nameToModule = Map.ofEntries(nameEntries);
+
+ this.osName = resolver.osName();
+ this.osArch = resolver.osArch();
+ this.osVersion = resolver.osVersion();
}
-
/**
* Resolves a collection of root modules, with this configuration as its
* parent, to create a new configuration. This method works exactly as
* specified by the static {@link
- * #resolveRequires(ModuleFinder,List,ModuleFinder,Collection) resolveRequires}
+ * #resolve(ModuleFinder,List,ModuleFinder,Collection) resolve}
* method when invoked with this configuration as the parent. In other words,
* if this configuration is {@code cf} then this method is equivalent to
* invoking:
* <pre> {@code
- * Configuration.resolveRequires(before, List.of(cf), after, roots);
+ * Configuration.resolve(before, List.of(cf), after, roots);
* }</pre>
*
* @param before
* The <em>before</em> module finder to find modules
* @param after
- * The <em>after</em> module finder to locate modules when a
- * module cannot be located by the {@code before} module finder
- * and the module is not in this configuration
+ * The <em>after</em> module finder to locate modules when not
+ * located by the {@code before} module finder or in parent
+ * configurations
* @param roots
* The possibly-empty collection of module names of the modules
* to resolve
@@ -242,16 +180,20 @@
* @return The configuration that is the result of resolving the given
* root modules
*
+ * @throws FindException
+ * If resolution fails for any of the observability-related reasons
+ * specified by the static {@code resolve} method
* @throws ResolutionException
- * If resolution or the post-resolution checks fail
+ * If any of the post-resolution consistency checks specified by
+ * the static {@code resolve} method fail
* @throws SecurityException
* If locating a module is denied by the security manager
*/
- public Configuration resolveRequires(ModuleFinder before,
- ModuleFinder after,
- Collection<String> roots)
+ public Configuration resolve(ModuleFinder before,
+ ModuleFinder after,
+ Collection<String> roots)
{
- return resolveRequires(before, List.of(this), after, roots);
+ return resolve(before, List.of(this), after, roots);
}
@@ -259,12 +201,12 @@
* Resolves a collection of root modules, with service binding, and with
* this configuration as its parent, to create a new configuration.
* This method works exactly as specified by the static {@link
- * #resolveRequiresAndUses(ModuleFinder,List,ModuleFinder,Collection)
- * resolveRequiresAndUses} method when invoked with this configuration
+ * #resolveAndBind(ModuleFinder,List,ModuleFinder,Collection)
+ * resolveAndBind} method when invoked with this configuration
* as the parent. In other words, if this configuration is {@code cf} then
* this method is equivalent to invoking:
* <pre> {@code
- * Configuration.resolveRequiresAndUses(before, List.of(cf), after, roots);
+ * Configuration.resolveAndBind(before, List.of(cf), after, roots);
* }</pre>
*
*
@@ -272,25 +214,29 @@
* The <em>before</em> module finder to find modules
* @param after
* The <em>after</em> module finder to locate modules when not
- * located by the {@code before} module finder and this
- * configuration
+ * located by the {@code before} module finder or in parent
+ * configurations
* @param roots
* The possibly-empty collection of module names of the modules
* to resolve
*
- * @return The configuration that is the result of resolving the given
- * root modules
+ * @return The configuration that is the result of resolving, with service
+ * binding, the given root modules
*
+ * @throws FindException
+ * If resolution fails for any of the observability-related reasons
+ * specified by the static {@code resolve} method
* @throws ResolutionException
- * If resolution or the post-resolution checks fail
+ * If any of the post-resolution consistency checks specified by
+ * the static {@code resolve} method fail
* @throws SecurityException
* If locating a module is denied by the security manager
*/
- public Configuration resolveRequiresAndUses(ModuleFinder before,
- ModuleFinder after,
- Collection<String> roots)
+ public Configuration resolveAndBind(ModuleFinder before,
+ ModuleFinder after,
+ Collection<String> roots)
{
- return resolveRequiresAndUses(before, List.of(this), after, roots);
+ return resolveAndBind(before, List.of(this), after, roots);
}
@@ -301,14 +247,14 @@
*
* This method is used to create the configuration for the boot layer.
*/
- static Configuration resolveRequiresAndUses(ModuleFinder finder,
- Collection<String> roots,
- boolean check,
- PrintStream traceOutput)
+ static Configuration resolveAndBind(ModuleFinder finder,
+ Collection<String> roots,
+ boolean check,
+ PrintStream traceOutput)
{
List<Configuration> parents = List.of(empty());
Resolver resolver = new Resolver(finder, parents, ModuleFinder.of(), traceOutput);
- resolver.resolveRequires(roots).resolveUses();
+ resolver.resolve(roots).bind();
return new Configuration(parents, resolver, check);
}
@@ -328,11 +274,11 @@
*
* <p> When all modules have been resolved then the resulting dependency
* graph is checked to ensure that it does not contain cycles. A
- * readability graph is constructed and in conjunction with the module
+ * readability graph is constructed, and in conjunction with the module
* exports and service use, checked for consistency. </p>
*
- * <p> Resolution and the (post-resolution) consistency checks may fail for
- * following reasons: </p>
+ * <p> Resolution may fail with {@code FindException} for the following
+ * <em>observability-related</em> reasons: </p>
*
* <ul>
* <li><p> A root module, or a direct or transitive dependency, is not
@@ -343,6 +289,20 @@
* descriptor ({@code module-info.class}) or two versions of the same
* module are found in the same directory. </p></li>
*
+ * <li><p> A module with the required name is found but the module
+ * requires a different {@link ModuleDescriptor#osName() operating
+ * system}, {@link ModuleDescriptor#osArch() architecture}, or {@link
+ * ModuleDescriptor#osVersion() version} to other modules that have
+ * been resolved for the new configuration or modules in the parent
+ * configurations. </p></li>
+ *
+ * </ul>
+ *
+ * <p> Post-resolution consistency checks may fail with {@code
+ * ResolutionException} for the following reasons: </p>
+ *
+ * <ul>
+ *
* <li><p> A cycle is detected, say where module {@code m1} requires
* module {@code m2} and {@code m2} requires {@code m1}. </p></li>
*
@@ -356,20 +316,11 @@
* module {@code M} nor exported to {@code M} by any module that
* {@code M} reads. </p></li>
*
- * <li><p> A module {@code M} declares that it
- * "{@code provides ... with q.T}" but package {@code q} is not in
- * module {@code M}. </p></li>
+ * </ul>
*
- * <li><p> Two or more modules in the configuration are specific to
- * different {@link ModuleDescriptor#osName() operating systems},
- * {@link ModuleDescriptor#osArch() architectures}, or {@link
- * ModuleDescriptor#osVersion() versions}. </p></li>
- *
- * <li><p> Other implementation specific checks, for example referential
- * integrity checks to ensure that different versions of tighly coupled
- * modules cannot be combined in the same configuration. </p></li>
- *
- * </ul>
+ * @implNote In the implementation then observability of modules may depend
+ * on referential integrity checks that ensure different builds of tightly
+ * coupled modules are not combined in the same configuration.
*
* @param before
* The <em>before</em> module finder to find modules
@@ -386,17 +337,22 @@
* @return The configuration that is the result of resolving the given
* root modules
*
+ * @throws FindException
+ * If resolution fails for an observability-related reason
* @throws ResolutionException
- * If resolution or the post-resolution checks fail
+ * If a post-resolution consistency checks fails
* @throws IllegalArgumentException
- * If the list of parents is empty
+ * If the list of parents is empty, or the list has two or more
+ * parents with modules for different target operating systems,
+ * architectures, or versions
+ *
* @throws SecurityException
* If locating a module is denied by the security manager
*/
- public static Configuration resolveRequires(ModuleFinder before,
- List<Configuration> parents,
- ModuleFinder after,
- Collection<String> roots)
+ public static Configuration resolve(ModuleFinder before,
+ List<Configuration> parents,
+ ModuleFinder after,
+ Collection<String> roots)
{
Objects.requireNonNull(before);
Objects.requireNonNull(after);
@@ -407,7 +363,7 @@
throw new IllegalArgumentException("'parents' is empty");
Resolver resolver = new Resolver(before, parentList, after, null);
- resolver.resolveRequires(roots);
+ resolver.resolve(roots);
return new Configuration(parentList, resolver, true);
}
@@ -417,24 +373,24 @@
* configuration.
*
* <p> This method works exactly as specified by {@link
- * #resolveRequires(ModuleFinder,List,ModuleFinder,Collection)
- * resolveRequires} except that the graph of resolved modules is augmented
+ * #resolve(ModuleFinder,List,ModuleFinder,Collection)
+ * resolve} except that the graph of resolved modules is augmented
* with modules induced by the service-use dependence relation. </p>
*
* <p> More specifically, the root modules are resolved as if by calling
- * {@code resolveRequires}. The resolved modules, and all modules in the
+ * {@code resolve}. The resolved modules, and all modules in the
* parent configurations, with {@link ModuleDescriptor#uses() service
* dependences} are then examined. All modules found by the given module
* finders that {@link ModuleDescriptor#provides() provide} an
* implementation of one or more of the service types are added to the
* module graph and then resolved as if by calling the {@code
- * resolveRequires} method. Adding modules to the module graph may
- * introduce new service-use dependences and so the process works
- * iteratively until no more modules are added. </p>
+ * resolve} method. Adding modules to the module graph may introduce new
+ * service-use dependences and so the process works iteratively until no
+ * more modules are added. </p>
*
- * <p> As service binding involves resolution then it may fail with {@link
- * ResolutionException} for exactly the same reasons specified in
- * {@code resolveRequires}. </p>
+ * <p> As service binding involves resolution then it may fail with {@code
+ * FindException} or {@code ResolutionException} for exactly the same
+ * reasons specified in {@code resolve}. </p>
*
* @param before
* The <em>before</em> module finder to find modules
@@ -448,20 +404,26 @@
* The possibly-empty collection of module names of the modules
* to resolve
*
- * @return The configuration that is the result of resolving the given
- * root modules
+ * @return The configuration that is the result of resolving, with service
+ * binding, the given root modules
*
+ * @throws FindException
+ * If resolution fails for any of the observability-related reasons
+ * specified by the static {@code resolve} method
* @throws ResolutionException
- * If resolution or the post-resolution checks fail
+ * If any of the post-resolution consistency checks specified by
+ * the static {@code resolve} method fail
* @throws IllegalArgumentException
- * If the list of parents is empty
+ * If the list of parents is empty, or the list has two or more
+ * parents with modules for different target operating systems,
+ * architectures, or versions
* @throws SecurityException
* If locating a module is denied by the security manager
*/
- public static Configuration resolveRequiresAndUses(ModuleFinder before,
- List<Configuration> parents,
- ModuleFinder after,
- Collection<String> roots)
+ public static Configuration resolveAndBind(ModuleFinder before,
+ List<Configuration> parents,
+ ModuleFinder after,
+ Collection<String> roots)
{
Objects.requireNonNull(before);
Objects.requireNonNull(after);
@@ -472,7 +434,7 @@
throw new IllegalArgumentException("'parents' is empty");
Resolver resolver = new Resolver(before, parentList, after, null);
- resolver.resolveRequires(roots).resolveUses();
+ resolver.resolve(roots).bind();
return new Configuration(parentList, resolver, true);
}
--- a/jdk/src/java.base/share/classes/java/lang/module/FindException.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/FindException.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,10 +26,14 @@
package java.lang.module;
/**
- * Thrown by module finders when finding a module fails.
+ * Thrown by a {@link ModuleFinder ModuleFinder} when an error occurs finding
+ * a module. Also thrown by {@link
+ * Configuration#resolve(ModuleFinder,java.util.List,ModuleFinder,java.util.Collection)
+ * Configuration.resolve} when resolution fails for observability-related
+ * reasons.
*
- * @see ModuleFinder
* @since 9
+ * @spec JPMS
*/
public class FindException extends RuntimeException {
--- a/jdk/src/java.base/share/classes/java/lang/module/InvalidModuleDescriptorException.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/InvalidModuleDescriptorException.java Wed Jul 05 22:52:22 2017 +0200
@@ -31,6 +31,7 @@
*
* @see ModuleDescriptor#read
* @since 9
+ * @spec JPMS
*/
public class InvalidModuleDescriptorException extends RuntimeException {
private static final long serialVersionUID = 4863390386809347380L;
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,7 @@
import java.nio.ByteBuffer;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
@@ -56,18 +57,37 @@
/**
* A module descriptor.
*
- * <p> A {@code ModuleDescriptor} is typically created from the binary form
- * of a module declaration. Alternatively, the {@link ModuleDescriptor.Builder}
- * class can be used to create a {@code ModuleDescriptor} from its components.
- * The {@link #module module}, {@link #openModule openModule}, and {@link
- * #automaticModule automaticModule} methods create builders for building
- * different kinds of modules. </p>
+ * <p> A module descriptor describes a named module and defines methods to
+ * obtain each of its components. The module descriptor for a named module
+ * in the Java virtual machine is obtained by invoking the {@link
+ * java.lang.reflect.Module Module}'s {@link java.lang.reflect.Module#getDescriptor
+ * getDescriptor} method. Module descriptors can also be created using the
+ * {@link ModuleDescriptor.Builder} class or by reading the binary form of a
+ * module declaration ({@code module-info.class}) using the {@link
+ * #read(InputStream,Supplier) read} methods defined here. </p>
+ *
+ * <p> A module descriptor describes a <em>normal</em>, open, or automatic
+ * module. <em>Normal</em> modules and open modules describe their {@link
+ * #requires() dependences}, {@link #exports() exported-packages}, the services
+ * that they {@link #uses() use} or {@link #provides() provide}, and other
+ * components. <em>Normal</em> modules may {@link #opens() open} specific
+ * packages. The module descriptor for an open modules does not declare any
+ * open packages (its {@code opens} method returns an empty set) but when
+ * instantiated in the Java virtual machine then it is treated as if all
+ * packages are open. The module descriptor for an automatic module does not
+ * declare any dependences (except for the mandatory dependency on {@code
+ * java.base}), and does not declare any exported or open packages. Automatic
+ * module receive special treatment during resolution so that they read all
+ * other modules in the configuration. When an automatic module is instantiated
+ * in the Java virtual machine then it reads every unnamed module and is
+ * treated as if all packages are exported and open. </p>
*
* <p> {@code ModuleDescriptor} objects are immutable and safe for use by
* multiple concurrent threads.</p>
*
+ * @see java.lang.reflect.Module
* @since 9
- * @see java.lang.reflect.Module
+ * @spec JPMS
*/
public class ModuleDescriptor
@@ -75,10 +95,45 @@
{
/**
+ * A modifier on a module.
+ *
+ * @see ModuleDescriptor#modifiers()
+ * @since 9
+ */
+ public static enum Modifier {
+ /**
+ * An open module. An open module does not declare any open packages
+ * but the resulting module is treated as if all packages are open.
+ */
+ OPEN,
+
+ /**
+ * An automatic module. An automatic module is treated as if it exports
+ * and opens all packages.
+ *
+ * @apiNote This modifier does not correspond to a module flag in the
+ * binary form of a module declaration ({@code module-info.class}).
+ */
+ AUTOMATIC,
+
+ /**
+ * The module was not explicitly or implicitly declared.
+ */
+ SYNTHETIC,
+
+ /**
+ * The module was implicitly declared.
+ */
+ MANDATED;
+ }
+
+
+ /**
* <p> A dependence upon a module </p>
*
* @see ModuleDescriptor#requires()
* @since 9
+ * @spec JPMS
*/
public final static class Requires
@@ -88,7 +143,9 @@
/**
* A modifier on a module dependence.
*
+ * @see Requires#modifiers()
* @since 9
+ * @spec JPMS
*/
public static enum Modifier {
@@ -171,14 +228,18 @@
* Compares this module dependence to another.
*
* <p> Two {@code Requires} objects are compared by comparing their
- * module name lexicographically. Where the module names are equal then
- * the sets of modifiers are compared based on a value computed from the
- * ordinal of each modifier. Where the module names are equal and the
- * set of modifiers are equal then the version of the modules recorded
- * at compile-time are compared. When comparing the versions recorded
- * at compile-time then a dependence that has a recorded version is
- * considered to succeed a dependence that does not have a recorded
- * version. </p>
+ * module names lexicographically. Where the module names are equal
+ * then the sets of modifiers are compared in the same way that
+ * module modifiers are compared (see {@link ModuleDescriptor#compareTo
+ * ModuleDescriptor.compareTo}). Where the module names are equal and
+ * the set of modifiers are equal then the version of the modules
+ * recorded at compile-time are compared. When comparing the versions
+ * recorded at compile-time then a dependence that has a recorded
+ * version is considered to succeed a dependence that does not have a
+ * recorded version. </p>
+ *
+ * @param that
+ * The module dependence to compare
*
* @return A negative integer, zero, or a positive integer if this module
* dependence is less than, equal to, or greater than the given
@@ -186,39 +247,22 @@
*/
@Override
public int compareTo(Requires that) {
+ if (this == that) return 0;
+
int c = this.name().compareTo(that.name());
- if (c != 0)
- return c;
+ if (c != 0) return c;
// modifiers
- c = Long.compare(this.modsValue(), that.modsValue());
- if (c != 0)
- return c;
+ long v1 = modsValue(this.modifiers());
+ long v2 = modsValue(that.modifiers());
+ c = Long.compare(v1, v2);
+ if (c != 0) return c;
// compiledVersion
- if (this.compiledVersion != null) {
- if (that.compiledVersion != null)
- c = this.compiledVersion.compareTo(that.compiledVersion);
- else
- c = 1;
- } else {
- if (that.compiledVersion != null)
- c = -1;
- }
+ c = compare(this.compiledVersion, that.compiledVersion);
+ if (c != 0) return c;
- return c;
- }
-
- /**
- * Return a value for the modifiers to allow sets of modifiers to be
- * compared.
- */
- private long modsValue() {
- long value = 0;
- for (Modifier m : mods) {
- value += 1 << m.ordinal();
- }
- return value;
+ return 0;
}
/**
@@ -266,9 +310,9 @@
}
/**
- * Returns a string describing module dependence.
+ * Returns a string describing this module dependence.
*
- * @return A string describing module dependence
+ * @return A string describing this module dependence
*/
@Override
public String toString() {
@@ -285,18 +329,23 @@
/**
- * <p> A module export, may be qualified or unqualified. </p>
+ * <p> A package exported by a module, may be qualified or unqualified. </p>
*
* @see ModuleDescriptor#exports()
* @since 9
+ * @spec JPMS
*/
- public final static class Exports {
+ public final static class Exports
+ implements Comparable<Exports>
+ {
/**
- * A modifier on a module export.
+ * A modifier on an exported package.
*
+ * @see Exports#modifiers()
* @since 9
+ * @spec JPMS
*/
public static enum Modifier {
@@ -381,6 +430,52 @@
}
/**
+ * Compares this module export to another.
+ *
+ * <p> Two {@code Exports} objects are compared by comparing the package
+ * names lexicographically. Where the packages names are equal then the
+ * sets of modifiers are compared in the same way that module modifiers
+ * are compared (see {@link ModuleDescriptor#compareTo
+ * ModuleDescriptor.compareTo}). Where the package names are equal and
+ * the set of modifiers are equal then the set of target modules are
+ * compared. This is done by sorting the names of the target modules
+ * in ascending order, and according to their natural ordering, and then
+ * comparing the corresponding elements lexicographically. Where the
+ * sets differ in size, and the larger set contains all elements of the
+ * smaller set, then the larger set is considered to succeed the smaller
+ * set. </p>
+ *
+ * @param that
+ * The module export to compare
+ *
+ * @return A negative integer, zero, or a positive integer if this module
+ * export is less than, equal to, or greater than the given
+ * export dependence
+ */
+ @Override
+ public int compareTo(Exports that) {
+ if (this == that) return 0;
+
+ int c = source.compareTo(that.source);
+ if (c != 0)
+ return c;
+
+ // modifiers
+ long v1 = modsValue(this.modifiers());
+ long v2 = modsValue(that.modifiers());
+ c = Long.compare(v1, v2);
+ if (c != 0)
+ return c;
+
+ // targets
+ c = compare(targets, that.targets);
+ if (c != 0)
+ return c;
+
+ return 0;
+ }
+
+ /**
* Computes a hash code for this module export.
*
* <p> The hash code is based upon the modifiers, the package name,
@@ -425,9 +520,9 @@
}
/**
- * Returns a string describing module export.
+ * Returns a string describing the exported package.
*
- * @return A string describing module export
+ * @return A string describing the exported package
*/
@Override
public String toString() {
@@ -441,8 +536,7 @@
/**
- * <p> Represents a module <em>opens</em> directive, may be qualified or
- * unqualified. </p>
+ * <p> A package opened by a module, may be qualified or unqualified. </p>
*
* <p> The <em>opens</em> directive in a module declaration declares a
* package to be open to allow all types in the package, and all their
@@ -452,26 +546,30 @@
*
* @see ModuleDescriptor#opens()
* @since 9
+ * @spec JPMS
*/
- public final static class Opens {
-
+ public final static class Opens
+ implements Comparable<Opens>
+ {
/**
- * A modifier on a module <em>opens</em> directive.
+ * A modifier on an open package.
*
+ * @see Opens#modifiers()
* @since 9
+ * @spec JPMS
*/
public static enum Modifier {
/**
- * The opens was not explicitly or implicitly declared in the
- * source of the module declaration.
+ * The open package was not explicitly or implicitly declared in
+ * the source of the module declaration.
*/
SYNTHETIC,
/**
- * The opens was implicitly declared in the source of the module
- * declaration.
+ * The open package was implicitly declared in the source of the
+ * module declaration.
*/
MANDATED;
@@ -544,6 +642,52 @@
}
/**
+ * Compares this module opens to another.
+ *
+ * <p> Two {@code Opens} objects are compared by comparing the package
+ * names lexicographically. Where the packages names are equal then the
+ * sets of modifiers are compared in the same way that module modifiers
+ * are compared (see {@link ModuleDescriptor#compareTo
+ * ModuleDescriptor.compareTo}). Where the package names are equal and
+ * the set of modifiers are equal then the set of target modules are
+ * compared. This is done by sorting the names of the target modules
+ * in ascending order, and according to their natural ordering, and then
+ * comparing the corresponding elements lexicographically. Where the
+ * sets differ in size, and the larger set contains all elements of the
+ * smaller set, then the larger set is considered to succeed the smaller
+ * set. </p>
+ *
+ * @param that
+ * The module opens to compare
+ *
+ * @return A negative integer, zero, or a positive integer if this module
+ * opens is less than, equal to, or greater than the given
+ * module opens
+ */
+ @Override
+ public int compareTo(Opens that) {
+ if (this == that) return 0;
+
+ int c = source.compareTo(that.source);
+ if (c != 0)
+ return c;
+
+ // modifiers
+ long v1 = modsValue(this.modifiers());
+ long v2 = modsValue(that.modifiers());
+ c = Long.compare(v1, v2);
+ if (c != 0)
+ return c;
+
+ // targets
+ c = compare(targets, that.targets);
+ if (c != 0)
+ return c;
+
+ return 0;
+ }
+
+ /**
* Computes a hash code for this module opens.
*
* <p> The hash code is based upon the modifiers, the package name,
@@ -588,9 +732,9 @@
}
/**
- * Returns a string describing module opens.
+ * Returns a string describing the open package.
*
- * @return A string describing module opens
+ * @return A string describing the open package
*/
@Override
public String toString() {
@@ -608,10 +752,12 @@
*
* @see ModuleDescriptor#provides()
* @since 9
+ * @spec JPMS
*/
- public final static class Provides {
-
+ public final static class Provides
+ implements Comparable<Provides>
+ {
private final String service;
private final List<String> providers;
@@ -642,6 +788,46 @@
public List<String> providers() { return providers; }
/**
+ * Compares this provides to another.
+ *
+ * <p> Two {@code Provides} objects are compared by comparing the fully
+ * qualified class name of the service type lexicographically. Where the
+ * class names are equal then the list of the provider class names are
+ * compared by comparing the corresponding elements of both lists
+ * lexicographically and in sequence. Where the lists differ in size,
+ * {@code N} is the size of the shorter list, and the first {@code N}
+ * corresponding elements are equal, then the longer list is considered
+ * to succeed the shorter list. </p>
+ *
+ * @param that
+ * The {@code Provides} to compare
+ *
+ * @return A negative integer, zero, or a positive integer if this provides
+ * is less than, equal to, or greater than the given provides
+ */
+ public int compareTo(Provides that) {
+ if (this == that) return 0;
+
+ int c = service.compareTo(that.service);
+ if (c != 0) return c;
+
+ // compare provider class names in sequence
+ int size1 = this.providers.size();
+ int size2 = that.providers.size();
+ for (int index=0; index<Math.min(size1, size2); index++) {
+ String e1 = this.providers.get(index);
+ String e2 = that.providers.get(index);
+ c = e1.compareTo(e2);
+ if (c != 0) return c;
+ }
+ if (size1 == size2) {
+ return 0;
+ } else {
+ return (size1 > size2) ? 1 : -1;
+ }
+ }
+
+ /**
* Computes a hash code for this provides.
*
* <p> The hash code is based upon the service type and the set of
@@ -699,7 +885,7 @@
*
* <p> A version string has three components: The version number itself, an
* optional pre-release version, and an optional build version. Each
- * component is sequence of tokens; each token is either a non-negative
+ * component is a sequence of tokens; each token is either a non-negative
* integer or a string. Tokens are separated by the punctuation characters
* {@code '.'}, {@code '-'}, or {@code '+'}, or by transitions from a
* sequence of digits to a sequence of characters that are neither digits
@@ -740,6 +926,7 @@
*
* @see ModuleDescriptor#version()
* @since 9
+ * @spec JPMS
*/
public final static class Version
@@ -1009,36 +1196,26 @@
}
-
+
private final String name;
private final Version version;
- private final boolean open;
-
- // Indicates if synthesised for a JAR file found on the module path
- private final boolean automatic;
-
- // Not generated from a module-info.java
- private final boolean synthetic;
-
+ private final Set<Modifier> modifiers;
+ private final boolean open; // true if modifiers contains OPEN
+ private final boolean automatic; // true if modifiers contains AUTOMATIC
private final Set<Requires> requires;
private final Set<Exports> exports;
private final Set<Opens> opens;
private final Set<String> uses;
private final Set<Provides> provides;
-
- // Added post-compilation by tools
private final Set<String> packages;
private final String mainClass;
private final String osName;
private final String osArch;
private final String osVersion;
-
private ModuleDescriptor(String name,
Version version,
- boolean open,
- boolean automatic,
- boolean synthetic,
+ Set<Modifier> modifiers,
Set<Requires> requires,
Set<Exports> exports,
Set<Opens> opens,
@@ -1052,10 +1229,9 @@
{
this.name = name;
this.version = version;
- this.open = open;
- this.automatic = automatic;
- this.synthetic = synthetic;
-
+ this.modifiers = emptyOrUnmodifiableSet(modifiers);
+ this.open = modifiers.contains(Modifier.OPEN);
+ this.automatic = modifiers.contains(Modifier.AUTOMATIC);
assert (requires.stream().map(Requires::name).distinct().count()
== requires.size());
this.requires = emptyOrUnmodifiableSet(requires);
@@ -1072,40 +1248,12 @@
}
/**
- * Clones the given module descriptor with an augmented set of packages
- */
- ModuleDescriptor(ModuleDescriptor md, Set<String> pkgs) {
- this.name = md.name;
- this.version = md.version;
- this.open = md.open;
- this.automatic = md.automatic;
- this.synthetic = md.synthetic;
-
- this.requires = md.requires;
- this.exports = md.exports;
- this.opens = md.opens;
- this.uses = md.uses;
- this.provides = md.provides;
-
- Set<String> packages = new HashSet<>(md.packages);
- packages.addAll(pkgs);
- this.packages = emptyOrUnmodifiableSet(packages);
-
- this.mainClass = md.mainClass;
- this.osName = md.osName;
- this.osArch = md.osArch;
- this.osVersion = md.osVersion;
- }
-
- /**
* Creates a module descriptor from its components.
* The arguments are pre-validated and sets are unmodifiable sets.
*/
ModuleDescriptor(String name,
Version version,
- boolean open,
- boolean automatic,
- boolean synthetic,
+ Set<Modifier> modifiers,
Set<Requires> requires,
Set<Exports> exports,
Set<Opens> opens,
@@ -1120,9 +1268,9 @@
boolean unused) {
this.name = name;
this.version = version;
- this.open = open;
- this.automatic = automatic;
- this.synthetic = synthetic;
+ this.modifiers = modifiers;
+ this.open = modifiers.contains(Modifier.OPEN);
+ this.automatic = modifiers.contains(Modifier.AUTOMATIC);
this.requires = requires;
this.exports = exports;
this.opens = opens;
@@ -1137,7 +1285,7 @@
}
/**
- * <p> The module name. </p>
+ * <p> Returns the module name. </p>
*
* @return The module name
*/
@@ -1146,11 +1294,19 @@
}
/**
+ * <p> Returns the set of module modifiers. </p>
+ *
+ * @return A possibly-empty unmodifiable set of modifiers
+ */
+ public Set<Modifier> modifiers() {
+ return modifiers;
+ }
+
+ /**
* <p> Returns {@code true} if this is an open module. </p>
*
- * <p> An open module does not declare any open packages (the {@link #opens()
- * opens} method returns an empty set) but the resulting module is treated
- * as if all packages are open. </p>
+ * <p> This method is equivalent to testing if the set of {@link #modifiers
+ * modifiers} contains the {@link Modifier#OPEN OPEN} modifier. </p>
*
* @return {@code true} if this is an open module
*/
@@ -1161,12 +1317,8 @@
/**
* <p> Returns {@code true} if this is an automatic module. </p>
*
- * <p> An automatic module is defined implicitly rather than explicitly
- * and therefore does not have a module declaration. JAR files located on
- * the application module path, or by the {@link ModuleFinder} returned by
- * {@link ModuleFinder#of(java.nio.file.Path[]) ModuleFinder.of}, are
- * treated as automatic modules if they do have not have a module
- * declaration. </p>
+ * <p> This method is equivalent to testing if the set of {@link #modifiers
+ * modifiers} contains the {@link Modifier#OPEN AUTOMATIC} modifier. </p>
*
* @return {@code true} if this is an automatic module
*/
@@ -1175,20 +1327,13 @@
}
/**
- * <p> Returns {@code true} if this module descriptor was not generated
- * from an explicit module declaration ({@code module-info.java})
- * or an implicit module declaration (an {@link #isAutomatic() automatic}
- * module). </p>
+ * <p> Returns the set of {@code Requires} objects representing the module
+ * dependences. </p>
*
- * @return {@code true} if this module descriptor was not generated by
- * an explicit or implicit module declaration
- */
- public boolean isSynthetic() {
- return synthetic;
- }
-
- /**
- * <p> The dependences of this module. </p>
+ * <p> The set includes a dependency on "{@code java.base}" when this
+ * module is not named "{@code java.base}". If this module is an automatic
+ * module then it does not have a dependency on any module other than
+ * "{@code java.base}". </p>
*
* @return A possibly-empty unmodifiable set of {@link Requires} objects
*/
@@ -1197,7 +1342,11 @@
}
/**
- * <p> The module exports. </p>
+ * <p> Returns the set of {@code Exports} objects representing the exported
+ * packages. </p>
+ *
+ * <p> If this module is an automatic module then the set of exports
+ * is empty. </p>
*
* @return A possibly-empty unmodifiable set of exported packages
*/
@@ -1206,16 +1355,11 @@
}
/**
- * <p> The module <em>opens</em> directives. </p>
+ * <p> Returns the set of {@code Opens} objects representing the open
+ * packages. </p>
*
- * <p> Each {@code Opens} object in the set represents a package (and
- * the set of target module names when qualified) where all types in the
- * package, and all their members, not just public types and their public
- * members, can be reflected on when using APIs that bypass or suppress
- * default Java language access control checks. </p>
- *
- * <p> This method returns an empty set when invoked on {@link #isOpen()
- * open} module. </p>
+ * <p> If this module is an open module or an automatic module then the
+ * set of open packages is empty. </p>
*
* @return A possibly-empty unmodifiable set of open packages
*/
@@ -1224,7 +1368,10 @@
}
/**
- * <p> The service dependences of this module. </p>
+ * <p> Returns the set of service dependences. </p>
+ *
+ * <p> If this module is an automatic module then the set of service
+ * dependences is empty. </p>
*
* @return A possibly-empty unmodifiable set of the fully qualified class
* names of the service types used
@@ -1234,7 +1381,8 @@
}
/**
- * <p> The services that this module provides. </p>
+ * <p> Returns the set of {@code Provides} objects representing the
+ * services that the module provides. </p>
*
* @return The possibly-empty unmodifiable set of the services that this
* module provides
@@ -1244,7 +1392,7 @@
}
/**
- * Returns this module's version.
+ * <p> Returns the module version. </p>
*
* @return This module's version
*/
@@ -1253,10 +1401,10 @@
}
/**
- * Returns a string containing this module's name and, if present, its
- * version.
+ * <p> Returns a string containing the module name and, if present, its
+ * version. </p>
*
- * @return A string containing this module's name and, if present, its
+ * @return A string containing the module name and, if present, its
* version.
*/
public String toNameAndVersion() {
@@ -1268,51 +1416,51 @@
}
/**
- * Returns the module's main class.
+ * <p> Returns the module main class. </p>
*
- * @return The fully qualified class name of this module's main class
+ * @return The fully qualified class name of the module's main class
*/
public Optional<String> mainClass() {
return Optional.ofNullable(mainClass);
}
/**
- * Returns the operating system name if this module is operating system
+ * Returns the operating system name if the module is operating system
* specific.
*
* @return The operating system name or an empty {@code Optional}
- * if this module is not operating system specific
+ * if the module is not operating system specific
*/
public Optional<String> osName() {
return Optional.ofNullable(osName);
}
/**
- * Returns the operating system architecture if this module is operating
+ * Returns the operating system architecture if the module is operating
* system architecture specific.
*
* @return The operating system architecture or an empty {@code Optional}
- * if this module is not operating system architecture specific
+ * if the module is not operating system architecture specific
*/
public Optional<String> osArch() {
return Optional.ofNullable(osArch);
}
/**
- * Returns the operating system version if this module is operating
+ * Returns the operating system version if the module is operating
* system version specific.
*
* @return The operating system version or an empty {@code Optional}
- * if this module is not operating system version specific
+ * if the module is not operating system version specific
*/
public Optional<String> osVersion() {
return Optional.ofNullable(osVersion);
}
/**
- * Returns the names of all packages in this module.
+ * Returns the set of packages in the module.
*
- * @return A possibly-empty unmodifiable set of all packages in the module
+ * @return A possibly-empty unmodifiable set of the packages in the module
*/
public Set<String> packages() {
return packages;
@@ -1320,37 +1468,53 @@
/**
- * A builder used for building {@link ModuleDescriptor} objects.
+ * A builder for building {@link ModuleDescriptor} objects.
+ *
+ * <p> {@code ModuleDescriptor} defines the {@link #newModule newModule},
+ * {@link #newOpenModule newOpenModule}, and {@link #newAutomaticModule
+ * newAutomaticModule} methods to create builders for building
+ * <em>normal</em>, open, and automatic modules. </p>
*
- * <p> {@code ModuleDescriptor} defines the {@link #module module}, {@link
- * #openModule openModule}, and {@link #automaticModule automaticModule}
- * methods to create builders for building different kinds of modules. </p>
+ * <p> The set of packages in the module are accumulated by the {@code
+ * Builder} as the {@link ModuleDescriptor.Builder#exports(String) exports},
+ * {@link ModuleDescriptor.Builder#opens(String) opens},
+ * {@link ModuleDescriptor.Builder#packages(Set) packages},
+ * {@link ModuleDescriptor.Builder#provides(String,List) provides}, and
+ * {@link ModuleDescriptor.Builder#mainClass(String) mainClass} methods are
+ * invoked. </p>
+ *
+ * <p> The module names, package names, and class names that are parameters
+ * specified to the builder methods are the module names, package names,
+ * and qualified names of classes (in named packages) as defined in the
+ * <cite>The Java™ Language Specification</cite>. </p>
*
* <p> Example usage: </p>
- * <pre>{@code ModuleDescriptor descriptor = ModuleDescriptor.module("m1")
- * .exports("p")
- * .requires("m2")
+ * <pre>{@code ModuleDescriptor descriptor = ModuleDescriptor.newModule("stats.core")
+ * .requires("java.base")
+ * .exports("org.acme.stats.core.clustering")
+ * .exports("org.acme.stats.core.regression")
+ * .packages(Set.of("org.acme.stats.core.internal"))
* .build();
* }</pre>
*
* @apiNote A {@code Builder} checks the components and invariants as
- * components are added to the builder. The rational for this is to detect
+ * components are added to the builder. The rationale for this is to detect
* errors as early as possible and not defer all validation to the
- * {@link #build build} method. A {@code Builder} cannot be used to create
- * a {@link ModuleDescriptor#isSynthetic() synthetic} module.
+ * {@link #build build} method.
*
* @since 9
+ * @spec JPMS
*/
public static final class Builder {
final String name;
- final boolean strict; // true if module names are checked
+ final boolean strict;
+ final Set<Modifier> modifiers;
final boolean open;
- final boolean synthetic;
- boolean automatic;
+ final boolean automatic;
+ final Set<String> packages = new HashSet<>();
final Map<String, Requires> requires = new HashMap<>();
final Map<String, Exports> exports = new HashMap<>();
final Map<String, Opens> opens = new HashMap<>();
- final Set<String> concealedPackages = new HashSet<>();
final Set<String> uses = new HashSet<>();
final Map<String, Provides> provides = new HashMap<>();
Version version;
@@ -1362,35 +1526,25 @@
/**
* Initializes a new builder with the given module name.
*
- * @param strict
- * Indicates whether module names are checked or not
+ * If {@code strict} is {@code true} then module, package, and class
+ * names are checked to ensure they are legal names. In addition, the
+ * {@link #build buid} method will add "{@code requires java.base}" if
+ * the dependency is not declared.
*/
- Builder(String name, boolean strict, boolean open, boolean synthetic) {
+ Builder(String name, boolean strict, Set<Modifier> modifiers) {
this.name = (strict) ? requireModuleName(name) : name;
this.strict = strict;
- this.open = open;
- this.synthetic = synthetic;
- }
-
- /* package */ Builder automatic(boolean automatic) {
- this.automatic = automatic;
- return this;
+ this.modifiers = modifiers;
+ this.open = modifiers.contains(Modifier.OPEN);
+ this.automatic = modifiers.contains(Modifier.AUTOMATIC);
+ assert !open || !automatic;
}
/**
- * Returns the set of packages that are exported (unconditionally or
- * unconditionally).
+ * Returns a snapshot of the packages in the module.
*/
- /* package */ Set<String> exportedPackages() {
- return exports.keySet();
- }
-
- /**
- * Returns the set of packages that are opened (unconditionally or
- * unconditionally).
- */
- /* package */Set<String> openPackages() {
- return opens.keySet();
+ /* package */ Set<String> packages() {
+ return Collections.unmodifiableSet(packages);
}
/**
@@ -1406,8 +1560,12 @@
* initialized to build
* @throws IllegalStateException
* If the dependence on the module has already been declared
+ * or this builder is for an automatic module
*/
public Builder requires(Requires req) {
+ if (automatic)
+ throw new IllegalStateException("Automatic modules cannot declare"
+ + " dependences");
String mn = req.name();
if (name.equals(mn))
throw new IllegalArgumentException("Dependence on self");
@@ -1433,11 +1591,12 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the module name is {@code null}, is not a legal Java
- * identifier, or is equal to the module name that this builder
+ * If the module name is {@code null}, is not a legal module
+ * name, or is equal to the module name that this builder
* was initialized to build
* @throws IllegalStateException
* If the dependence on the module has already been declared
+ * or this builder is for an automatic module
*/
public Builder requires(Set<Requires.Modifier> ms,
String mn,
@@ -1448,6 +1607,23 @@
return requires(new Requires(ms, mn, compiledVersion));
}
+ /* package */Builder requires(Set<Requires.Modifier> ms,
+ String mn,
+ String compiledVersion) {
+ Version v = null;
+ try {
+ v = Version.parse(compiledVersion);
+ } catch (IllegalArgumentException e) {
+ // for now, drop un-parsable version when non-strict
+ if (strict) throw e;
+ }
+ if (v == null) {
+ return requires(ms, mn);
+ } else {
+ return requires(ms, mn, v);
+ }
+ }
+
/**
* Adds a dependence on a module with the given (and possibly empty)
* set of modifiers.
@@ -1460,11 +1636,12 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the module name is {@code null}, is not a legal Java
- * identifier, or is equal to the module name that this builder
+ * If the module name is {@code null}, is not a legal module
+ * name, or is equal to the module name that this builder
* was initialized to build
* @throws IllegalStateException
* If the dependence on the module has already been declared
+ * or this builder is for an automatic module
*/
public Builder requires(Set<Requires.Modifier> ms, String mn) {
if (strict)
@@ -1481,18 +1658,19 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the module name is {@code null}, is not a legal Java
- * identifier, or is equal to the module name that this builder
+ * If the module name is {@code null}, is not a legal module
+ * name, or is equal to the module name that this builder
* was initialized to build
* @throws IllegalStateException
* If the dependence on the module has already been declared
+ * or this builder is for an automatic module
*/
public Builder requires(String mn) {
return requires(EnumSet.noneOf(Requires.Modifier.class), mn);
}
/**
- * Adds an export.
+ * Adds an exported package.
*
* @param e
* The export
@@ -1500,29 +1678,27 @@
* @return This builder
*
* @throws IllegalStateException
- * If the package is already declared as a package with the
- * {@link #contains contains} method or the package is already
- * declared as exported
+ * If the {@link Exports#source package} is already declared as
+ * exported or this builder is for an automatic module
*/
public Builder exports(Exports e) {
- // can't be exported and concealed
+ if (automatic) {
+ throw new IllegalStateException("Automatic modules cannot declare"
+ + " exported packages");
+ }
String source = e.source();
- if (concealedPackages.contains(source)) {
- throw new IllegalStateException("Package " + source
- + " already declared");
- }
if (exports.containsKey(source)) {
throw new IllegalStateException("Exported package " + source
+ " already declared");
}
-
exports.put(source, e);
+ packages.add(source);
return this;
}
/**
- * Adds an export, with the given (and possibly empty) set of modifiers,
- * to export a package to a set of target modules.
+ * Adds an exported package with the given (and possibly empty) set of
+ * modifiers. The package is exported to a set of target modules.
*
* @param ms
* The set of modifiers
@@ -1534,33 +1710,34 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the package name or any of the target modules is {@code
- * null} or is not a legal Java identifier, or the set of
- * targets is empty
+ * If the package name is {@code null} or is not a legal
+ * package name, the set of target modules is empty, or the set
+ * of target modules contains a name that is not a legal module
+ * name
* @throws IllegalStateException
- * If the package is already declared as a package with the
- * {@link #contains contains} method or the package is already
- * declared as exported
+ * If the package is already declared as exported
+ * or this builder is for an automatic module
*/
public Builder exports(Set<Exports.Modifier> ms,
String pn,
Set<String> targets)
{
- Exports e = new Exports(ms, requirePackageName(pn), targets);
+ Exports e = new Exports(ms, pn, targets);
// check targets
targets = e.targets();
if (targets.isEmpty())
throw new IllegalArgumentException("Empty target set");
- if (strict)
+ if (strict) {
+ requirePackageName(e.source());
targets.stream().forEach(Checks::requireModuleName);
-
+ }
return exports(e);
}
/**
- * Adds an unqualified export with the given (and possibly empty) set
- * of modifiers.
+ * Adds an exported package with the given (and possibly empty) set of
+ * modifiers. The package is exported to all modules.
*
* @param ms
* The set of modifiers
@@ -1570,20 +1747,23 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the package name is {@code null} or is not a legal Java
- * identifier
+ * If the package name is {@code null} or is not a legal
+ * package name
* @throws IllegalStateException
- * If the package is already declared as a package with the
- * {@link #contains contains} method or the package is already
- * declared as exported
+ * If the package is already declared as exported
+ * or this builder is for an automatic module
*/
public Builder exports(Set<Exports.Modifier> ms, String pn) {
- Exports e = new Exports(ms, requirePackageName(pn), Collections.emptySet());
+ if (strict) {
+ requirePackageName(pn);
+ }
+ Exports e = new Exports(ms, pn, Collections.emptySet());
return exports(e);
}
/**
- * Adds an export to export a package to a set of target modules.
+ * Adds an exported package. The package is exported to a set of target
+ * modules.
*
* @param pn
* The package name
@@ -1593,20 +1773,20 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the package name or any of the target modules is {@code
- * null} or is not a legal Java identifier, or the set of
- * targets is empty
+ * If the package name is {@code null} or is not a legal
+ * package name, the set of target modules is empty, or the set
+ * of target modules contains a name that is not a legal module
+ * name
* @throws IllegalStateException
- * If the package is already declared as a package with the
- * {@link #contains contains} method or the package is already
- * declared as exported
+ * If the package is already declared as exported
+ * or this builder is for an automatic module
*/
public Builder exports(String pn, Set<String> targets) {
return exports(Collections.emptySet(), pn, targets);
}
/**
- * Adds an unqualified export.
+ * Adds an exported package. The package is exported to all modules.
*
* @param pn
* The package name
@@ -1614,19 +1794,18 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the package name is {@code null} or is not a legal Java
- * identifier
+ * If the package name is {@code null} or is not a legal
+ * package name
* @throws IllegalStateException
- * If the package is already declared as a package with the
- * {@link #contains contains} method or the package is already
- * declared as exported
+ * If the package is already declared as exported
+ * or this builder is for an automatic module
*/
public Builder exports(String pn) {
return exports(Collections.emptySet(), pn);
}
/**
- * Adds an <em>opens</em> directive.
+ * Adds an open package.
*
* @param obj
* The {@code Opens} object
@@ -1634,35 +1813,28 @@
* @return This builder
*
* @throws IllegalStateException
- * If the package is already declared as a package with the
- * {@link #contains contains} method, the package is already
- * declared as open, or this is a builder for an open module
+ * If the package is already declared as open, or this is a
+ * builder for an open module or automatic module
*/
public Builder opens(Opens obj) {
- if (open) {
- throw new IllegalStateException("open modules cannot declare"
- + " open packages");
+ if (open || automatic) {
+ throw new IllegalStateException("Open or automatic modules cannot"
+ + " declare open packages");
}
-
- // can't be open and concealed
String source = obj.source();
- if (concealedPackages.contains(source)) {
- throw new IllegalStateException("Package " + source
- + " already declared");
- }
if (opens.containsKey(source)) {
throw new IllegalStateException("Open package " + source
+ " already declared");
}
-
opens.put(source, obj);
+ packages.add(source);
return this;
}
/**
- * Adds an <em>opens</em> directive, with the given (and possibly empty)
- * set of modifiers, to open a package to a set of target modules.
+ * Adds an open package with the given (and possibly empty) set of
+ * modifiers. The package is open to a set of target modules.
*
* @param ms
* The set of modifiers
@@ -1674,33 +1846,34 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the package name or any of the target modules is {@code
- * null} or is not a legal Java identifier, or the set of
- * targets is empty
+ * If the package name is {@code null} or is not a legal
+ * package name, the set of target modules is empty, or the set
+ * of target modules contains a name that is not a legal module
+ * name
* @throws IllegalStateException
- * If the package is already declared as a package with the
- * {@link #contains contains} method, the package is already
- * declared as open, or this is a builder for an open module
+ * If the package is already declared as open, or this is a
+ * builder for an open module or automatic module
*/
public Builder opens(Set<Opens.Modifier> ms,
String pn,
Set<String> targets)
{
- Opens e = new Opens(ms, requirePackageName(pn), targets);
+ Opens opens = new Opens(ms, pn, targets);
// check targets
- targets = e.targets();
+ targets = opens.targets();
if (targets.isEmpty())
throw new IllegalArgumentException("Empty target set");
- if (strict)
+ if (strict) {
+ requirePackageName(opens.source());
targets.stream().forEach(Checks::requireModuleName);
-
- return opens(e);
+ }
+ return opens(opens);
}
/**
- * Adds an <em>opens</em> directive to open a package with the given (and
- * possibly empty) set of modifiers.
+ * Adds an open package with the given (and possibly empty) set of
+ * modifiers. The package is open to all modules.
*
* @param ms
* The set of modifiers
@@ -1710,21 +1883,22 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the package name is {@code null} or is not a legal Java
- * identifier
+ * If the package name is {@code null} or is not a legal
+ * package name
* @throws IllegalStateException
- * If the package is already declared as a package with the
- * {@link #contains contains} method, the package is already
- * declared as open, or this is a builder for an open module
+ * If the package is already declared as open, or this is a
+ * builder for an open module or automatic module
*/
public Builder opens(Set<Opens.Modifier> ms, String pn) {
- Opens e = new Opens(ms, requirePackageName(pn), Collections.emptySet());
+ if (strict) {
+ requirePackageName(pn);
+ }
+ Opens e = new Opens(ms, pn, Collections.emptySet());
return opens(e);
}
/**
- * Adds an <em>opens</em> directive to open a package to a set of target
- * modules.
+ * Adds an open package. The package is open to a set of target modules.
*
* @param pn
* The package name
@@ -1734,20 +1908,20 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the package name or any of the target modules is {@code
- * null} or is not a legal Java identifier, or the set of
- * targets is empty
+ * If the package name is {@code null} or is not a legal
+ * package name, the set of target modules is empty, or the set
+ * of target modules contains a name that is not a legal module
+ * name
* @throws IllegalStateException
- * If the package is already declared as a package with the
- * {@link #contains contains} method, the package is already
- * declared as open, or this is a builder for an open module
+ * If the package is already declared as open, or this is a
+ * builder for an open module or automatic module
*/
public Builder opens(String pn, Set<String> targets) {
return opens(Collections.emptySet(), pn, targets);
}
/**
- * Adds an <em>opens</em> directive to open a package.
+ * Adds an open package. The package is open to all modules.
*
* @param pn
* The package name
@@ -1755,12 +1929,11 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the package name is {@code null} or is not a legal Java
- * identifier
+ * If the package name is {@code null} or is not a legal
+ * package name
* @throws IllegalStateException
- * If the package is already declared as a package with the
- * {@link #contains contains} method, the package is already
- * declared as open, or this is a builder for an open module
+ * If the package is already declared as open, or this is a
+ * builder for an open module or automatic module
*/
public Builder opens(String pn) {
return opens(Collections.emptySet(), pn);
@@ -1775,12 +1948,16 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If the service type is {@code null} or is not a legal Java
- * identifier
+ * If the service type is {@code null} or not a qualified name of
+ * a class in a named package
* @throws IllegalStateException
* If a dependency on the service type has already been declared
+ * or this is a builder for an an automatic module
*/
public Builder uses(String service) {
+ if (automatic)
+ throw new IllegalStateException("Automatic modules can not declare"
+ + " service dependences");
if (uses.contains(requireServiceTypeName(service)))
throw new IllegalStateException("Dependence upon service "
+ service + " already declared");
@@ -1789,7 +1966,9 @@
}
/**
- * Provides a service with one or more implementations.
+ * Provides a service with one or more implementations. The package for
+ * each {@link Provides#providers provider} (or provider factory) is
+ * added to the module if not already added.
*
* @param p
* The provides
@@ -1801,16 +1980,18 @@
* declared
*/
public Builder provides(Provides p) {
- String st = p.service();
- if (provides.containsKey(st))
+ String service = p.service();
+ if (provides.containsKey(service))
throw new IllegalStateException("Providers of service "
- + st + " already declared");
- provides.put(st, p);
+ + service + " already declared");
+ provides.put(service, p);
+ p.providers().forEach(name -> packages.add(packageName(name)));
return this;
}
/**
- * Provides implementations of a service.
+ * Provides implementations of a service. The package for each provider
+ * (or provider factory) is added to the module if not already added.
*
* @param service
* The service type
@@ -1821,103 +2002,59 @@
*
* @throws IllegalArgumentException
* If the service type or any of the provider class names is
- * {@code null} or is not a legal Java identifier, or the list
- * of provider class names is empty
+ * {@code null} or not a qualified name of a class in a named
+ * package, or the list of provider class names is empty
* @throws IllegalStateException
* If the providers for the service type have already been
* declared
*/
public Builder provides(String service, List<String> providers) {
- if (provides.containsKey(service))
- throw new IllegalStateException("Providers of service "
- + service + " already declared by " + name);
-
- Provides p = new Provides(requireServiceTypeName(service), providers);
+ Provides p = new Provides(service, providers);
// check providers after the set has been copied.
List<String> providerNames = p.providers();
if (providerNames.isEmpty())
throw new IllegalArgumentException("Empty providers set");
- providerNames.forEach(Checks::requireServiceProviderName);
- provides.put(service, p);
- return this;
+ if (strict) {
+ requireServiceTypeName(p.service());
+ providerNames.forEach(Checks::requireServiceProviderName);
+ } else {
+ // Disallow service/providers in unnamed package
+ String pn = packageName(service);
+ if (pn.isEmpty()) {
+ throw new IllegalArgumentException(service
+ + ": unnamed package");
+ }
+ for (String name : providerNames) {
+ pn = packageName(name);
+ if (pn.isEmpty()) {
+ throw new IllegalArgumentException(name
+ + ": unnamed package");
+ }
+ }
+ }
+ return provides(p);
}
/**
- * Provides an implementation of a service.
- *
- * @param service
- * The service type
- * @param provider
- * The provider or provider factory class name
- *
- * @return This builder
- *
- * @throws IllegalArgumentException
- * If the service type or the provider class name is {@code
- * null} or is not a legal Java identifier
- * @throws IllegalStateException
- * If the providers for the service type have already been
- * declared
- */
- public Builder provides(String service, String provider) {
- if (provider == null)
- throw new IllegalArgumentException("'provider' is null");
- return provides(service, List.of(provider));
- }
-
- /**
- * Adds a (possible empty) set of packages to the module
+ * Adds packages to the module. All packages in the set of package names
+ * that are not in the module are added to module.
*
* @param pns
- * The set of package names
+ * The (possibly empty) set of package names
*
* @return This builder
*
* @throws IllegalArgumentException
* If any of the package names is {@code null} or is not a
- * legal Java identifier
- * @throws IllegalStateException
- * If any of packages are already declared as packages in
- * the module. This includes packages that are already
- * declared as exported or open packages.
+ * legal package name
*/
- public Builder contains(Set<String> pns) {
- pns.forEach(this::contains);
- return this;
- }
-
- /**
- * Adds a package to the module.
- *
- * @param pn
- * The package name
- *
- * @return This builder
- *
- * @throws IllegalArgumentException
- * If the package name is {@code null}, or is not a legal Java
- * identifier
- * @throws IllegalStateException
- * If the package is already declared as a package in the
- * module. This includes the package already declared as an
- * exported or open package.
- */
- public Builder contains(String pn) {
- Checks.requirePackageName(pn);
- if (concealedPackages.contains(pn)) {
- throw new IllegalStateException("Package " + pn
- + " already declared");
+ public Builder packages(Set<String> pns) {
+ if (strict) {
+ pns = new HashSet<>(pns);
+ pns.forEach(Checks::requirePackageName);
}
- if (exports.containsKey(pn)) {
- throw new IllegalStateException("Exported package "
- + pn + " already declared");
- }
- if (opens.containsKey(pn)) {
- throw new IllegalStateException("Open package "
- + pn + " already declared");
- }
- concealedPackages.add(pn);
+ this.packages.addAll(pns);
return this;
}
@@ -1937,22 +2074,35 @@
/**
* Sets the module version.
*
- * @param v
+ * @param vs
* The version string to parse
*
* @return This builder
*
* @throws IllegalArgumentException
- * If {@code v} is null or cannot be parsed as a version string
+ * If {@code vs} is {@code null} or cannot be parsed as a
+ * version string
*
* @see Version#parse(String)
*/
- public Builder version(String v) {
- return version(Version.parse(v));
+ public Builder version(String vs) {
+ Version v;
+ if (strict) {
+ v = Version.parse(vs);
+ } else {
+ try {
+ v = Version.parse(vs);
+ } catch (IllegalArgumentException ignore) {
+ // for now, ignore when non-strict
+ return this;
+ }
+ }
+ return version(v);
}
/**
- * Sets the module main class.
+ * Sets the module main class. The package for the main class is added
+ * to the module if not already added.
*
* @param mc
* The module main class
@@ -1960,10 +2110,24 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If {@code mainClass} is null or is not a legal Java identifier
+ * If {@code mainClass} is {@code null} or not a qualified
+ * name of a class in a named package
*/
public Builder mainClass(String mc) {
- mainClass = requireBinaryName("main class name", mc);
+ String pn;
+ if (strict) {
+ mc = requireQualifiedClassName("main class name", mc);
+ pn = packageName(mc);
+ assert !pn.isEmpty();
+ } else {
+ // Disallow main class in unnamed package
+ pn = packageName(mc);
+ if (pn.isEmpty()) {
+ throw new IllegalArgumentException(mc + ": unnamed package");
+ }
+ }
+ mainClass = mc;
+ packages.add(pn);
return this;
}
@@ -1976,7 +2140,7 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If {@code name} is null or the empty String
+ * If {@code name} is {@code null} or the empty String
*/
public Builder osName(String name) {
if (name == null || name.isEmpty())
@@ -1994,7 +2158,7 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If {@code name} is null or the empty String
+ * If {@code name} is {@code null} or the empty String
*/
public Builder osArch(String arch) {
if (arch == null || arch.isEmpty())
@@ -2012,7 +2176,7 @@
* @return This builder
*
* @throws IllegalArgumentException
- * If {@code name} is null or the empty String
+ * If {@code name} is {@code null} or the empty String
*/
public Builder osVersion(String version) {
if (version == null || version.isEmpty())
@@ -2024,26 +2188,34 @@
/**
* Builds and returns a {@code ModuleDescriptor} from its components.
*
+ * <p> The module will require "{@code java.base}" even if the dependence
+ * has not been declared (the exception is when building a module named
+ * "{@code java.base}" as it cannot require itself). The dependence on
+ * "{@code java.base}" will have the {@link
+ * java.lang.module.ModuleDescriptor.Requires.Modifier#MANDATED MANDATED}
+ * modifier if the dependence was not declared. </p>
+ *
* @return The module descriptor
*/
public ModuleDescriptor build() {
Set<Requires> requires = new HashSet<>(this.requires.values());
-
- Set<String> packages = new HashSet<>();
- packages.addAll(exports.keySet());
- packages.addAll(opens.keySet());
- packages.addAll(concealedPackages);
-
Set<Exports> exports = new HashSet<>(this.exports.values());
Set<Opens> opens = new HashSet<>(this.opens.values());
+ // add dependency on java.base
+ if (strict
+ && !name.equals("java.base")
+ && !this.requires.containsKey("java.base")) {
+ requires.add(new Requires(Set.of(Requires.Modifier.MANDATED),
+ "java.base",
+ null));
+ }
+
Set<Provides> provides = new HashSet<>(this.provides.values());
return new ModuleDescriptor(name,
version,
- open,
- automatic,
- synthetic,
+ modifiers,
requires,
exports,
opens,
@@ -2062,16 +2234,20 @@
* Compares this module descriptor to another.
*
* <p> Two {@code ModuleDescriptor} objects are compared by comparing their
- * module name lexicographically. Where the module names are equal then
- * the versions, if present, are compared. </p>
- *
- * @apiNote For now, the natural ordering is not consistent with equals.
- * If two module descriptors have equal module names, equal versions if
- * present, but their corresponding components are not equal, then they
- * will be considered equal by this method.
+ * module names lexicographically. Where the module names are equal then the
+ * module versions are compared. When comparing the module versions then a
+ * module descriptor with a version is considered to succeed a module
+ * descriptor that does not have a version. Where the module names are equal
+ * and the versions are equal (or not present in both), then the set of
+ * modifiers are compared. Sets of modifiers are compared by comparing
+ * a <em>binary value</em> computed for each set. If a modifier is present
+ * in the set then the bit at the position of its ordinal is {@code 1}
+ * in the binary value, otherwise {@code 0}. If the two set of modifiers
+ * are also equal then the other components of the module descriptors are
+ * compared in a manner that is consistent with {@code equals}. </p>
*
* @param that
- * The object to which this module descriptor is to be compared
+ * The module descriptor to compare
*
* @return A negative integer, zero, or a positive integer if this module
* descriptor is less than, equal to, or greater than the given
@@ -2079,16 +2255,50 @@
*/
@Override
public int compareTo(ModuleDescriptor that) {
+ if (this == that) return 0;
+
int c = this.name().compareTo(that.name());
if (c != 0) return c;
- if (version == null) {
- if (that.version == null)
- return 0;
- return -1;
- }
- if (that.version == null)
- return +1;
- return version.compareTo(that.version);
+
+ c = compare(this.version, that.version);
+ if (c != 0) return c;
+
+ long v1 = modsValue(this.modifiers());
+ long v2 = modsValue(that.modifiers());
+ c = Long.compare(v1, v2);
+ if (c != 0) return c;
+
+ c = compare(this.requires, that.requires);
+ if (c != 0) return c;
+
+ c = compare(this.packages, that.packages);
+ if (c != 0) return c;
+
+ c = compare(this.exports, that.exports);
+ if (c != 0) return c;
+
+ c = compare(this.opens, that.opens);
+ if (c != 0) return c;
+
+ c = compare(this.uses, that.uses);
+ if (c != 0) return c;
+
+ c = compare(this.provides, that.provides);
+ if (c != 0) return c;
+
+ c = compare(this.mainClass, that.mainClass);
+ if (c != 0) return c;
+
+ c = compare(this.osName, that.osName);
+ if (c != 0) return c;
+
+ c = compare(this.osArch, that.osArch);
+ if (c != 0) return c;
+
+ c = compare(this.osVersion, that.osVersion);
+ if (c != 0) return c;
+
+ return 0;
}
/**
@@ -2115,10 +2325,9 @@
return false;
ModuleDescriptor that = (ModuleDescriptor)ob;
return (name.equals(that.name)
- && open == that.open
- && automatic == that.automatic
- && synthetic == that.synthetic
+ && modifiers.equals(that.modifiers)
&& requires.equals(that.requires)
+ && Objects.equals(packages, that.packages)
&& exports.equals(that.exports)
&& opens.equals(that.opens)
&& uses.equals(that.uses)
@@ -2127,12 +2336,9 @@
&& Objects.equals(mainClass, that.mainClass)
&& Objects.equals(osName, that.osName)
&& Objects.equals(osArch, that.osArch)
- && Objects.equals(osVersion, that.osVersion)
- && Objects.equals(packages, that.packages));
+ && Objects.equals(osVersion, that.osVersion));
}
- private transient int hash; // cached hash code
-
/**
* Computes a hash code for this module descriptor.
*
@@ -2147,10 +2353,9 @@
int hc = hash;
if (hc == 0) {
hc = name.hashCode();
- hc = hc * 43 + Boolean.hashCode(open);
- hc = hc * 43 + Boolean.hashCode(automatic);
- hc = hc * 43 + Boolean.hashCode(synthetic);
+ hc = hc * 43 + Objects.hashCode(modifiers);
hc = hc * 43 + requires.hashCode();
+ hc = hc * 43 + Objects.hashCode(packages);
hc = hc * 43 + exports.hashCode();
hc = hc * 43 + opens.hashCode();
hc = hc * 43 + uses.hashCode();
@@ -2160,18 +2365,18 @@
hc = hc * 43 + Objects.hashCode(osName);
hc = hc * 43 + Objects.hashCode(osArch);
hc = hc * 43 + Objects.hashCode(osVersion);
- hc = hc * 43 + Objects.hashCode(packages);
if (hc == 0)
hc = -1;
hash = hc;
}
return hc;
}
+ private transient int hash; // cached hash code
/**
- * Returns a string describing this descriptor.
+ * <p> Returns a string describing the module. </p>
*
- * @return A string describing this descriptor
+ * @return A string describing the module
*/
@Override
public String toString() {
@@ -2201,31 +2406,50 @@
*
* @param name
* The module name
+ * @param ms
+ * The set of module modifiers
*
* @return A new builder
*
* @throws IllegalArgumentException
- * If the module name is {@code null} or is not a legal Java
- * identifier
+ * If the module name is {@code null} or is not a legal module
+ * name, or the set of modifiers contains {@link
+ * Modifier#AUTOMATIC AUTOMATIC} with other modifiers
*/
- public static Builder module(String name) {
- return new Builder(name, true, false, false);
+ public static Builder newModule(String name, Set<Modifier> ms) {
+ Set<Modifier> mods = new HashSet<>(ms);
+ if (mods.contains(Modifier.AUTOMATIC) && mods.size() > 1)
+ throw new IllegalArgumentException("AUTOMATIC cannot be used with"
+ + " other modifiers");
+
+ return new Builder(name, true, mods);
+ }
+
+ /**
+ * Instantiates a builder to build a module descriptor for a <em>normal</em>
+ * module. This method is equivalent to invoking {@link #newModule(String,Set)
+ * newModule} with an empty set of {@link ModuleDescriptor.Modifier modifiers}.
+ *
+ * @param name
+ * The module name
+ *
+ * @return A new builder
+ *
+ * @throws IllegalArgumentException
+ * If the module name is {@code null} or is not a legal module
+ * name
+ */
+ public static Builder newModule(String name) {
+ return new Builder(name, true, Set.of());
}
/**
* Instantiates a builder to build a module descriptor for an open module.
- * An open module does not declare any open packages but the resulting
- * module is treated as if all packages are open.
+ * This method is equivalent to invoking {@link #newModule(String,Set)
+ * newModule} with the {@link ModuleDescriptor.Modifier#OPEN OPEN} modifier.
*
- * <p> As an example, the following creates a module descriptor for an open
- * name "{@code m}" containing two packages, one of which is exported. </p>
- * <pre>{@code
- * ModuleDescriptor descriptor = ModuleDescriptor.openModule("m")
- * .requires("java.base")
- * .exports("p")
- * .contains("q")
- * .build();
- * }</pre>
+ * <p> The builder for an open module cannot be used to declare any open
+ * packages. </p>
*
* @param name
* The module name
@@ -2233,19 +2457,22 @@
* @return A new builder that builds an open module
*
* @throws IllegalArgumentException
- * If the module name is {@code null} or is not a legal Java
- * identifier
+ * If the module name is {@code null} or is not a legal module
+ * name
*/
- public static Builder openModule(String name) {
- return new Builder(name, true, true, false);
+ public static Builder newOpenModule(String name) {
+ return new Builder(name, true, Set.of(Modifier.OPEN));
}
/**
* Instantiates a builder to build a module descriptor for an automatic
- * module. Automatic modules receive special treatment during resolution
- * (see {@link Configuration}) so that they read all other modules. When
- * Instantiated in the Java virtual machine as a {@link java.lang.reflect.Module}
- * then the Module reads every unnamed module in the Java virtual machine.
+ * module. This method is equivalent to invoking {@link #newModule(String,Set)
+ * newModule} with the {@link ModuleDescriptor.Modifier#AUTOMATIC AUTOMATIC}
+ * modifier.
+ *
+ * <p> The builder for an automatic module cannot be used to declare module
+ * or service dependences. It also cannot be used to declare any exported
+ * or open packages. </p>
*
* @param name
* The module name
@@ -2253,13 +2480,13 @@
* @return A new builder that builds an automatic module
*
* @throws IllegalArgumentException
- * If the module name is {@code null} or is not a legal Java
- * identifier
+ * If the module name is {@code null} or is not a legal module
+ * name
*
* @see ModuleFinder#of(Path[])
*/
- public static Builder automaticModule(String name) {
- return new Builder(name, true, false, false).automatic(true);
+ public static Builder newAutomaticModule(String name) {
+ return new Builder(name, true, Set.of(Modifier.AUTOMATIC));
}
@@ -2269,8 +2496,12 @@
*
* <p> If the descriptor encoded in the input stream does not indicate a
* set of packages in the module then the {@code packageFinder} will be
- * invoked. If the {@code packageFinder} throws an {@link UncheckedIOException}
- * then {@link IOException} cause will be re-thrown. </p>
+ * invoked. The set of packages that the {@code packageFinder} returns
+ * must include all the packages that the module exports, opens, as well
+ * as the packages of the service implementations that the module provides,
+ * and the package of the main class (if the module has a main class). If
+ * the {@code packageFinder} throws an {@link UncheckedIOException} then
+ * {@link IOException} cause will be re-thrown. </p>
*
* <p> If there are bytes following the module descriptor then it is
* implementation specific as to whether those bytes are read, ignored,
@@ -2292,7 +2523,9 @@
* @return The module descriptor
*
* @throws InvalidModuleDescriptorException
- * If an invalid module descriptor is detected
+ * If an invalid module descriptor is detected or the set of
+ * packages returned by the {@code packageFinder} does not include
+ * all of the packages obtained from the module descriptor
* @throws IOException
* If an I/O error occurs reading from the input stream or {@code
* UncheckedIOException} is thrown by the package finder
@@ -2305,8 +2538,12 @@
}
/**
- * Reads the binary form of a module declaration from an input stream
- * as a module descriptor.
+ * Reads the binary form of a module declaration from an input stream as a
+ * module descriptor. This method works exactly as specified by the 2-arg
+ * {@link #read(InputStream,Supplier) read} method with the exception that
+ * a packager finder is not used to find additional packages when the
+ * module descriptor read from the stream does not indicate the set of
+ * packages.
*
* @param in
* The input stream
@@ -2327,7 +2564,13 @@
* as a module descriptor.
*
* <p> If the descriptor encoded in the byte buffer does not indicate a
- * set of packages then the {@code packageFinder} will be invoked. </p>
+ * set of packages in the module then the {@code packageFinder} will be
+ * invoked. The set of packages that the {@code packageFinder} returns
+ * must include all the packages that the module exports, opens, as well
+ * as the packages of the service implementations that the module provides,
+ * and the package of the main class (if the module has a main class). If
+ * the {@code packageFinder} throws an {@link UncheckedIOException} then
+ * {@link IOException} cause will be re-thrown. </p>
*
* <p> The module descriptor is read from the buffer stating at index
* {@code p}, where {@code p} is the buffer's {@link ByteBuffer#position()
@@ -2353,7 +2596,9 @@
* @return The module descriptor
*
* @throws InvalidModuleDescriptorException
- * If an invalid module descriptor is detected
+ * If an invalid module descriptor is detected or the set of
+ * packages returned by the {@code packageFinder} does not include
+ * all of the packages obtained from the module descriptor
*/
public static ModuleDescriptor read(ByteBuffer bb,
Supplier<Set<String>> packageFinder)
@@ -2362,8 +2607,11 @@
}
/**
- * Reads the binary form of a module declaration from a byte buffer
- * as a module descriptor.
+ * Reads the binary form of a module declaration from a byte buffer as a
+ * module descriptor. This method works exactly as specified by the 2-arg
+ * {@link #read(ByteBuffer,Supplier) read} method with the exception that a
+ * packager finder is not used to find additional packages when the module
+ * descriptor encoded in the buffer does not indicate the set of packages.
*
* @param bb
* The byte buffer
@@ -2398,6 +2646,11 @@
}
}
+ private static String packageName(String cn) {
+ int index = cn.lastIndexOf('.');
+ return (index == -1) ? "" : cn.substring(0, index);
+ }
+
/**
* Returns a string containing the given set of modifiers and label.
*/
@@ -2407,6 +2660,36 @@
.collect(Collectors.joining(" "));
}
+ private static <T extends Object & Comparable<? super T>>
+ int compare(T obj1, T obj2) {
+ if (obj1 != null) {
+ return (obj2 != null) ? obj1.compareTo(obj2) : 1;
+ } else {
+ return (obj2 == null) ? 0 : -1;
+ }
+ }
+
+ /**
+ * Compares two sets of {@code Comparable} objects.
+ */
+ @SuppressWarnings("unchecked")
+ private static <T extends Object & Comparable<? super T>>
+ int compare(Set<T> s1, Set<T> s2) {
+ T[] a1 = (T[]) s1.toArray();
+ T[] a2 = (T[]) s2.toArray();
+ Arrays.sort(a1);
+ Arrays.sort(a2);
+ return Arrays.compare(a1, a2);
+ }
+
+ private static <E extends Enum<E>> long modsValue(Set<E> set) {
+ long value = 0;
+ for (Enum<E> e : set) {
+ value += 1 << e.ordinal();
+ }
+ return value;
+ }
+
static {
/**
* Setup the shared secret to allow code in other packages access
@@ -2417,19 +2700,21 @@
@Override
public Builder newModuleBuilder(String mn,
boolean strict,
- boolean open,
- boolean synthetic) {
- return new Builder(mn, strict, open, synthetic);
+ Set<ModuleDescriptor.Modifier> modifiers) {
+ return new Builder(mn, strict, modifiers);
}
@Override
- public Set<String> exportedPackages(ModuleDescriptor.Builder builder) {
- return builder.exportedPackages();
+ public Set<String> packages(ModuleDescriptor.Builder builder) {
+ return builder.packages();
}
@Override
- public Set<String> openPackages(ModuleDescriptor.Builder builder) {
- return builder.openPackages();
+ public void requires(ModuleDescriptor.Builder builder,
+ Set<Requires.Modifier> ms,
+ String mn,
+ String compiledVersion) {
+ builder.requires(ms, mn, compiledVersion);
}
@Override
@@ -2467,22 +2752,9 @@
}
@Override
- public Version newVersion(String v) {
- return new Version(v);
- }
-
- @Override
- public ModuleDescriptor newModuleDescriptor(ModuleDescriptor md,
- Set<String> pkgs) {
- return new ModuleDescriptor(md, pkgs);
- }
-
- @Override
public ModuleDescriptor newModuleDescriptor(String name,
Version version,
- boolean open,
- boolean automatic,
- boolean synthetic,
+ Set<ModuleDescriptor.Modifier> modifiers,
Set<Requires> requires,
Set<Exports> exports,
Set<Opens> opens,
@@ -2496,9 +2768,7 @@
int hashCode) {
return new ModuleDescriptor(name,
version,
- open,
- automatic,
- synthetic,
+ modifiers,
requires,
exports,
opens,
@@ -2514,12 +2784,12 @@
}
@Override
- public Configuration resolveRequiresAndUses(ModuleFinder finder,
- Collection<String> roots,
- boolean check,
- PrintStream traceOutput)
+ public Configuration resolveAndBind(ModuleFinder finder,
+ Collection<String> roots,
+ boolean check,
+ PrintStream traceOutput)
{
- return Configuration.resolveRequiresAndUses(finder, roots, check, traceOutput);
+ return Configuration.resolveAndBind(finder, roots, check, traceOutput);
}
});
}
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleFinder.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,14 +42,15 @@
import java.util.Optional;
import java.util.Set;
+import jdk.internal.module.ModuleBootstrap;
import jdk.internal.module.ModulePath;
import jdk.internal.module.SystemModuleFinder;
import sun.security.action.GetPropertyAction;
/**
* A finder of modules. A {@code ModuleFinder} is used to find modules during
- * <a href="Configuration.html#resolution">resolution</a> or
- * <a href="Configuration.html#servicebinding">service binding</a>.
+ * <a href="package-summary.html#resolution">resolution</a> or
+ * <a href="package-summary.html#servicebinding">service binding</a>.
*
* <p> A {@code ModuleFinder} can only find one module with a given name. A
* {@code ModuleFinder} that finds modules in a sequence of directories, for
@@ -85,6 +86,7 @@
* <p> A {@code ModuleFinder} is not required to be thread safe. </p>
*
* @since 9
+ * @spec JPMS
*/
public interface ModuleFinder {
@@ -124,8 +126,8 @@
* to find that module. </p>
*
* @apiNote This is important to have for methods such as {@link
- * Configuration#resolveRequiresAndUses resolveRequiresAndUses} that need
- * to scan the module path to find modules that provide a specific service.
+ * Configuration#resolveAndBind resolveAndBind} that need to scan the
+ * module path to find modules that provide a specific service.
*
* @return The set of all module references that this finder locates
*
@@ -172,7 +174,8 @@
} else {
Path mlib = Paths.get(home, "modules");
if (Files.isDirectory(mlib)) {
- return of(mlib);
+ // exploded build may be patched
+ return ModulePath.of(ModuleBootstrap.patcher(), mlib);
} else {
throw new InternalError("Unable to detect the run-time image");
}
@@ -198,13 +201,9 @@
*
* <p> If an element is a path to a directory of modules then each entry in
* the directory is a packaged module or the top-level directory of an
- * exploded module. The module finder's {@link #find(String) find} or
- * {@link #findAll() findAll} methods throw {@link FindException} if a
- * directory containing more than one module with the same name is
- * encountered. </p>
- *
- * <p> If an element in the array is a path to a directory, and that
- * directory contains a file named {@code module-info.class}, then the
+ * exploded module. It it an error if a directory contains more than one
+ * module with the same name. If an element is a path to a directory, and
+ * that directory contains a file named {@code module-info.class}, then the
* directory is treated as an exploded module rather than a directory of
* modules. </p>
*
@@ -214,9 +213,8 @@
* entry in a {@link java.util.jar.JarFile#isMultiRelease() multi-release}
* JAR file) is a modular JAR and is an <em>explicit module</em>.
* A JAR file that does not have a {@code module-info.class} in the
- * top-level directory is an {@link ModuleDescriptor#isAutomatic automatic}
- * module. The {@link ModuleDescriptor} for an automatic module is created as
- * follows:
+ * top-level directory is created as an automatic module. The components
+ * for the automatic module are derived as follows:
*
* <ul>
*
@@ -248,46 +246,48 @@
*
* </ul></li>
*
- * <li><p> It {@link ModuleDescriptor#requires() requires} {@code
- * java.base}. </p></li>
- *
- * <li><p> The set of packages in the module is derived from the names
- * of non-directory entries in the JAR file. A candidate package name
- * is derived from an entry using the characters up to, but not
- * including, the last forward slash. All remaining forward slashes are
- * replaced with dot ({@code "."}). If the resulting string is a valid
- * Java identifier then it is assumed to be a package name. For example,
- * if the JAR file contains an entry "{@code p/q/Foo.class}" then the
- * package name derived is "{@code p.q}". All packages are {@link
- * ModuleDescriptor#exports() exported}. </p></li>
+ * <li><p> The set of packages in the module is derived from the
+ * non-directory entries in the JAR file that have names ending in
+ * "{@code .class}". A candidate package name is derived from the name
+ * using the characters up to, but not including, the last forward slash.
+ * All remaining forward slashes are replaced with dot ({@code "."}). If
+ * the resulting string is a legal package name then it is assumed to be
+ * a package name. For example, if the JAR file contains the entry
+ * "{@code p/q/Foo.class}" then the package name derived is
+ * "{@code p.q}".</p></li>
*
* <li><p> The contents of entries starting with {@code
* META-INF/services/} are assumed to be service configuration files
* (see {@link java.util.ServiceLoader}). If the name of a file
- * (that follows {@code META-INF/services/}) is a legal Java identifier
- * then it is assumed to be the fully-qualified binary name of a
- * service type. The entries in the file are assumed to be the
- * fully-qualified binary names of provider classes. </p></li>
+ * (that follows {@code META-INF/services/}) is a legal class name
+ * then it is assumed to be the fully-qualified class name of a service
+ * type. The entries in the file are assumed to be the fully-qualified
+ * class names of provider classes. </p></li>
*
* <li><p> If the JAR file has a {@code Main-Class} attribute in its
- * main manifest then its value is the {@link
+ * main manifest then its value is the module {@link
* ModuleDescriptor#mainClass() main class}. </p></li>
*
* </ul>
*
* <p> If a {@code ModuleDescriptor} cannot be created (by means of the
* {@link ModuleDescriptor.Builder ModuleDescriptor.Builder} API) for an
- * automatic module then {@code FindException} is thrown. This can arise,
- * for example, when a legal Java identifier name cannot be derived from
- * the file name of the JAR file or where the JAR file contains a {@code
- * .class} in the top-level directory of the JAR file. </p>
+ * automatic module then {@code FindException} is thrown. This can arise
+ * when a legal module name cannot be derived from the file name of the JAR
+ * file, where the JAR file contains a {@code .class} in the top-level
+ * directory of the JAR file, where an entry in a service configuration
+ * file is not a legal class name or its package name is not in the set of
+ * packages derived for the module, or where the module main class is not
+ * a legal class name or its package is not in the module. </p>
*
* <p> In addition to JAR files, an implementation may also support modules
- * that are packaged in other implementation specific module formats. When
- * a file is encountered that is not recognized as a packaged module then
- * {@code FindException} is thrown. An implementation may choose to ignore
- * some files, {@link java.nio.file.Files#isHidden hidden} files for
- * example. Paths to files that do not exist are always ignored. </p>
+ * that are packaged in other implementation specific module formats. If
+ * an element in the array specified to this method is a path to a directory
+ * of modules then entries in the directory that not recognized as modules
+ * are ignored. If an element in the array is a path to a packaged module
+ * that is not recognized then a {@code FindException} is thrown when the
+ * file is encountered. Paths to files that do not exist are always ignored.
+ * </p>
*
* <p> As with automatic modules, the contents of a packaged or exploded
* module may need to be <em>scanned</em> in order to determine the packages
@@ -325,7 +325,7 @@
};
}
- return new ModulePath(entries);
+ return ModulePath.of(entries);
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReader.java Wed Jul 05 22:52:22 2017 +0200
@@ -45,7 +45,7 @@
* module. A module reader is also intended to be used by {@code ClassLoader}
* implementations that load classes and resources from modules. </p>
*
- * <p> A resource in a module is identified by a name that is a
+ * <p> A resource in a module is identified by an abstract name that is a
* '{@code /}'-separated path string. For example, module {@code java.base} may
* have a resource "{@code java/lang/Object.class}" that, by convention, is the
* class file for {@code java.lang.Object}. </p>
@@ -61,8 +61,18 @@
* open}, {@link #read read}, and {@link #list list} methods may throw {@code
* SecurityException} if access is denied by the security manager. </p>
*
+ * @implSpec Implementations of {@code ModuleReader} should take great care
+ * when translating an abstract resource name to the location of a resource in
+ * a packaged module or on the file system. Implementations are advised to
+ * treat resource names with elements such as '{@code .}, '{@code ..}',
+ * elements containing file separators, or empty elements as "not found". More
+ * generally, if the resource name is not in the stream of elements that the
+ * {@code list} method returns then the resource should be treated as "not
+ * found" to avoid inconsistencies.
+ *
* @see ModuleReference
* @since 9
+ * @spec JPMS
*/
public interface ModuleReader extends Closeable {
@@ -148,6 +158,9 @@
* If an I/O error occurs or the module reader is closed
* @throws SecurityException
* If denied by the security manager
+ * @throws OutOfMemoryError
+ * If the resource is larger than {@code Integer.MAX_VALUE},
+ * the maximum capacity of a byte buffer
*
* @see ClassLoader#defineClass(String, ByteBuffer, java.security.ProtectionDomain)
*/
--- a/jdk/src/java.base/share/classes/java/lang/module/ModuleReference.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/ModuleReference.java Wed Jul 05 22:52:22 2017 +0200
@@ -44,6 +44,7 @@
* @see ModuleFinder
* @see ModuleReader
* @since 9
+ * @spec JPMS
*/
public abstract class ModuleReference {
@@ -76,7 +77,7 @@
/**
* Returns the location of this module's content, if known.
*
- * <p> This URI, when present, is used as the {@linkplain
+ * <p> This URI, when present, can be used as the {@linkplain
* java.security.CodeSource#getLocation location} value of a {@link
* java.security.CodeSource CodeSource} so that a module's classes can be
* granted specific permissions when loaded by a {@link
--- a/jdk/src/java.base/share/classes/java/lang/module/ResolutionException.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/ResolutionException.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,10 +26,12 @@
package java.lang.module;
/**
- * Thrown when resolving a set of modules or binding fails.
+ * Thrown when resolving a set of modules, or resolving a set of modules with
+ * service binding, fails.
*
* @see Configuration
* @since 9
+ * @spec JPMS
*/
public class ResolutionException extends RuntimeException {
private static final long serialVersionUID = -1031186845316729450L;
--- a/jdk/src/java.base/share/classes/java/lang/module/ResolvedModule.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/ResolvedModule.java Wed Jul 05 22:52:22 2017 +0200
@@ -37,6 +37,7 @@
* module's content.
*
* @since 9
+ * @spec JPMS
* @see Configuration#modules()
*/
public final class ResolvedModule {
--- a/jdk/src/java.base/share/classes/java/lang/module/Resolver.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/Resolver.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -49,8 +49,8 @@
import jdk.internal.module.ModuleReferenceImpl;
/**
- * The resolver used by {@link Configuration#resolveRequires} and
- * {@link Configuration#resolveRequiresAndUses}.
+ * The resolver used by {@link Configuration#resolve} and {@link
+ * Configuration#resolveAndBind}.
*
* @implNote The resolver is used at VM startup and so deliberately avoids
* using lambda and stream usages in code paths used during startup.
@@ -66,7 +66,19 @@
// maps module name to module reference
private final Map<String, ModuleReference> nameToReference = new HashMap<>();
+ // module constraints on target platform
+ private String osName;
+ private String osArch;
+ private String osVersion;
+ String osName() { return osName; }
+ String osArch() { return osArch; }
+ String osVersion() { return osVersion; }
+
+ /**
+ * @throws IllegalArgumentException if there are more than one parent and
+ * the constraints on the target platform conflict
+ */
Resolver(ModuleFinder beforeFinder,
List<Configuration> parents,
ModuleFinder afterFinder,
@@ -75,15 +87,54 @@
this.parents = parents;
this.afterFinder = afterFinder;
this.traceOutput = traceOutput;
+
+ // record constraints on target platform, checking that they don't conflict
+ for (Configuration parent : parents) {
+ String value = parent.osName();
+ if (value != null) {
+ if (osName == null) {
+ osName = value;
+ } else {
+ if (!value.equals(osName)) {
+ failParentConflict("Operating System", osName, value);
+ }
+ }
+ }
+ value = parent.osArch();
+ if (value != null) {
+ if (osArch == null) {
+ osArch = value;
+ } else {
+ if (!value.equals(osArch)) {
+ failParentConflict("OS architecture", osArch, value);
+ }
+ }
+ }
+ value = parent.osVersion();
+ if (value != null) {
+ if (osVersion == null) {
+ osVersion = value;
+ } else {
+ if (!value.equals(osVersion)) {
+ failParentConflict("OS version", osVersion, value);
+ }
+ }
+ }
+ }
}
+ private void failParentConflict(String constraint, String s1, String s2) {
+ String msg = "Parents have conflicting constraints on target "
+ + constraint + ": " + s1 + ", " + s2;
+ throw new IllegalArgumentException(msg);
+ }
/**
* Resolves the given named modules.
*
* @throws ResolutionException
*/
- Resolver resolveRequires(Collection<String> roots) {
+ Resolver resolve(Collection<String> roots) {
// create the visit stack to get us started
Deque<ModuleDescriptor> q = new ArrayDeque<>();
@@ -100,7 +151,7 @@
mref = findWithAfterFinder(root);
if (mref == null) {
- fail("Module %s not found", root);
+ findFail("Module %s not found", root);
}
}
@@ -109,8 +160,7 @@
mref.location().ifPresent(uri -> trace(" (%s)", uri));
}
- assert mref.descriptor().name().equals(root);
- nameToReference.put(root, mref);
+ addFoundModule(mref);
q.push(mref.descriptor());
}
@@ -152,19 +202,19 @@
mref = findWithAfterFinder(dn);
if (mref == null) {
- fail("Module %s not found, required by %s",
- dn, descriptor.name());
+ findFail("Module %s not found, required by %s",
+ dn, descriptor.name());
}
}
if (!nameToReference.containsKey(dn)) {
- nameToReference.put(dn, mref);
+ addFoundModule(mref);
q.offer(mref.descriptor());
resolved.add(mref.descriptor());
if (isTracing()) {
trace("Module %s located, required by %s",
- dn, descriptor.name());
+ dn, descriptor.name());
mref.location().ifPresent(uri -> trace(" (%s)", uri));
}
}
@@ -181,7 +231,7 @@
* Augments the set of resolved modules with modules induced by the
* service-use relation.
*/
- Resolver resolveUses() {
+ Resolver bind() {
// Scan the finders for all available service provider modules. As
// java.base uses services then then module finders will be scanned
@@ -246,7 +296,7 @@
mref.location()
.ifPresent(uri -> trace(" (%s)", uri));
}
- nameToReference.put(pn, mref);
+ addFoundModule(mref);
q.push(provider);
}
}
@@ -264,6 +314,81 @@
/**
+ * Add the module to the nameToReference map. Also check any constraints on
+ * the target platform with the constraints of other modules.
+ */
+ private void addFoundModule(ModuleReference mref) {
+ ModuleDescriptor descriptor = mref.descriptor();
+ nameToReference.put(descriptor.name(), mref);
+
+ if (descriptor.osName().isPresent()
+ || descriptor.osArch().isPresent()
+ || descriptor.osVersion().isPresent())
+ checkTargetConstraints(descriptor);
+ }
+
+ /**
+ * Check that the module's constraints on the target platform do not
+ * conflict with the constraints of other modules resolved so far or
+ * modules in parent configurations.
+ */
+ private void checkTargetConstraints(ModuleDescriptor descriptor) {
+ String value = descriptor.osName().orElse(null);
+ if (value != null) {
+ if (osName == null) {
+ osName = value;
+ } else {
+ if (!value.equals(osName)) {
+ failTargetConstraint(descriptor);
+ }
+ }
+ }
+ value = descriptor.osArch().orElse(null);
+ if (value != null) {
+ if (osArch == null) {
+ osArch = value;
+ } else {
+ if (!value.equals(osArch)) {
+ failTargetConstraint(descriptor);
+ }
+ }
+ }
+ value = descriptor.osVersion().orElse(null);
+ if (value != null) {
+ if (osVersion == null) {
+ osVersion = value;
+ } else {
+ if (!value.equals(osVersion)) {
+ failTargetConstraint(descriptor);
+ }
+ }
+ }
+ }
+
+ private void failTargetConstraint(ModuleDescriptor md) {
+ String s1 = targetAsString(osName, osArch, osVersion);
+ String s2 = targetAsString(md);
+ findFail("Module %s has constraints on target platform that conflict" +
+ " with other modules: %s, %s", md.name(), s1, s2);
+ }
+
+ private String targetAsString(ModuleDescriptor descriptor) {
+ String osName = descriptor.osName().orElse(null);
+ String osArch = descriptor.osArch().orElse(null);
+ String osVersion = descriptor.osVersion().orElse(null);
+ return targetAsString(osName, osArch, osVersion);
+ }
+
+ private String targetAsString(String osName, String osArch, String osVersion) {
+ return new StringJoiner("-")
+ .add(Objects.toString(osName, "*"))
+ .add(Objects.toString(osArch, "*"))
+ .add(Objects.toString(osVersion, "*"))
+ .toString();
+ }
+
+
+ /**
* Execute post-resolution checks and returns the module graph of resolved
* modules as {@code Map}. The resolved modules will be in the given
* configuration.
@@ -281,7 +406,6 @@
if (check) {
detectCycles();
- checkPlatformConstraints();
checkHashes();
}
@@ -319,8 +443,7 @@
if (!visited.contains(descriptor)) {
boolean added = visitPath.add(descriptor);
if (!added) {
- throw new ResolutionException("Cycle detected: " +
- cycleAsString(descriptor));
+ resolveFail("Cycle detected: %s", cycleAsString(descriptor));
}
for (ModuleDescriptor.Requires requires : descriptor.requires()) {
String dn = requires.name();
@@ -354,86 +477,6 @@
/**
- * If there are platform specific modules then check that the OS name,
- * architecture and version match.
- *
- * @apiNote This method does not currently check if the OS matches
- * platform specific modules in parent configurations.
- */
- private void checkPlatformConstraints() {
-
- // first module encountered that is platform specific
- String savedModuleName = null;
- String savedOsName = null;
- String savedOsArch = null;
- String savedOsVersion = null;
-
- for (ModuleReference mref : nameToReference.values()) {
- ModuleDescriptor descriptor = mref.descriptor();
-
- String osName = descriptor.osName().orElse(null);
- String osArch = descriptor.osArch().orElse(null);
- String osVersion = descriptor.osVersion().orElse(null);
-
- if (osName != null || osArch != null || osVersion != null) {
-
- if (savedModuleName == null) {
-
- savedModuleName = descriptor.name();
- savedOsName = osName;
- savedOsArch = osArch;
- savedOsVersion = osVersion;
-
- } else {
-
- boolean matches = platformMatches(osName, savedOsName)
- && platformMatches(osArch, savedOsArch)
- && platformMatches(osVersion, savedOsVersion);
-
- if (!matches) {
- String s1 = platformAsString(savedOsName,
- savedOsArch,
- savedOsVersion);
-
- String s2 = platformAsString(osName, osArch, osVersion);
- fail("Mismatching constraints on target platform: "
- + savedModuleName + ": " + s1
- + ", " + descriptor.name() + ": " + s2);
- }
-
- }
-
- }
- }
-
- }
-
- /**
- * Returns true if the s1 and s2 are equal or one of them is null.
- */
- private boolean platformMatches(String s1, String s2) {
- if (s1 == null || s2 == null)
- return true;
- else
- return Objects.equals(s1, s2);
- }
-
- /**
- * Return a string that encodes the OS name/arch/version.
- */
- private String platformAsString(String osName,
- String osArch,
- String osVersion) {
-
- return new StringJoiner("-")
- .add(Objects.toString(osName, "*"))
- .add(Objects.toString(osArch, "*"))
- .add(Objects.toString(osVersion, "*"))
- .toString();
-
- }
-
- /**
* Checks the hashes in the module descriptor to ensure that they match
* any recorded hashes.
*/
@@ -460,7 +503,7 @@
continue;
if (!(mref2 instanceof ModuleReferenceImpl)) {
- fail("Unable to compute the hash of module %s", dn);
+ findFail("Unable to compute the hash of module %s", dn);
}
// skip checking the hash if the module has been patched
@@ -469,11 +512,11 @@
byte[] recordedHash = hashes.hashFor(dn);
byte[] actualHash = other.computeHash(algorithm);
if (actualHash == null)
- fail("Unable to compute the hash of module %s", dn);
+ findFail("Unable to compute the hash of module %s", dn);
if (!Arrays.equals(recordedHash, actualHash)) {
- fail("Hash of %s (%s) differs to expected hash (%s)" +
- " recorded in %s", dn, toHexString(actualHash),
- toHexString(recordedHash), descriptor.name());
+ findFail("Hash of %s (%s) differs to expected hash (%s)" +
+ " recorded in %s", dn, toHexString(actualHash),
+ toHexString(recordedHash), descriptor.name());
}
}
}
@@ -694,37 +737,38 @@
for (ResolvedModule endpoint : reads) {
ModuleDescriptor descriptor2 = endpoint.descriptor();
- for (ModuleDescriptor.Exports export : descriptor2.exports()) {
-
- if (export.isQualified()) {
- if (!export.targets().contains(descriptor1.name()))
- continue;
- }
-
- // source is exported to descriptor2
- String source = export.source();
- ModuleDescriptor other
- = packageToExporter.putIfAbsent(source, descriptor2);
+ if (descriptor2.isAutomatic()) {
+ // automatic modules read self and export all packages
+ if (descriptor2 != descriptor1){
+ for (String source : descriptor2.packages()) {
+ ModuleDescriptor supplier
+ = packageToExporter.putIfAbsent(source, descriptor2);
- if (other != null && other != descriptor2) {
- // package might be local to descriptor1
- if (other == descriptor1) {
- fail("Module %s contains package %s"
- + ", module %s exports package %s to %s",
- descriptor1.name(),
- source,
- descriptor2.name(),
- source,
- descriptor1.name());
- } else {
- fail("Modules %s and %s export package %s to module %s",
- descriptor2.name(),
- other.name(),
- source,
- descriptor1.name());
+ // descriptor2 and 'supplier' export source to descriptor1
+ if (supplier != null) {
+ failTwoSuppliers(descriptor1, source, descriptor2, supplier);
+ }
}
}
+ } else {
+ for (ModuleDescriptor.Exports export : descriptor2.exports()) {
+ if (export.isQualified()) {
+ if (!export.targets().contains(descriptor1.name()))
+ continue;
+ }
+
+ // source is exported by descriptor2
+ String source = export.source();
+ ModuleDescriptor supplier
+ = packageToExporter.putIfAbsent(source, descriptor2);
+
+ // descriptor2 and 'supplier' export source to descriptor1
+ if (supplier != null) {
+ failTwoSuppliers(descriptor1, source, descriptor2, supplier);
+ }
+ }
+
}
}
@@ -735,8 +779,8 @@
for (String service : descriptor1.uses()) {
String pn = packageName(service);
if (!packageToExporter.containsKey(pn)) {
- fail("Module %s does not read a module that exports %s",
- descriptor1.name(), pn);
+ resolveFail("Module %s does not read a module that exports %s",
+ descriptor1.name(), pn);
}
}
@@ -744,15 +788,8 @@
for (ModuleDescriptor.Provides provides : descriptor1.provides()) {
String pn = packageName(provides.service());
if (!packageToExporter.containsKey(pn)) {
- fail("Module %s does not read a module that exports %s",
- descriptor1.name(), pn);
- }
-
- for (String provider : provides.providers()) {
- if (!packages.contains(packageName(provider))) {
- fail("Provider %s not in module %s",
- provider, descriptor1.name());
- }
+ resolveFail("Module %s does not read a module that exports %s",
+ descriptor1.name(), pn);
}
}
@@ -763,6 +800,42 @@
}
/**
+ * Fail because a module in the configuration exports the same package to
+ * a module that reads both. This includes the case where a module M
+ * containing a package p reads another module that exports p to at least
+ * module M.
+ */
+ private void failTwoSuppliers(ModuleDescriptor descriptor,
+ String source,
+ ModuleDescriptor supplier1,
+ ModuleDescriptor supplier2) {
+
+ if (supplier2 == descriptor) {
+ ModuleDescriptor tmp = supplier1;
+ supplier1 = supplier2;
+ supplier2 = tmp;
+ }
+
+ if (supplier1 == descriptor) {
+ resolveFail("Module %s contains package %s"
+ + ", module %s exports package %s to %s",
+ descriptor.name(),
+ source,
+ supplier2.name(),
+ source,
+ descriptor.name());
+ } else {
+ resolveFail("Modules %s and %s export package %s to module %s",
+ supplier1.name(),
+ supplier2.name(),
+ source,
+ descriptor.name());
+ }
+
+ }
+
+
+ /**
* Find a module of the given name in the parent configurations
*/
private ResolvedModule findInParent(String mn) {
@@ -779,24 +852,16 @@
* Invokes the beforeFinder to find method to find the given module.
*/
private ModuleReference findWithBeforeFinder(String mn) {
- try {
- return beforeFinder.find(mn).orElse(null);
- } catch (FindException e) {
- // unwrap
- throw new ResolutionException(e.getMessage(), e.getCause());
- }
+
+ return beforeFinder.find(mn).orElse(null);
+
}
/**
* Invokes the afterFinder to find method to find the given module.
*/
private ModuleReference findWithAfterFinder(String mn) {
- try {
- return afterFinder.find(mn).orElse(null);
- } catch (FindException e) {
- // unwrap
- throw new ResolutionException(e.getMessage(), e.getCause());
- }
+ return afterFinder.find(mn).orElse(null);
}
/**
@@ -804,34 +869,27 @@
* and after ModuleFinders.
*/
private Set<ModuleReference> findAll() {
- try {
-
- Set<ModuleReference> beforeModules = beforeFinder.findAll();
- Set<ModuleReference> afterModules = afterFinder.findAll();
+ Set<ModuleReference> beforeModules = beforeFinder.findAll();
+ Set<ModuleReference> afterModules = afterFinder.findAll();
- if (afterModules.isEmpty())
- return beforeModules;
+ if (afterModules.isEmpty())
+ return beforeModules;
- if (beforeModules.isEmpty()
- && parents.size() == 1
- && parents.get(0) == Configuration.empty())
- return afterModules;
+ if (beforeModules.isEmpty()
+ && parents.size() == 1
+ && parents.get(0) == Configuration.empty())
+ return afterModules;
- Set<ModuleReference> result = new HashSet<>(beforeModules);
- for (ModuleReference mref : afterModules) {
- String name = mref.descriptor().name();
- if (!beforeFinder.find(name).isPresent()
- && findInParent(name) == null) {
- result.add(mref);
- }
+ Set<ModuleReference> result = new HashSet<>(beforeModules);
+ for (ModuleReference mref : afterModules) {
+ String name = mref.descriptor().name();
+ if (!beforeFinder.find(name).isPresent()
+ && findInParent(name) == null) {
+ result.add(mref);
}
-
- return result;
+ }
- } catch (FindException e) {
- // unwrap
- throw new ResolutionException(e.getMessage(), e.getCause());
- }
+ return result;
}
/**
@@ -843,9 +901,17 @@
}
/**
+ * Throw FindException with the given format string and arguments
+ */
+ private static void findFail(String fmt, Object ... args) {
+ String msg = String.format(fmt, args);
+ throw new FindException(msg);
+ }
+
+ /**
* Throw ResolutionException with the given format string and arguments
*/
- private static void fail(String fmt, Object ... args) {
+ private static void resolveFail(String fmt, Object ... args) {
String msg = String.format(fmt, args);
throw new ResolutionException(msg);
}
--- a/jdk/src/java.base/share/classes/java/lang/module/package-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/module/package-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,112 @@
* Classes to support module descriptors and creating configurations of modules
* by means of resolution and service binding.
*
+ * <h2><a name="resolution">Resolution</a></h2>
+ *
+ * <p> Resolution is the process of computing the transitive closure of a set
+ * of root modules over a set of observable modules by resolving the
+ * dependences expressed by {@link
+ * java.lang.module.ModuleDescriptor.Requires requires} clauses.
+ * The <em>dependence graph</em> is augmented with edges that take account of
+ * implicitly declared dependences ({@code requires transitive}) to create a
+ * <em>readability graph</em>. The result of resolution is a {@link
+ * java.lang.module.Configuration Configuration} that encapsulates the
+ * readability graph. </p>
+ *
+ * <p> As an example, suppose we have the following observable modules: </p>
+ * <pre> {@code
+ * module m1 { requires m2; }
+ * module m2 { requires transitive m3; }
+ * module m3 { }
+ * module m4 { }
+ * } </pre>
+ *
+ * <p> If the module {@code m1} is resolved then the resulting configuration
+ * contains three modules ({@code m1}, {@code m2}, {@code m3}). The edges in
+ * its readability graph are: </p>
+ * <pre> {@code
+ * m1 --> m2 (meaning m1 reads m2)
+ * m1 --> m3
+ * m2 --> m3
+ * } </pre>
+ *
+ * <p> Resolution is an additive process. When computing the transitive closure
+ * then the dependence relation may include dependences on modules in {@link
+ * java.lang.module.Configuration#parents() parent} configurations. The result
+ * is a <em>relative configuration</em> that is relative to one or more parent
+ * configurations and where the readability graph may have edges from modules
+ * in the configuration to modules in parent configurations. </p>
+ *
+ * <p> As an example, suppose we have the following observable modules: </p>
+ * <pre> {@code
+ * module m1 { requires m2; requires java.xml; }
+ * module m2 { }
+ * } </pre>
+ *
+ * <p> If module {@code m1} is resolved with the configuration for the {@link
+ * java.lang.reflect.Layer#boot() boot} layer as the parent then the resulting
+ * configuration contains two modules ({@code m1}, {@code m2}). The edges in
+ * its readability graph are:
+ * <pre> {@code
+ * m1 --> m2
+ * m1 --> java.xml
+ * } </pre>
+ * where module {@code java.xml} is in the parent configuration. For
+ * simplicity, this example omits the implicitly declared dependence on the
+ * {@code java.base} module.
+ *
+ * <p> Requires clauses that are "{@code requires static}" express an optional
+ * dependence (except at compile-time). If a module declares that it
+ * "{@code requires static M}" then resolution does not search the observable
+ * modules for "{@code M}". However, if "{@code M}" is resolved (because resolution
+ * resolves a module that requires "{@code M}" without the {@link
+ * java.lang.module.ModuleDescriptor.Requires.Modifier#STATIC static} modifier)
+ * then the readability graph will contain read edges for each module that
+ * "{@code requires static M}". </p>
+ *
+ * <p> {@link java.lang.module.ModuleDescriptor#isAutomatic() Automatic} modules
+ * receive special treatment during resolution. Each automatic module is resolved
+ * so that it reads all other modules in the configuration and all parent
+ * configurations. Each automatic module is also resolved as if it
+ * "{@code requires transitive}" all other automatic modules in the configuration
+ * (and all automatic modules in parent configurations). </p>
+ *
+ * <h2><a name="servicebinding">Service binding</a></h2>
+ *
+ * <p> Service binding is the process of augmenting a graph of resolved modules
+ * from the set of observable modules induced by the service-use dependence
+ * ({@code uses} and {@code provides} clauses). Any module that was not
+ * previously in the graph requires resolution to compute its transitive
+ * closure. Service binding is an iterative process in that adding a module
+ * that satisfies some service-use dependence may introduce new service-use
+ * dependences. </p>
+ *
+ * <p> Suppose we have the following observable modules: </p>
+ * <pre> {@code
+ * module m1 { exports p; uses p.S; }
+ * module m2 { requires m1; provides p.S with p2.S2; }
+ * module m3 { requires m1; requires m4; provides p.S with p3.S3; }
+ * module m4 { }
+ * } </pre>
+ *
+ * <p> If the module {@code m1} is resolved then the resulting graph of modules
+ * has one module ({@code m1}). If the graph is augmented with modules induced
+ * by the service-use dependence relation then the configuration will contain
+ * four modules ({@code m1}, {@code m2}, {@code m3}, {@code m4}). The edges in
+ * its readability graph are: </p>
+ * <pre> {@code
+ * m2 --> m1
+ * m3 --> m1
+ * m3 --> m4
+ * } </pre>
+ * <p> The edges in the conceptual service-use graph are: </p>
+ * <pre> {@code
+ * m1 --> m2 (meaning m1 uses a service that is provided by m2)
+ * m1 --> m3
+ * } </pre>
+ *
+ * <h2>General Exceptions</h2>
+ *
* <p> Unless otherwise noted, passing a {@code null} argument to a constructor
* or method of any class or interface in this package will cause a {@link
* java.lang.NullPointerException NullPointerException} to be thrown. Additionally,
@@ -34,6 +140,7 @@
* will cause a {@code NullPointerException}, unless otherwise specified. </p>
*
* @since 9
+ * @spec JPMS
*/
package java.lang.module;
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,38 +28,44 @@
import java.lang.annotation.Annotation;
import java.security.AccessController;
-import jdk.internal.misc.VM;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import jdk.internal.reflect.ReflectionFactory;
-import sun.security.action.GetPropertyAction;
/**
- * The AccessibleObject class is the base class for Field, Method and
- * Constructor objects. It provides the ability to flag a reflected
- * object as suppressing default Java language access control checks
- * when it is used. The access checks -- <em>module boundaries</em>,
- * public, default (package) access, protected, and private members --
- * are performed when Fields, Methods or Constructors are used to set
- * or get fields, to invoke methods or to create and initialize new
- * instances of classes, respectively. Unlike access control specified
- * in the <cite>The Java™ Language Specification</cite> and
- * <cite>The Java Virtual Machine Specification</cite>, access checks
- * with reflected objects assume {@link Module#canRead readability}.
+ * The {@code AccessibleObject} class is the base class for {@code Field},
+ * {@code Method}, and {@code Constructor} objects (known as <em>reflected
+ * objects</em>). It provides the ability to flag a reflected object as
+ * suppressing checks for Java language access control when it is used. This
+ * permits sophisticated applications with sufficient privilege, such as Java
+ * Object Serialization or other persistence mechanisms, to manipulate objects
+ * in a manner that would normally be prohibited.
*
- * <p>Setting the {@code accessible} flag in a reflected object
- * permits sophisticated applications with sufficient privilege, such
- * as Java Object Serialization or other persistence mechanisms, to
- * manipulate objects in a manner that would normally be prohibited.
- *
- * <p>By default, a reflected object is <em>not</em> accessible.
+ * <p> Java language access control prevents use of private members outside
+ * their class; package access members outside their package; protected members
+ * outside their package or subclasses; and public members outside their
+ * module unless they are declared in an {@link Module#isExported(String,Module)
+ * exported} package and the user {@link Module#canRead reads} their module. By
+ * default, Java language access control is enforced (with one variation) when
+ * {@code Field}s, {@code Method}s, or {@code Constructor}s are used to get or
+ * set fields, to invoke methods, or to create and initialize new instances of
+ * classes, respectively. Every reflected object checks that the code using it
+ * is in an appropriate class, package, or module. </p>
*
- * @see Field
- * @see Method
- * @see Constructor
- * @see ReflectPermission
+ * <p> The one variation from Java language access control is that the checks
+ * by reflected objects assume readability. That is, the module containing
+ * the use of a reflected object is assumed to read the module in which
+ * the underlying field, method, or constructor is declared. </p>
*
+ * <p> Whether the checks for Java language access control can be suppressed
+ * (and thus, whether access can be enabled) depends on whether the reflected
+ * object corresponds to a member in an exported or open package
+ * (see {@link #setAccessible(boolean)}). </p>
+ *
+ * @jls 6.6 Access Control
* @since 1.2
+ * @revised 9
+ * @spec JPMS
*/
public class AccessibleObject implements AnnotatedElement {
@@ -78,15 +84,11 @@
/**
* Convenience method to set the {@code accessible} flag for an
- * array of objects with a single security check (for efficiency).
+ * array of reflected objects with a single security check (for efficiency).
*
- * <p>This method cannot be used to enable access to an object that is a
- * {@link Member member} of a class in a different module to the caller and
- * where the class is in a package that is not exported to the caller's
- * module. Additionally, if the member is non-public or its declaring
- * class is non-public, then this method can only be used to enable access
- * if the package is {@link Module#isOpen(String,Module) open} to at least
- * the caller's module.
+ * <p> This method may be used to enable access to all reflected objects in
+ * the array when access to each reflected object can be enabled as
+ * specified by {@link #setAccessible(boolean) setAccessible(boolean)}. </p>
*
* <p>If there is a security manager, its
* {@code checkPermission} method is first called with a
@@ -99,10 +101,15 @@
* @param array the array of AccessibleObjects
* @param flag the new value for the {@code accessible} flag
* in each object
- * @throws InaccessibleObjectException if access cannot be enabled
- * @throws SecurityException if the request is denied.
+ * @throws InaccessibleObjectException if access cannot be enabled for all
+ * objects in the array
+ * @throws SecurityException if the request is denied by the security manager
+ * or an element in the array is a constructor for {@code
+ * java.lang.Class}
* @see SecurityManager#checkPermission
* @see ReflectPermission
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public static void setAccessible(AccessibleObject[] array, boolean flag) {
@@ -120,41 +127,143 @@
}
/**
- * Set the {@code accessible} flag for this object to
+ * Set the {@code accessible} flag for this reflected object to
* the indicated boolean value. A value of {@code true} indicates that
- * the reflected object should suppress Java language access
- * checking when it is used. A value of {@code false} indicates
- * that the reflected object should enforce Java language access checks
- * while assuming readability (as noted in the class description).
+ * the reflected object should suppress checks for Java language access
+ * control when it is used. A value of {@code false} indicates that
+ * the reflected object should enforce checks for Java language access
+ * control when it is used, with the variation noted in the class description.
+ *
+ * <p> This method may be used by a caller in class {@code C} to enable
+ * access to a {@link Member member} of {@link Member#getDeclaringClass()
+ * declaring class} {@code D} if any of the following hold: </p>
+ *
+ * <ul>
+ * <li> {@code C} and {@code D} are in the same module. </li>
+ *
+ * <li> The member is {@code public} and {@code D} is {@code public} in
+ * a package that the module containing {@code D} {@link
+ * Module#isExported(String,Module) exports} to at least the module
+ * containing {@code C}. </li>
*
- * <p>This method cannot be used to enable access to an object that is a
- * {@link Member member} of a class in a different module to the caller and
- * where the class is in a package that is not exported to the caller's
- * module. Additionally, if the member is non-public or its declaring
- * class is non-public, then this method can only be used to enable access
- * if the package is {@link Module#isOpen(String,Module) open} to at least
- * the caller's module.
+ * <li> The member is {@code protected} {@code static}, {@code D} is
+ * {@code public} in a package that the module containing {@code D}
+ * exports to at least the module containing {@code C}, and {@code C}
+ * is a subclass of {@code D}. </li>
*
- * <p>If there is a security manager, its
+ * <li> {@code D} is in a package that the module containing {@code D}
+ * {@link Module#isOpen(String,Module) opens} to at least the module
+ * containing {@code C}.
+ * All packages in unnamed and open modules are open to all modules and
+ * so this method always succeeds when {@code D} is in an unnamed or
+ * open module. </li>
+ * </ul>
+ *
+ * <p> This method cannot be used to enable access to private members,
+ * members with default (package) access, protected instance members, or
+ * protected constructors when the declaring class is in a different module
+ * to the caller and the package containing the declaring class is not open
+ * to the caller's module. </p>
+ *
+ * <p> If there is a security manager, its
* {@code checkPermission} method is first called with a
* {@code ReflectPermission("suppressAccessChecks")} permission.
*
* @param flag the new value for the {@code accessible} flag
* @throws InaccessibleObjectException if access cannot be enabled
- * @throws SecurityException if the request is denied
- * @see SecurityManager#checkPermission
- * @see ReflectPermission
+ * @throws SecurityException if the request is denied by the security manager
+ * @see #trySetAccessible
* @see java.lang.invoke.MethodHandles#privateLookupIn
+ * @revised 9
+ * @spec JPMS
*/
public void setAccessible(boolean flag) {
AccessibleObject.checkPermission();
setAccessible0(flag);
}
- void setAccessible0(boolean flag) {
+ /**
+ * Sets the accessible flag and returns the new value
+ */
+ boolean setAccessible0(boolean flag) {
this.override = flag;
+ return flag;
}
+ /**
+ * Set the {@code accessible} flag for this reflected object to {@code true}
+ * if possible. This method sets the {@code accessible} flag, as if by
+ * invoking {@link #setAccessible(boolean) setAccessible(true)}, and returns
+ * the possibly-updated value for the {@code accessible} flag. If access
+ * cannot be enabled, i.e. the checks or Java language access control cannot
+ * be suppressed, this method returns {@code false} (as opposed to {@code
+ * setAccessible(true)} throwing {@code InaccessibleObjectException} when
+ * it fails).
+ *
+ * <p> This method is a no-op if the {@code accessible} flag for
+ * this reflected object is {@code true}.
+ *
+ * <p> For example, a caller can invoke {@code trySetAccessible}
+ * on a {@code Method} object for a private instance method
+ * {@code p.T::privateMethod} to suppress the checks for Java language access
+ * control when the {@code Method} is invoked.
+ * If {@code p.T} class is in a different module to the caller and
+ * package {@code p} is open to at least the caller's module,
+ * the code below successfully sets the {@code accessible} flag
+ * to {@code true}.
+ *
+ * <pre>
+ * {@code
+ * p.T obj = ....; // instance of p.T
+ * :
+ * Method m = p.T.class.getDeclaredMethod("privateMethod");
+ * if (m.trySetAccessible()) {
+ * m.invoke(obj);
+ * } else {
+ * // package p is not opened to the caller to access private member of T
+ * ...
+ * }
+ * }</pre>
+ *
+ * <p> If there is a security manager, its {@code checkPermission} method
+ * is first called with a {@code ReflectPermission("suppressAccessChecks")}
+ * permission. </p>
+ *
+ * @return {@code true} if the {@code accessible} flag is set to {@code true};
+ * {@code false} if access cannot be enabled.
+ * @throws SecurityException if the request is denied by the security manager
+ *
+ * @since 9
+ * @spec JPMS
+ * @see java.lang.invoke.MethodHandles#privateLookupIn
+ */
+ @CallerSensitive
+ public final boolean trySetAccessible() {
+ AccessibleObject.checkPermission();
+
+ if (override == true) return true;
+
+ // if it's not a Constructor, Method, Field then no access check
+ if (!Member.class.isInstance(this)) {
+ return setAccessible0(true);
+ }
+
+ // does not allow to suppress access check for Class's constructor
+ Class<?> declaringClass = ((Member) this).getDeclaringClass();
+ if (declaringClass == Class.class && this instanceof Constructor) {
+ return false;
+ }
+
+ if (checkCanSetAccessible(Reflection.getCallerClass(),
+ declaringClass,
+ false)) {
+ return setAccessible0(true);
+ } else {
+ return false;
+ }
+ }
+
+
/**
* If the given AccessibleObject is a {@code Constructor}, {@code Method}
* or {@code Field} then checks that its declaring class is in a package
@@ -164,22 +273,29 @@
// do nothing, needs to be overridden by Constructor, Method, Field
}
+
void checkCanSetAccessible(Class<?> caller, Class<?> declaringClass) {
+ checkCanSetAccessible(caller, declaringClass, true);
+ }
+
+ private boolean checkCanSetAccessible(Class<?> caller,
+ Class<?> declaringClass,
+ boolean throwExceptionIfDenied) {
Module callerModule = caller.getModule();
Module declaringModule = declaringClass.getModule();
- if (callerModule == declaringModule) return;
- if (callerModule == Object.class.getModule()) return;
- if (!declaringModule.isNamed()) return;
+ if (callerModule == declaringModule) return true;
+ if (callerModule == Object.class.getModule()) return true;
+ if (!declaringModule.isNamed()) return true;
// package is open to caller
String pn = packageName(declaringClass);
if (declaringModule.isOpen(pn, callerModule)) {
- printStackTraceIfOpenedReflectively(declaringModule, pn, callerModule);
- return;
+ dumpStackIfOpenedReflectively(declaringModule, pn, callerModule);
+ return true;
}
- // package is exported to caller and class/member is public
+ // package is exported to caller
boolean isExported = declaringModule.isExported(pn, callerModule);
boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers());
int modifiers;
@@ -188,48 +304,72 @@
} else {
modifiers = ((Field) this).getModifiers();
}
- boolean isMemberPublic = Modifier.isPublic(modifiers);
- if (isExported && isClassPublic && isMemberPublic) {
- printStackTraceIfExportedReflectively(declaringModule, pn, callerModule);
- return;
+ if (isExported && isClassPublic) {
+
+ // member is public
+ if (Modifier.isPublic(modifiers)) {
+ dumpStackIfExportedReflectively(declaringModule, pn, callerModule);
+ return true;
+ }
+
+ // member is protected-static
+ if (Modifier.isProtected(modifiers)
+ && Modifier.isStatic(modifiers)
+ && isSubclassOf(caller, declaringClass)) {
+ dumpStackIfExportedReflectively(declaringModule, pn, callerModule);
+ return true;
+ }
}
- // not accessible
- String msg = "Unable to make ";
- if (this instanceof Field)
- msg += "field ";
- msg += this + " accessible: " + declaringModule + " does not \"";
- if (isClassPublic && isMemberPublic)
- msg += "exports";
- else
- msg += "opens";
- msg += " " + pn + "\" to " + callerModule;
- InaccessibleObjectException e = new InaccessibleObjectException(msg);
- if (Reflection.printStackTraceWhenAccessFails()) {
- e.printStackTrace(System.err);
+ if (throwExceptionIfDenied) {
+ // not accessible
+ String msg = "Unable to make ";
+ if (this instanceof Field)
+ msg += "field ";
+ msg += this + " accessible: " + declaringModule + " does not \"";
+ if (isClassPublic && Modifier.isPublic(modifiers))
+ msg += "exports";
+ else
+ msg += "opens";
+ msg += " " + pn + "\" to " + callerModule;
+ InaccessibleObjectException e = new InaccessibleObjectException(msg);
+ if (Reflection.printStackTraceWhenAccessFails()) {
+ e.printStackTrace(System.err);
+ }
+ throw e;
}
- throw e;
+ return false;
}
- private void printStackTraceIfOpenedReflectively(Module module,
- String pn,
- Module other) {
- printStackTraceIfExposedReflectively(module, pn, other, true);
+ private boolean isSubclassOf(Class<?> queryClass, Class<?> ofClass) {
+ while (queryClass != null) {
+ if (queryClass == ofClass) {
+ return true;
+ }
+ queryClass = queryClass.getSuperclass();
+ }
+ return false;
}
- private void printStackTraceIfExportedReflectively(Module module,
- String pn,
- Module other) {
- printStackTraceIfExposedReflectively(module, pn, other, false);
+ private void dumpStackIfOpenedReflectively(Module module,
+ String pn,
+ Module other) {
+ dumpStackIfExposedReflectively(module, pn, other, true);
}
- private void printStackTraceIfExposedReflectively(Module module,
- String pn,
- Module other,
- boolean open)
+ private void dumpStackIfExportedReflectively(Module module,
+ String pn,
+ Module other) {
+ dumpStackIfExposedReflectively(module, pn, other, false);
+ }
+
+ private void dumpStackIfExposedReflectively(Module module,
+ String pn,
+ Module other,
+ boolean open)
{
if (Reflection.printStackTraceWhenAccessSucceeds()
- && !module.isStaticallyExportedOrOpen(pn, other, open))
+ && !module.isStaticallyExportedOrOpen(pn, other, open))
{
String msg = other + " allowed to invoke setAccessible on ";
if (this instanceof Field)
@@ -256,15 +396,100 @@
}
/**
- * Get the value of the {@code accessible} flag for this object.
+ * Get the value of the {@code accessible} flag for this reflected object.
*
* @return the value of the object's {@code accessible} flag
+ *
+ * @deprecated
+ * This method is deprecated because its name hints that it checks
+ * if the reflected object is accessible when it actually indicates
+ * if the checks for Java language access control are suppressed.
+ * This method may return {@code false} on a reflected object that is
+ * accessible to the caller. To test if this reflected object is accessible,
+ * it should use {@link #canAccess(Object)}.
+ *
+ * @revised 9
*/
+ @Deprecated(since="9")
public boolean isAccessible() {
return override;
}
/**
+ * Test if the caller can access this reflected object. If this reflected
+ * object corresponds to an instance method or field then this method tests
+ * if the caller can access the given {@code obj} with the reflected object.
+ * For instance methods or fields then the {@code obj} argument must be an
+ * instance of the {@link Member#getDeclaringClass() declaring class}. For
+ * static members and constructors then {@code obj} must be {@code null}.
+ *
+ * <p> This method returns {@code true} if the {@code accessible} flag
+ * is set to {@code true}, i.e. the checks for Java language access control
+ * are suppressed, or if the caller can access the member as
+ * specified in <cite>The Java™ Language Specification</cite>,
+ * with the variation noted in the class description. </p>
+ *
+ * @param obj an instance object of the declaring class of this reflected
+ * object if it is an instance method or field
+ *
+ * @return {@code true} if the caller can access this reflected object.
+ *
+ * @throws IllegalArgumentException
+ * <ul>
+ * <li> if this reflected object is a static member or constructor and
+ * the given {@code obj} is non-{@code null}, or </li>
+ * <li> if this reflected object is an instance method or field
+ * and the given {@code obj} is {@code null} or of type
+ * that is not a subclass of the {@link Member#getDeclaringClass()
+ * declaring class} of the member.</li>
+ * </ul>
+ *
+ * @since 9
+ * @spec JPMS
+ * @jls 6.6 Access Control
+ * @see #trySetAccessible
+ * @see #setAccessible(boolean)
+ */
+ @CallerSensitive
+ public final boolean canAccess(Object obj) {
+ if (!Member.class.isInstance(this)) {
+ return override;
+ }
+
+ Class<?> declaringClass = ((Member) this).getDeclaringClass();
+ int modifiers = ((Member) this).getModifiers();
+ if (!Modifier.isStatic(modifiers) &&
+ (this instanceof Method || this instanceof Field)) {
+ if (obj == null) {
+ throw new IllegalArgumentException("null object for " + this);
+ }
+ // if this object is an instance member, the given object
+ // must be a subclass of the declaring class of this reflected object
+ if (!declaringClass.isAssignableFrom(obj.getClass())) {
+ throw new IllegalArgumentException("object is not an instance of "
+ + declaringClass.getName());
+ }
+ } else if (obj != null) {
+ throw new IllegalArgumentException("non-null object for " + this);
+ }
+
+ // access check is suppressed
+ if (override) return true;
+
+ Class<?> caller = Reflection.getCallerClass();
+ Class<?> targetClass;
+ if (this instanceof Constructor) {
+ targetClass = declaringClass;
+ } else {
+ targetClass = Modifier.isStatic(modifiers) ? null : obj.getClass();
+ }
+ return Reflection.verifyMemberAccess(caller,
+ declaringClass,
+ targetClass,
+ modifiers);
+ }
+
+ /**
* Constructor: only used by the Java Virtual Machine.
*/
protected AccessibleObject() {}
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Wed Jul 05 22:52:22 2017 +0200
@@ -168,6 +168,13 @@
* is true. </p>
*
* @param flag {@inheritDoc}
+ *
+ * @throws InaccessibleObjectException {@inheritDoc}
+ * @throws SecurityException if the request is denied by the security manager
+ * or this is a constructor for {@code java.lang.Class}
+ *
+ * @since 9
+ * @spec JPMS
*/
@Override
@CallerSensitive
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Wed Jul 05 22:52:22 2017 +0200
@@ -158,6 +158,10 @@
return res;
}
+ /**
+ * @throws InaccessibleObjectException {@inheritDoc}
+ * @throws SecurityException {@inheritDoc}
+ */
@Override
@CallerSensitive
public void setAccessible(boolean flag) {
--- a/jdk/src/java.base/share/classes/java/lang/reflect/InaccessibleObjectException.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/InaccessibleObjectException.java Wed Jul 05 22:52:22 2017 +0200
@@ -30,6 +30,7 @@
*
* @see AccessibleObject#setAccessible(boolean)
* @since 9
+ * @spec JPMS
*/
public class InaccessibleObjectException extends RuntimeException {
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Layer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Layer.java Wed Jul 05 22:52:22 2017 +0200
@@ -56,20 +56,19 @@
/**
* A layer of modules in the Java virtual machine.
*
- * <p> A layer is created from a graph of modules that is the {@link
- * Configuration} and a function that maps each module to a {@link ClassLoader}.
+ * <p> A layer is created from a graph of modules in a {@link Configuration}
+ * and a function that maps each module to a {@link ClassLoader}.
* Creating a layer informs the Java virtual machine about the classes that
- * may be loaded from modules so that the Java virtual machine knows which
- * module that each class is a member of. Each layer, except the {@link
- * #empty() empty} layer, has at least one {@link #parents() parent}. </p>
+ * may be loaded from the modules so that the Java virtual machine knows which
+ * module that each class is a member of. </p>
*
* <p> Creating a layer creates a {@link Module} object for each {@link
* ResolvedModule} in the configuration. For each resolved module that is
* {@link ResolvedModule#reads() read}, the {@code Module} {@link
* Module#canRead reads} the corresponding run-time {@code Module}, which may
- * be in the same layer or a parent layer. The {@code Module} {@link
- * Module#isExported(String) exports} the packages described by its {@link
- * ModuleDescriptor}. </p>
+ * be in the same layer or a {@link #parents() parent} layer. The {@code Module}
+ * {@link Module#isExported(String) exports} and {@link Module#isOpen(String)
+ * opens} the packages described by its {@link ModuleDescriptor}. </p>
*
* <p> The {@link #defineModulesWithOneLoader defineModulesWithOneLoader} and
* {@link #defineModulesWithManyLoaders defineModulesWithManyLoaders} methods
@@ -80,7 +79,7 @@
* a function specified to the method. Each of these methods has an instance
* and static variant. The instance methods create a layer with the receiver
* as the parent layer. The static methods are for more advanced cases where
- * there can be more than one parent layer or a {@link Layer.Controller
+ * there can be more than one parent layer or where a {@link Layer.Controller
* Controller} is needed to control modules in the layer. </p>
*
* <p> A Java virtual machine has at least one non-empty layer, the {@link
@@ -93,9 +92,8 @@
* the {@link #parents() parent} when creating additional layers. </p>
*
* <p> As when creating a {@code Configuration},
- * {@link ModuleDescriptor#isAutomatic() automatic} modules receive
- * <a href="../module/Configuration.html#automaticmoduleresolution">special
- * treatment</a> when creating a layer. An automatic module is created in the
+ * {@link ModuleDescriptor#isAutomatic() automatic} modules receive special
+ * treatment when creating a layer. An automatic module is created in the
* Java virtual machine as a {@code Module} that reads every unnamed {@code
* Module} in the Java virtual machine. </p>
*
@@ -115,8 +113,7 @@
*
* Layer parent = Layer.boot();
*
- * Configuration cf = parent.configuration()
- * .resolveRequires(finder, ModuleFinder.of(), Set.of("myapp"));
+ * Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));
*
* ClassLoader scl = ClassLoader.getSystemClassLoader();
*
@@ -126,6 +123,7 @@
* }</pre>
*
* @since 9
+ * @spec JPMS
* @see Module#getLayer()
*/
@@ -168,10 +166,15 @@
* module layers return a {@code Controller} that can be used to control
* modules in the layer.
*
+ * <p> Unless otherwise specified, passing a {@code null} argument to a
+ * method in this class causes a {@link NullPointerException
+ * NullPointerException} to be thrown. </p>
+ *
* @apiNote Care should be taken with {@code Controller} objects, they
* should never be shared with untrusted code.
*
* @since 9
+ * @spec JPMS
*/
public static final class Controller {
private final Layer layer;
@@ -281,10 +284,8 @@
* If the parent of the given configuration is not the configuration
* for this layer
* @throws LayerInstantiationException
- * If all modules cannot be defined to the same class loader for any
- * of the reasons listed above or the layer cannot be created because
- * the configuration contains a module named "{@code java.base}" or
- * a module with a package name starting with "{@code java.}"
+ * If the layer cannot be created for any of the reasons specified
+ * by the static {@code defineModulesWithOneLoader} method
* @throws SecurityException
* If {@code RuntimePermission("createClassLoader")} or
* {@code RuntimePermission("getClassLoader")} is denied by
@@ -325,9 +326,8 @@
* If the parent of the given configuration is not the configuration
* for this layer
* @throws LayerInstantiationException
- * If the layer cannot be created because the configuration contains
- * a module named "{@code java.base}" or a module with a package
- * name starting with "{@code java.}"
+ * If the layer cannot be created for any of the reasons specified
+ * by the static {@code defineModulesWithManyLoaders} method
* @throws SecurityException
* If {@code RuntimePermission("createClassLoader")} or
* {@code RuntimePermission("getClassLoader")} is denied by
@@ -365,14 +365,8 @@
* If the parent of the given configuration is not the configuration
* for this layer
* @throws LayerInstantiationException
- * If creating the {@code Layer} fails for any of the reasons
- * listed above, the layer cannot be created because the
- * configuration contains a module named "{@code java.base}",
- * a module with a package name starting with "{@code java.}" is
- * mapped to a class loader other than the {@link
- * ClassLoader#getPlatformClassLoader() platform class loader},
- * or the function to map a module name to a class loader returns
- * {@code null}
+ * If the layer cannot be created for any of the reasons specified
+ * by the static {@code defineModules} method
* @throws SecurityException
* If {@code RuntimePermission("getClassLoader")} is denied by
* the security manager
@@ -396,7 +390,6 @@
* exported to one or more of the modules in this layer. The class
* loader delegates to the class loader of the module, throwing {@code
* ClassNotFoundException} if not found by that class loader.
- *
* When {@code loadClass} is invoked to load classes that do not map to a
* module then it delegates to the parent class loader. </p>
*
@@ -414,6 +407,10 @@
*
* </ul>
*
+ * <p> In addition, a layer cannot be created if the configuration contains
+ * a module named "{@code java.base}" or a module with a package name
+ * starting with "{@code java.}". </p>
+ *
* <p> If there is a security manager then the class loader created by
* this method will load classes and resources with privileges that are
* restricted by the calling context of this method. </p>
@@ -433,9 +430,7 @@
* the parent layers, including order
* @throws LayerInstantiationException
* If all modules cannot be defined to the same class loader for any
- * of the reasons listed above or the layer cannot be created because
- * the configuration contains a module named "{@code java.base}" or
- * a module with a package name starting with "{@code java.}"
+ * of the reasons listed above
* @throws SecurityException
* If {@code RuntimePermission("createClassLoader")} or
* {@code RuntimePermission("getClassLoader")} is denied by
@@ -480,7 +475,6 @@
* module in a parent layer. The class loader delegates to the class loader
* of the module, throwing {@code ClassNotFoundException} if not found by
* that class loader.
- *
* When {@code loadClass} is invoked to load classes that do not map to a
* module then it delegates to the parent class loader. </p>
*
@@ -533,15 +527,19 @@
/**
* Creates a new layer by defining the modules in the given {@code
- * Configuration} to the Java virtual machine.
- * Each module is mapped, by name, to its class loader by means of the
- * given function. The class loader delegation implemented by these class
- * loaders must respect module readability. The class loaders should be
+ * Configuration} to the Java virtual machine. The given function maps each
+ * module in the configuration, by name, to a class loader. Creating the
+ * layer informs the Java virtual machine about the classes that may be
+ * loaded so that the Java virtual machine knows which module that each
+ * class is a member of.
+ *
+ * <p> The class loader delegation implemented by the class loaders must
+ * respect module readability. The class loaders should be
* {@link ClassLoader#registerAsParallelCapable parallel-capable} so as to
* avoid deadlocks during class loading. In addition, the entity creating
- * a new layer with this method should arrange that the class loaders are
+ * a new layer with this method should arrange that the class loaders be
* ready to load from these modules before there are any attempts to load
- * classes or resources.
+ * classes or resources. </p>
*
* <p> Creating a {@code Layer} can fail for the following reasons: </p>
*
@@ -558,6 +556,13 @@
*
* </ul>
*
+ * <p> In addition, a layer cannot be created if the configuration contains
+ * a module named "{@code java.base}", a configuration contains a module
+ * with a package name starting with "{@code java.}" is mapped to a class
+ * loader other than the {@link ClassLoader#getPlatformClassLoader()
+ * platform class loader}, or the function to map a module name to a class
+ * loader returns {@code null}. </p>
+ *
* <p> If the function to map a module name to class loader throws an error
* or runtime exception then it is propagated to the caller of this method.
* </p>
@@ -565,7 +570,7 @@
* @apiNote It is implementation specific as to whether creating a Layer
* with this method is an atomic operation or not. Consequentially it is
* possible for this method to fail with some modules, but not all, defined
- * to Java virtual machine.
+ * to the Java virtual machine.
*
* @param cf
* The configuration for the layer
@@ -580,14 +585,7 @@
* If the parent configurations do not match the configuration of
* the parent layers, including order
* @throws LayerInstantiationException
- * If creating the {@code Layer} fails for any of the reasons
- * listed above, the layer cannot be created because the
- * configuration contains a module named "{@code java.base}",
- * a module with a package name starting with "{@code java.}" is
- * mapped to a class loader other than the {@link
- * ClassLoader#getPlatformClassLoader() platform class loader},
- * or the function to map a module name to a class loader returns
- * {@code null}
+ * If creating the layer fails for any of the reasons listed above
* @throws SecurityException
* If {@code RuntimePermission("getClassLoader")} is denied by
* the security manager
@@ -763,7 +761,7 @@
/**
* Returns the module with the given name in this layer, or if not in this
- * layer, the {@linkplain #parents parents} layers. Finding a module in
+ * layer, the {@linkplain #parents parent} layers. Finding a module in
* parent layers is equivalent to invoking {@code findModule} on each
* parent, in search order, until the module is found or all parents have
* been searched. In a <em>tree of layers</em> then this is equivalent to
--- a/jdk/src/java.base/share/classes/java/lang/reflect/LayerInstantiationException.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/LayerInstantiationException.java Wed Jul 05 22:52:22 2017 +0200
@@ -31,6 +31,7 @@
* @see Layer
*
* @since 9
+ * @spec JPMS
*/
public class LayerInstantiationException extends RuntimeException {
private static final long serialVersionUID = -906239691613568347L;
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Wed Jul 05 22:52:22 2017 +0200
@@ -179,6 +179,10 @@
return res;
}
+ /**
+ * @throws InaccessibleObjectException {@inheritDoc}
+ * @throws SecurityException {@inheritDoc}
+ */
@Override
@CallerSensitive
public void setAccessible(boolean flag) {
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Module.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Module.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,7 +39,6 @@
import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -74,16 +73,15 @@
* Java Virtual Machine when a graph of modules is defined to the Java virtual
* machine to create a module {@link Layer Layer}. </p>
*
- * <p> An unnamed module does not have a name. There is an unnamed module
- * per {@link ClassLoader ClassLoader} that is obtained by invoking the class
- * loader's {@link ClassLoader#getUnnamedModule() getUnnamedModule} method. The
- * {@link Class#getModule() getModule} method of all types defined by a class
- * loader that are not in a named module return the class loader's unnamed
+ * <p> An unnamed module does not have a name. There is an unnamed module for
+ * each {@link ClassLoader ClassLoader}, obtained by invoking its {@link
+ * ClassLoader#getUnnamedModule() getUnnamedModule} method. All types that are
+ * not in a named module are members of their defining class loader's unnamed
* module. </p>
*
* <p> The package names that are parameters or returned by methods defined in
* this class are the fully-qualified names of the packages as defined in
- * section 6.5.3 of <cite>The Java™ Language Specification </cite>, for
+ * section 6.5.3 of <cite>The Java™ Language Specification</cite>, for
* example, {@code "java.lang"}. </p>
*
* <p> Unless otherwise specified, passing a {@code null} argument to a method
@@ -91,6 +89,7 @@
* be thrown. </p>
*
* @since 9
+ * @spec JPMS
* @see java.lang.Class#getModule
*/
@@ -327,8 +326,9 @@
*
* @return this module
*
- * @throws IllegalStateException
- * If this is a named module and the caller is not this module
+ * @throws IllegalCallerException
+ * If this is a named module and the caller's module is not this
+ * module
*
* @see #canRead
*/
@@ -338,7 +338,7 @@
if (this.isNamed()) {
Module caller = Reflection.getCallerClass().getModule();
if (caller != this) {
- throw new IllegalStateException(caller + " != " + this);
+ throw new IllegalCallerException(caller + " != " + this);
}
implAddReads(other, true);
}
@@ -533,8 +533,8 @@
if (other == this && containsPackage(pn))
return true;
- // all packages in open modules are open
- if (descriptor.isOpen())
+ // all packages in open and automatic modules are open
+ if (descriptor.isOpen() || descriptor.isAutomatic())
return containsPackage(pn);
// exported/opened via module declaration/descriptor
@@ -634,8 +634,7 @@
* the given package to the given module.
*
* <p> This method has no effect if the package is already exported (or
- * <em>open</em>) to the given module. It also has no effect if
- * invoked on an {@link ModuleDescriptor#isOpen open} module. </p>
+ * <em>open</em>) to the given module. </p>
*
* @apiNote As specified in section 5.4.3 of the <cite>The Java™
* Virtual Machine Specification </cite>, if an attempt to resolve a
@@ -653,8 +652,9 @@
* @throws IllegalArgumentException
* If {@code pn} is {@code null}, or this is a named module and the
* package {@code pn} is not a package in this module
- * @throws IllegalStateException
- * If this is a named module and the caller is not this module
+ * @throws IllegalCallerException
+ * If this is a named module and the caller's module is not this
+ * module
*
* @jvms 5.4.3 Resolution
* @see #isExported(String,Module)
@@ -665,10 +665,10 @@
throw new IllegalArgumentException("package is null");
Objects.requireNonNull(other);
- if (isNamed() && !descriptor.isOpen()) {
+ if (isNamed()) {
Module caller = Reflection.getCallerClass().getModule();
if (caller != this) {
- throw new IllegalStateException(caller + " != " + this);
+ throw new IllegalCallerException(caller + " != " + this);
}
implAddExportsOrOpens(pn, other, /*open*/false, /*syncVM*/true);
}
@@ -686,8 +686,7 @@
* access control checks.
*
* <p> This method has no effect if the package is already <em>open</em>
- * to the given module. It also has no effect if invoked on an {@link
- * ModuleDescriptor#isOpen open} module. </p>
+ * to the given module. </p>
*
* @param pn
* The package name
@@ -699,9 +698,9 @@
* @throws IllegalArgumentException
* If {@code pn} is {@code null}, or this is a named module and the
* package {@code pn} is not a package in this module
- * @throws IllegalStateException
+ * @throws IllegalCallerException
* If this is a named module and this module has not opened the
- * package to at least the caller
+ * package to at least the caller's module
*
* @see #isOpen(String,Module)
* @see AccessibleObject#setAccessible(boolean)
@@ -713,10 +712,10 @@
throw new IllegalArgumentException("package is null");
Objects.requireNonNull(other);
- if (isNamed() && !descriptor.isOpen()) {
+ if (isNamed()) {
Module caller = Reflection.getCallerClass().getModule();
if (caller != this && !isOpen(pn, caller))
- throw new IllegalStateException(pn + " is not open to " + caller);
+ throw new IllegalCallerException(pn + " is not open to " + caller);
implAddExportsOrOpens(pn, other, /*open*/true, /*syncVM*/true);
}
@@ -767,8 +766,8 @@
Objects.requireNonNull(other);
Objects.requireNonNull(pn);
- // all packages are open in unnamed and open modules
- if (!isNamed() || descriptor.isOpen())
+ // all packages are open in unnamed, open, and automatic modules
+ if (!isNamed() || descriptor.isOpen() || descriptor.isAutomatic())
return;
// nothing to do if already exported/open to other
@@ -819,17 +818,17 @@
* passed a reference to the service type by other code. This method is
* a no-op when invoked on an unnamed module or an automatic module.
*
- * <p> This method does not cause {@link
- * Configuration#resolveRequiresAndUses resolveRequiresAndUses} to be
- * re-run. </p>
+ * <p> This method does not cause {@link Configuration#resolveAndBind
+ * resolveAndBind} to be re-run. </p>
*
* @param service
* The service type
*
* @return this module
*
- * @throws IllegalStateException
- * If this is a named module and the caller is not this module
+ * @throws IllegalCallerException
+ * If this is a named module and the caller's module is not this
+ * module
*
* @see #canUse(Class)
* @see ModuleDescriptor#uses()
@@ -841,7 +840,7 @@
if (isNamed() && !descriptor.isAutomatic()) {
Module caller = Reflection.getCallerClass().getModule();
if (caller != this) {
- throw new IllegalStateException(caller + " != " + this);
+ throw new IllegalCallerException(caller + " != " + this);
}
implAddUses(service);
}
@@ -894,14 +893,13 @@
// -- packages --
// Additional packages that are added to the module at run-time.
- // The field is volatile as it may be replaced at run-time
- private volatile Set<String> extraPackages;
+ private volatile Map<String, Boolean> extraPackages;
private boolean containsPackage(String pn) {
if (descriptor.packages().contains(pn))
return true;
- Set<String> extraPackages = this.extraPackages;
- if (extraPackages != null && extraPackages.contains(pn))
+ Map<String, Boolean> extraPackages = this.extraPackages;
+ if (extraPackages != null && extraPackages.containsKey(pn))
return true;
return false;
}
@@ -915,7 +913,7 @@
* added to the module, <a href="Proxy.html#dynamicmodule">dynamic modules</a>
* for example, after it was loaded.
*
- * <p> For unnamed modules, this method is the equivalent of invoking the
+ * <p> For unnamed modules, this method is the equivalent to invoking the
* {@link ClassLoader#getDefinedPackages() getDefinedPackages} method of
* this module's class loader and returning the array of package names. </p>
*
@@ -930,12 +928,12 @@
if (isNamed()) {
Set<String> packages = descriptor.packages();
- Set<String> extraPackages = this.extraPackages;
+ Map<String, Boolean> extraPackages = this.extraPackages;
if (extraPackages == null) {
return packages.toArray(new String[0]);
} else {
return Stream.concat(packages.stream(),
- extraPackages.stream())
+ extraPackages.keySet().stream())
.toArray(String[]::new);
}
@@ -955,10 +953,6 @@
* Add a package to this module.
*
* @apiNote This method is for Proxy use.
- *
- * @apiNote This is an expensive operation, not expected to be used often.
- * At this time then it does not validate that the package name is a
- * valid java identifier.
*/
void addPackage(String pn) {
implAddPackage(pn, true);
@@ -976,49 +970,52 @@
/**
* Add a package to this module.
*
- * If {@code syncVM} is {@code true} then the VM is notified.
+ * If {@code syncVM} is {@code true} then the VM is notified. This method is
+ * a no-op if this is an unnamed module or the module already contains the
+ * package.
+ *
+ * @throws IllegalArgumentException if the package name is not legal
+ * @throws IllegalStateException if the package is defined to another module
*/
private void implAddPackage(String pn, boolean syncVM) {
+ // no-op if unnamed module
if (!isNamed())
- throw new InternalError("adding package to unnamed module?");
- if (descriptor.isOpen())
- throw new InternalError("adding package to open module?");
+ return;
+
+ // no-op if module contains the package
+ if (containsPackage(pn))
+ return;
+
+ // check package name is legal for named modules
if (pn.isEmpty())
- throw new InternalError("adding <unnamed> package to module?");
-
- if (descriptor.packages().contains(pn)) {
- // already in module
- return;
+ throw new IllegalArgumentException("Cannot add <unnamed> package");
+ for (int i=0; i<pn.length(); i++) {
+ char c = pn.charAt(i);
+ if (c == '/' || c == ';' || c == '[') {
+ throw new IllegalArgumentException("Illegal character: " + c);
+ }
}
- Set<String> extraPackages = this.extraPackages;
- if (extraPackages != null && extraPackages.contains(pn)) {
- // already added
- return;
+ // create extraPackages if needed
+ Map<String, Boolean> extraPackages = this.extraPackages;
+ if (extraPackages == null) {
+ synchronized (this) {
+ extraPackages = this.extraPackages;
+ if (extraPackages == null)
+ this.extraPackages = extraPackages = new ConcurrentHashMap<>();
+ }
}
- synchronized (this) {
- // recheck under lock
- extraPackages = this.extraPackages;
- if (extraPackages != null) {
- if (extraPackages.contains(pn)) {
- // already added
- return;
- }
- // copy the set
- extraPackages = new HashSet<>(extraPackages);
- extraPackages.add(pn);
- } else {
- extraPackages = Collections.singleton(pn);
+ // update VM first in case it fails. This is a no-op if another thread
+ // beats us to add the package first
+ if (syncVM) {
+ // throws IllegalStateException if defined to another module
+ addPackage0(this, pn);
+ if (descriptor.isOpen() || descriptor.isAutomatic()) {
+ addExportsToAll0(this, pn);
}
-
- // update VM first, just in case it fails
- if (syncVM)
- addPackage0(this, pn);
-
- // replace with new set
- this.extraPackages = extraPackages; // volatile write
}
+ extraPackages.putIfAbsent(pn, Boolean.TRUE);
}
@@ -1169,8 +1166,9 @@
Map<String, Module> nameToModule,
Module m)
{
- // The VM doesn't know about open modules so need to export all packages
- if (descriptor.isOpen()) {
+ // The VM doesn't special case open or automatic modules so need to
+ // export all packages
+ if (descriptor.isOpen() || descriptor.isAutomatic()) {
assert descriptor.opens().isEmpty();
for (String source : descriptor.packages()) {
addExportsToAll0(m, source);
@@ -1375,35 +1373,44 @@
/**
- * Returns an input stream for reading a resource in this module. The
- * {@code name} parameter is a {@code '/'}-separated path name that
- * identifies the resource.
+ * Returns an input stream for reading a resource in this module.
+ * The {@code name} parameter is a {@code '/'}-separated path name that
+ * identifies the resource. As with {@link Class#getResourceAsStream
+ * Class.getResourceAsStream}, this method delegates to the module's class
+ * loader {@link ClassLoader#findResource(String,String)
+ * findResource(String,String)} method, invoking it with the module name
+ * (or {@code null} when the module is unnamed) and the name of the
+ * resource. If the resource name has a leading slash then it is dropped
+ * before delegation.
*
- * <p> A resource in a named modules may be <em>encapsulated</em> so that
+ * <p> A resource in a named module may be <em>encapsulated</em> so that
* it cannot be located by code in other modules. Whether a resource can be
- * located or not is determined as follows:
+ * located or not is determined as follows: </p>
*
* <ul>
- * <li> The <em>package name</em> of the resource is derived from the
- * subsequence of characters that precedes the last {@code '/'} and then
- * replacing each {@code '/'} character in the subsequence with
- * {@code '.'}. For example, the package name derived for a resource
- * named "{@code a/b/c/foo.properties}" is "{@code a.b.c}". </li>
+ * <li> If the resource name ends with "{@code .class}" then it is not
+ * encapsulated. </li>
*
- * <li> If the package name is a package in the module then the package
- * must be {@link #isOpen open} the module of the caller of this method.
- * If the package is not in the module then the resource is not
- * encapsulated. Resources in the unnamed package or "{@code META-INF}",
- * for example, are never encapsulated because they can never be
- * packages in a named module. </li>
+ * <li> A <em>package name</em> is derived from the resource name. If
+ * the package name is a {@link #getPackages() package} in the module
+ * then the resource can only be located by the caller of this method
+ * when the package is {@link #isOpen(String,Module) open} to at least
+ * the caller's module. If the resource is not in a package in the module
+ * then the resource is not encapsulated. </li>
+ * </ul>
*
- * <li> As a special case, resources ending with "{@code .class}" are
- * never encapsulated. </li>
- * </ul>
+ * <p> In the above, the <em>package name</em> for a resource is derived
+ * from the subsequence of characters that precedes the last {@code '/'} in
+ * the name and then replacing each {@code '/'} character in the subsequence
+ * with {@code '.'}. A leading slash is ignored when deriving the package
+ * name. As an example, the package name derived for a resource named
+ * "{@code a/b/c/foo.properties}" is "{@code a.b.c}". A resource name
+ * with the name "{@code META-INF/MANIFEST.MF}" is never encapsulated
+ * because "{@code META-INF}" is not a legal package name. </p>
*
* <p> This method returns {@code null} if the resource is not in this
* module, the resource is encapsulated and cannot be located by the caller,
- * or access to the resource is denied by the security manager.
+ * or access to the resource is denied by the security manager. </p>
*
* @param name
* The resource name
@@ -1413,11 +1420,13 @@
* @throws IOException
* If an I/O error occurs
*
- * @see java.lang.module.ModuleReader#open(String)
+ * @see Class#getResourceAsStream(String)
*/
@CallerSensitive
public InputStream getResourceAsStream(String name) throws IOException {
- Objects.requireNonNull(name);
+ if (name.startsWith("/")) {
+ name = name.substring(1);
+ }
if (isNamed() && !ResourceHelper.isSimpleResource(name)) {
Module caller = Reflection.getCallerClass().getModule();
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Proxy.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,7 @@
package java.lang.reflect;
+import java.lang.module.ModuleDescriptor;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
@@ -52,6 +53,9 @@
import sun.security.action.GetPropertyAction;
import sun.security.util.SecurityConstants;
+import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
+
+
/**
*
* {@code Proxy} provides static methods for creating objects that act like instances
@@ -164,7 +168,8 @@
* methods is specified as follows:
*
* <ol>
- * <li>If all the proxy interfaces are in <em>exported</em> packages:
+ * <li>If all the proxy interfaces are in <em>exported</em> or <em>open</em>
+ * packages:
* <ol type="a">
* <li>if all the proxy interfaces are <em>public</em>, then the proxy class is
* <em>public</em> in a package exported by the
@@ -178,10 +183,11 @@
* <a href="#restrictions">not possible</a>.</li>
* </ol>
* </li>
- * <li>If at least one proxy interface is a <em>non-exported</em> package:
+ * <li>If at least one proxy interface is in a package that is
+ * <em>non-exported</em> and <em>non-open</em>:
* <ol type="a">
* <li>if all the proxy interfaces are <em>public</em>, then the proxy class is
- * <em>public</em> in a <em>non-exported</em> package of
+ * <em>public</em> in a <em>non-exported</em>, <em>non-open</em> package of
* <a href="#dynamicmodule"><em>dynamic module</em>.</a>
* The names of the package and the module are unspecified.</li>
*
@@ -195,21 +201,22 @@
* </ol>
*
* <p>
- * Note that if proxy interfaces with a mix of accessibilities --
- * exported public, exported non-public, non-exported public, non-exported non-public --
- * are proxied by the same instance, then the proxy class's accessibility is
+ * Note that if proxy interfaces with a mix of accessibilities -- for example,
+ * an exported public interface and a non-exported non-public interface -- are
+ * proxied by the same instance, then the proxy class's accessibility is
* governed by the least accessible proxy interface.
* <p>
* Note that it is possible for arbitrary code to obtain access to a proxy class
- * in an exported package with {@link AccessibleObject#setAccessible setAccessible},
- * whereas a proxy class in a non-exported package is never accessible to
+ * in an open package with {@link AccessibleObject#setAccessible setAccessible},
+ * whereas a proxy class in a non-open package is never accessible to
* code outside the module of the proxy class.
*
* <p>
- * Throughout this specification, a "non-exported package" refers to a package that
- * is not exported to all modules. Specifically, it refers to a package that
- * either is not exported at all by its containing module or is exported in a
- * qualified fashion by its containing module.
+ * Throughout this specification, a "non-exported package" refers to a package
+ * that is not exported to all modules, and a "non-open package" refers to
+ * a package that is not open to all modules. Specifically, these terms refer to
+ * a package that either is not exported/open by its containing module or is
+ * exported/open in a qualified fashion by its containing module.
*
* <h3><a name="dynamicmodule">Dynamic Modules</a></h3>
* <p>
@@ -272,6 +279,8 @@
* @author Peter Jones
* @see InvocationHandler
* @since 1.3
+ * @revised 9
+ * @spec JPMS
*/
public class Proxy implements java.io.Serializable {
private static final long serialVersionUID = -2222568056686623797L;
@@ -358,6 +367,8 @@
* to create a proxy instance instead.
*
* @see <a href="#membership">Package and Module Membership of Proxy Class</a>
+ * @revised 9
+ * @spec JPMS
*/
@Deprecated
@CallerSensitive
@@ -855,7 +866,11 @@
// create a dynamic module and setup module access
String mn = "jdk.proxy" + counter.incrementAndGet();
String pn = PROXY_PACKAGE_PREFIX + "." + mn;
- Module m = Modules.defineModule(ld, mn, Collections.singleton(pn));
+ ModuleDescriptor descriptor =
+ ModuleDescriptor.newModule(mn, Set.of(SYNTHETIC))
+ .packages(Set.of(pn))
+ .build();
+ Module m = Modules.defineModule(ld, descriptor, null);
Modules.addReads(m, Proxy.class.getModule());
// java.base to create proxy instance
Modules.addExports(m, pn, Object.class.getModule());
@@ -955,6 +970,8 @@
* {@code null}
*
* @see <a href="#membership">Package and Module Membership of Proxy Class</a>
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader,
@@ -1039,6 +1056,9 @@
* @return {@code true} if the class is a proxy class and
* {@code false} otherwise
* @throws NullPointerException if {@code cl} is {@code null}
+ *
+ * @revised 9
+ * @spec JPMS
*/
public static boolean isProxyClass(Class<?> cl) {
return Proxy.class.isAssignableFrom(cl) && ProxyBuilder.isProxyClass(cl);
--- a/jdk/src/java.base/share/classes/java/lang/reflect/package-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/package-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -45,5 +45,7 @@
* members declared by a given class.
*
* @since 1.1
+ * @revised 9
+ * @spec JPMS
*/
package java.lang.reflect;
--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Wed Jul 05 22:52:22 2017 +0200
@@ -228,6 +228,7 @@
* allow creation of a class loader.
*
* @since 9
+ * @spec JPMS
*/
public URLClassLoader(String name,
URL[] urls,
@@ -262,6 +263,7 @@
* creation of a class loader.
*
* @since 9
+ * @spec JPMS
*/
public URLClassLoader(String name, URL[] urls, ClassLoader parent,
URLStreamHandlerFactory factory) {
@@ -558,6 +560,9 @@
* @throws IllegalArgumentException if the package name is
* already defined by this class loader
* @return the newly defined {@code Package} object
+ *
+ * @revised 9
+ * @spec JPMS
*/
protected Package definePackage(String name, Manifest man, URL url) {
String path = name.replace('.', '/').concat("/");
--- a/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/security/SecureClassLoader.java Wed Jul 05 22:52:22 2017 +0200
@@ -125,6 +125,7 @@
* doesn't allow creation of a class loader.
*
* @since 9
+ * @spec JPMS
*/
protected SecureClassLoader(String name, ClassLoader parent) {
super(name, parent);
--- a/jdk/src/java.base/share/classes/java/security/Security.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/security/Security.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,11 +25,12 @@
package java.security;
-import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.io.*;
import java.net.URL;
+
+import jdk.internal.misc.SharedSecrets;
import sun.security.util.Debug;
import sun.security.util.PropertyExpander;
@@ -800,9 +801,6 @@
* "package.definition", we need to signal to the SecurityManager
* class that the value has just changed, and that it should
* invalidate it's local cache values.
- *
- * Rather than create a new API entry for this function,
- * we use reflection to set a private variable.
*/
private static void invalidateSMCache(String key) {
@@ -810,42 +808,8 @@
final boolean pd = key.equals("package.definition");
if (pa || pd) {
- AccessController.doPrivileged(new PrivilegedAction<>() {
- public Void run() {
- try {
- /* Get the class via the bootstrap class loader. */
- Class<?> cl = Class.forName(
- "java.lang.SecurityManager", false, null);
- Field f = null;
- boolean accessible = false;
-
- if (pa) {
- f = cl.getDeclaredField("packageAccessValid");
- accessible = f.isAccessible();
- f.setAccessible(true);
- } else {
- f = cl.getDeclaredField("packageDefinitionValid");
- accessible = f.isAccessible();
- f.setAccessible(true);
- }
- f.setBoolean(f, false);
- f.setAccessible(accessible);
- }
- catch (Exception e1) {
- /* If we couldn't get the class, it hasn't
- * been loaded yet. If there is no such
- * field, we shouldn't try to set it. There
- * shouldn't be a security execption, as we
- * are loaded by boot class loader, and we
- * are inside a doPrivileged() here.
- *
- * NOOP: don't do anything...
- */
- }
- return null;
- } /* run */
- }); /* PrivilegedAction */
- } /* if */
+ SharedSecrets.getJavaLangAccess().invalidatePackageAccessCache();
+ }
}
private static void check(String directive) {
--- a/jdk/src/java.base/share/classes/java/util/ResourceBundle.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/ResourceBundle.java Wed Jul 05 22:52:22 2017 +0200
@@ -350,6 +350,8 @@
* @see MissingResourceException
* @see ResourceBundleProvider
* @since 1.1
+ * @revised 9
+ * @spec JPMS
*/
public abstract class ResourceBundle {
@@ -870,6 +872,8 @@
* @throws UnsupportedOperationException
* if this method is called in a named module
* @since 1.6
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public static final ResourceBundle getBundle(String baseName,
@@ -938,6 +942,7 @@
* specified module
* @return a resource bundle for the given base name and the default locale
* @since 9
+ * @spec JPMS
* @see ResourceBundleProvider
*/
@CallerSensitive
@@ -991,6 +996,7 @@
* be found in the specified {@code module}
* @return a resource bundle for the given base name and locale in the module
* @since 9
+ * @spec JPMS
*/
@CallerSensitive
public static ResourceBundle getBundle(String baseName, Locale targetLocale, Module module) {
@@ -1036,6 +1042,8 @@
* @throws UnsupportedOperationException
* if this method is called in a named module
* @since 1.6
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public static final ResourceBundle getBundle(String baseName, Locale targetLocale,
@@ -1243,6 +1251,8 @@
* @exception MissingResourceException
* if no resource bundle for the specified base name can be found
* @since 1.2
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public static ResourceBundle getBundle(String baseName, Locale locale,
@@ -1465,6 +1475,8 @@
* @throws UnsupportedOperationException
* if this method is called in a named module
* @since 1.6
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public static ResourceBundle getBundle(String baseName, Locale targetLocale,
@@ -2194,6 +2206,8 @@
* by the caller's module.
*
* @since 1.6
+ * @revised 9
+ * @spec JPMS
* @see ResourceBundle.Control#getTimeToLive(String,Locale)
*/
@CallerSensitive
@@ -2475,6 +2489,8 @@
* of {@link ResourceBundleControlProvider} are ignored in named modules.
*
* @since 1.6
+ * @revised 9
+ * @spec JPMS
* @see java.util.spi.ResourceBundleProvider
*/
public static class Control {
@@ -3103,6 +3119,8 @@
* if an error occurred when reading resources using
* any I/O operations
* @see java.util.spi.ResourceBundleProvider#getBundle(String, Locale)
+ * @revised 9
+ * @spec JPMS
*/
public ResourceBundle newBundle(String baseName, Locale locale, String format,
ClassLoader loader, boolean reload)
--- a/jdk/src/java.base/share/classes/java/util/ServiceLoader.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/ServiceLoader.java Wed Jul 05 22:52:22 2017 +0200
@@ -119,7 +119,7 @@
* and deployed as an explicit module must have an appropriate <i>uses</i>
* clause in its <i>module descriptor</i> to declare that the module uses
* implementations of the service. A corresponding requirement is that a
- * provider deployed as a named module must have an appropriate
+ * provider deployed as an explicit module must have an appropriate
* <i>provides</i> clause in its module descriptor to declare that the module
* provides an implementation of the service. The <i>uses</i> and
* <i>provides</i> allow consumers of a service to be <i>linked</i> to modules
@@ -203,8 +203,11 @@
* ordering of modules in a layer, is not defined. </li>
*
* <li> If a named module declares more than one provider then the providers
- * are located in the order that they appear in the {@code provides} table of
- * the {@code Module} class file attribute ({@code module-info.class}). </li>
+ * are located in the iteration order of the {@link
+ * java.lang.module.ModuleDescriptor.Provides#providers() providers} list.
+ * Providers added dynamically by instrumentation agents ({@link
+ * java.lang.instrument.Instrumentation#redefineModule redefineModule})
+ * are always located after providers declared by the module. </li>
*
* <li> When locating providers in unnamed modules then the ordering is
* based on the order that the class loader's {@link
@@ -335,6 +338,8 @@
*
* @author Mark Reinhold
* @since 1.6
+ * @revised 9
+ * @spec JPMS
*/
public final class ServiceLoader<S>
@@ -386,6 +391,7 @@
*
* @param <S> The service type
* @since 9
+ * @spec JPMS
*/
public static interface Provider<S> extends Supplier<S> {
/**
@@ -927,26 +933,28 @@
} else {
catalog = ServicesCatalog.getServicesCatalogOrNull(loader);
}
- Stream<ServiceProvider> stream1;
+ List<ServiceProvider> providers;
if (catalog == null) {
- stream1 = Stream.empty();
+ providers = List.of();
} else {
- stream1 = catalog.findServices(serviceName).stream();
+ providers = catalog.findServices(serviceName);
}
// modules in custom layers that define modules to the class loader
- Stream<ServiceProvider> stream2;
if (loader == null) {
- stream2 = Stream.empty();
+ return providers.iterator();
} else {
+ List<ServiceProvider> allProviders = new ArrayList<>(providers);
Layer bootLayer = Layer.boot();
- stream2 = JLRM_ACCESS.layers(loader)
- .filter(l -> (l != bootLayer))
- .map(l -> providers(l))
- .flatMap(List::stream);
+ Iterator<Layer> iterator = JLRM_ACCESS.layers(loader).iterator();
+ while (iterator.hasNext()) {
+ Layer layer = iterator.next();
+ if (layer != bootLayer) {
+ allProviders.addAll(providers(layer));
+ }
+ }
+ return allProviders.iterator();
}
-
- return Stream.concat(stream1, stream2).iterator();
}
@Override
@@ -1214,6 +1222,9 @@
*
* @return An iterator that lazily loads providers for this loader's
* service
+ *
+ * @revised 9
+ * @spec JPMS
*/
public Iterator<S> iterator() {
@@ -1279,8 +1290,10 @@
* provider to be loaded. </p>
*
* <p> If this loader's provider caches are cleared by invoking the {@link
- * #reload() reload} method then existing streams for this service
- * loader should be discarded. </p>
+ * #reload() reload} method then existing streams for this service loader
+ * should be discarded. The returned stream's source {@code Spliterator} is
+ * <em>fail-fast</em> and will throw {@link ConcurrentModificationException}
+ * if the provider cache has been cleared. </p>
*
* <p> The following examples demonstrate usage. The first example
* creates a stream of providers, the second example is the same except
@@ -1300,6 +1313,7 @@
* @return A stream that lazily loads providers for this loader's service
*
* @since 9
+ * @spec JPMS
*/
public Stream<Provider<S>> stream() {
// use cached providers as the source when all providers loaded
@@ -1414,6 +1428,9 @@
* if the service type is not accessible to the caller or the
* caller is in an explicit module and its module descriptor does
* not declare that it uses {@code service}
+ *
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public static <S> ServiceLoader<S> load(Class<S> service,
@@ -1457,6 +1474,9 @@
* if the service type is not accessible to the caller or the
* caller is in an explicit module and its module descriptor does
* not declare that it uses {@code service}
+ *
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public static <S> ServiceLoader<S> load(Class<S> service) {
@@ -1490,6 +1510,9 @@
* if the service type is not accessible to the caller or the
* caller is in an explicit module and its module descriptor does
* not declare that it uses {@code service}
+ *
+ * @revised 9
+ * @spec JPMS
*/
@CallerSensitive
public static <S> ServiceLoader<S> loadInstalled(Class<S> service) {
@@ -1522,6 +1545,7 @@
* not declare that it uses {@code service}
*
* @since 9
+ * @spec JPMS
*/
@CallerSensitive
public static <S> ServiceLoader<S> load(Layer layer, Class<S> service) {
@@ -1551,6 +1575,7 @@
* or error is thrown when locating or instantiating the provider.
*
* @since 9
+ * @spec JPMS
*/
public Optional<S> findFirst() {
Iterator<S> iterator = iterator();
--- a/jdk/src/java.base/share/classes/java/util/spi/AbstractResourceBundleProvider.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/spi/AbstractResourceBundleProvider.java Wed Jul 05 22:52:22 2017 +0200
@@ -81,6 +81,7 @@
* ResourceBundleProvider Service Providers</a>
*
* @since 9
+ * @spec JPMS
*/
public abstract class AbstractResourceBundleProvider implements ResourceBundleProvider {
private static final JavaUtilResourceBundleAccess RB_ACCESS =
--- a/jdk/src/java.base/share/classes/java/util/spi/ResourceBundleControlProvider.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/spi/ResourceBundleControlProvider.java Wed Jul 05 22:52:22 2017 +0200
@@ -44,6 +44,8 @@
*
* @author Masayoshi Okutsu
* @since 1.8
+ * @revised 9
+ * @spec JPMS
* @see ResourceBundle#getBundle(String, java.util.Locale, ClassLoader, ResourceBundle.Control)
* ResourceBundle.getBundle
* @see java.util.ServiceLoader#load(Class)
--- a/jdk/src/java.base/share/classes/java/util/spi/ResourceBundleProvider.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/java/util/spi/ResourceBundleProvider.java Wed Jul 05 22:52:22 2017 +0200
@@ -57,6 +57,7 @@
* @see <a href="../ResourceBundle.html#RBP_support">
* ResourceBundleProvider Service Providers</a>
* @since 9
+ * @spec JPMS
*/
public interface ResourceBundleProvider {
/**
--- a/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Wed Jul 05 22:52:22 2017 +0200
@@ -78,7 +78,7 @@
HEADER_FILES("include"),
LEGAL_NOTICES("legal"),
MAN_PAGES("man"),
- NATIVE_LIBS("native"),
+ NATIVE_LIBS("lib"),
NATIVE_CMDS("bin");
private final String jmodDir;
@@ -186,7 +186,7 @@
public Entry getEntry(Section section, String name) {
String entry = section.jmodDir() + "/" + name;
ZipEntry ze = zipfile.getEntry(entry);
- return (ze != null) ? new Entry(ze) : null;
+ return (ze == null || ze.isDirectory()) ? null : new Entry(ze);
}
/**
@@ -201,7 +201,7 @@
{
String entry = section.jmodDir() + "/" + name;
ZipEntry e = zipfile.getEntry(entry);
- if (e == null) {
+ if (e == null || e.isDirectory()) {
throw new IOException(name + " not found: " + file);
}
return zipfile.getInputStream(e);
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java Wed Jul 05 22:52:22 2017 +0200
@@ -57,8 +57,9 @@
import java.util.jar.Manifest;
import java.util.stream.Stream;
+import jdk.internal.misc.VM;
import jdk.internal.module.ModulePatcher.PatchedModuleReader;
-import jdk.internal.misc.VM;
+import jdk.internal.module.SystemModules;
/**
@@ -135,7 +136,7 @@
// maps package name to loaded module for modules in the boot layer
private static final Map<String, LoadedModule> packageToModule
- = new ConcurrentHashMap<>(1024);
+ = new ConcurrentHashMap<>(SystemModules.PACKAGES_IN_BOOT_LAYER);
// maps a module name to a module reference
private final Map<String, ModuleReference> nameToModule;
@@ -922,13 +923,13 @@
* Returns the ModuleReader for the given module.
*/
private ModuleReader moduleReaderFor(ModuleReference mref) {
- return moduleToReader.computeIfAbsent(mref, m -> createModuleReader(mref));
+ return moduleToReader.computeIfAbsent(mref, BuiltinClassLoader::createModuleReader);
}
/**
* Creates a ModuleReader for the given module.
*/
- private ModuleReader createModuleReader(ModuleReference mref) {
+ private static ModuleReader createModuleReader(ModuleReference mref) {
try {
return mref.open();
} catch (IOException e) {
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/ResourceHelper.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/ResourceHelper.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,10 @@
*/
package jdk.internal.loader;
+import java.io.File;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
import jdk.internal.module.Checks;
/**
@@ -34,7 +38,8 @@
private ResourceHelper() { }
/**
- * Returns the <em>package name</em> for a resource.
+ * Returns the <em>package name</em> for a resource or the empty package if
+ * the resource name does not contain a slash.
*/
public static String getPackageName(String name) {
int index = name.lastIndexOf('/');
@@ -46,19 +51,75 @@
}
/**
- * Returns true if the resource is a <em>simple resource</em> that can
- * never be encapsulated. Resources ending in "{@code .class}" or where
- * the package name is not a Java identifier are resources that can
- * never be encapsulated.
+ * Returns true if the resource is a <em>simple resource</em>. Simple
+ * resources can never be encapsulated. Resources ending in "{@code .class}"
+ * or where the package name is not a legal package name can not be
+ * encapsulated.
*/
public static boolean isSimpleResource(String name) {
int len = name.length();
if (len > 6 && name.endsWith(".class")) {
return true;
}
- if (!Checks.isJavaIdentifier(getPackageName(name))) {
+ if (!Checks.isPackageName(getPackageName(name))) {
return true;
}
return false;
}
+
+ /**
+ * Converts a resource name to a file path. Returns {@code null} if the
+ * resource name cannot be converted into a file path. Resource names
+ * with empty elements, or elements that are "." or ".." are rejected,
+ * as is a resource name that translates to a file path with a root
+ * component.
+ */
+ public static Path toFilePath(String name) {
+ // scan the resource name to eagerly reject obviously invalid names
+ int next;
+ int off = 0;
+ while ((next = name.indexOf('/', off)) != -1) {
+ int len = next - off;
+ if (!mayTranslate(name, off, len)) {
+ return null;
+ }
+ off = next + 1;
+ }
+ int rem = name.length() - off;
+ if (!mayTranslate(name, off, rem)) {
+ return null;
+ }
+
+ // convert to file path
+ Path path;
+ if (File.separatorChar == '/') {
+ path = Paths.get(name);
+ } else {
+ // not allowed to embed file separators
+ if (name.contains(File.separator))
+ return null;
+ path = Paths.get(name.replace('/', File.separatorChar));
+ }
+
+ // file path not allowed to have root component
+ return (path.getRoot() == null) ? path : null;
+ }
+
+ /**
+ * Returns {@code true} if the element in a resource name is a candidate
+ * to translate to the element of a file path.
+ */
+ private static boolean mayTranslate(String name, int off, int len) {
+ if (len <= 2) {
+ if (len == 0)
+ return false;
+ boolean starsWithDot = (name.charAt(off) == '.');
+ if (len == 1 && starsWithDot)
+ return false;
+ if (len == 2 && starsWithDot && (name.charAt(off+1) == '.'))
+ return false;
+ }
+ return true;
+ }
+
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangAccess.java Wed Jul 05 22:52:22 2017 +0200
@@ -174,4 +174,9 @@
* Invokes Long.fastUUID
*/
String fastUUID(long lsb, long msb);
+
+ /**
+ * Invalidate package access cache
+ */
+ void invalidatePackageAccessCache();
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaLangModuleAccess.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -59,20 +59,21 @@
*/
ModuleDescriptor.Builder newModuleBuilder(String mn,
boolean strict,
- boolean open,
- boolean synthetic);
+ Set<ModuleDescriptor.Modifier> ms);
+
+ /**
+ * Returns a snapshot of the packages in the module.
+ */
+ Set<String> packages(ModuleDescriptor.Builder builder);
/**
- * Returns the set of packages that are exported (unconditionally or
- * unconditionally).
+ * Adds a dependence on a module with the given (possibly un-parsable)
+ * version string.
*/
- Set<String> exportedPackages(ModuleDescriptor.Builder builder);
-
- /**
- * Returns the set of packages that are opened (unconditionally or
- * unconditionally).
- */
- Set<String> openPackages(ModuleDescriptor.Builder builder);
+ void requires(ModuleDescriptor.Builder builder,
+ Set<Requires.Modifier> ms,
+ String mn,
+ String compiledVersion);
/**
* Returns a {@code ModuleDescriptor.Requires} of the given modifiers
@@ -114,23 +115,11 @@
Provides newProvides(String service, List<String> providers);
/**
- * Returns a {@code ModuleDescriptor.Version} of the given version.
- */
- Version newVersion(String v);
-
- /**
- * Clones the given module descriptor with an augmented set of packages
- */
- ModuleDescriptor newModuleDescriptor(ModuleDescriptor md, Set<String> pkgs);
-
- /**
* Returns a new {@code ModuleDescriptor} instance.
*/
ModuleDescriptor newModuleDescriptor(String name,
Version version,
- boolean open,
- boolean automatic,
- boolean synthetic,
+ Set<ModuleDescriptor.Modifier> ms,
Set<Requires> requires,
Set<Exports> exports,
Set<Opens> opens,
@@ -148,9 +137,9 @@
* and the empty configuration as the parent. The post resolution
* checks are optionally run.
*/
- Configuration resolveRequiresAndUses(ModuleFinder finder,
- Collection<String> roots,
- boolean check,
- PrintStream traceOutput);
+ Configuration resolveAndBind(ModuleFinder finder,
+ Collection<String> roots,
+ boolean check,
+ PrintStream traceOutput);
}
--- a/jdk/src/java.base/share/classes/jdk/internal/module/Builder.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/Builder.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 jdk.internal.misc.SharedSecrets;
/**
- * This builder is optimized for reconstituting ModuleDescriptor
+ * This builder is optimized for reconstituting the {@code ModuleDescriptor}s
* for system modules. The validation should be done at jlink time.
*
* 1. skip name validation
@@ -136,9 +136,7 @@
}
final String name;
- boolean open;
- boolean automatic;
- boolean synthetic;
+ boolean open, synthetic, mandated;
Set<Requires> requires;
Set<Exports> exports;
Set<Opens> opens;
@@ -165,13 +163,13 @@
return this;
}
- Builder automatic(boolean value) {
- this.automatic = value;
+ Builder synthetic(boolean value) {
+ this.synthetic = value;
return this;
}
- Builder synthetic(boolean value) {
- this.synthetic = value;
+ Builder mandated(boolean value) {
+ this.mandated = value;
return this;
}
@@ -228,13 +226,10 @@
*
* @throws IllegalArgumentException if {@code v} is null or cannot be
* parsed as a version string
- * @throws IllegalStateException if the module version is already set
*
* @see Version#parse(String)
*/
public Builder version(String v) {
- if (version != null)
- throw new IllegalStateException("module version already set");
Version ver = cachedVersion;
if (ver != null && v.equals(ver.toString())) {
version = ver;
@@ -246,63 +241,63 @@
/**
* Sets the module main class.
- *
- * @throws IllegalStateException if already set
*/
public Builder mainClass(String mc) {
- if (mainClass != null)
- throw new IllegalStateException("main class already set");
mainClass = mc;
return this;
}
/**
* Sets the OS name.
- *
- * @throws IllegalStateException if already set
*/
public Builder osName(String name) {
- if (osName != null)
- throw new IllegalStateException("OS name already set");
this.osName = name;
return this;
}
/**
* Sets the OS arch.
- *
- * @throws IllegalStateException if already set
*/
public Builder osArch(String arch) {
- if (osArch != null)
- throw new IllegalStateException("OS arch already set");
this.osArch = arch;
return this;
}
/**
* Sets the OS version.
- *
- * @throws IllegalStateException if already set
*/
public Builder osVersion(String version) {
- if (osVersion != null)
- throw new IllegalStateException("OS version already set");
this.osVersion = version;
return this;
}
/**
+ * Returns an immutable set of the module modifiers derived from the flags.
+ */
+ private Set<ModuleDescriptor.Modifier> modifiers() {
+ int n = 0;
+ if (open) n++;
+ if (synthetic) n++;
+ if (mandated) n++;
+ if (n == 0) {
+ return Collections.emptySet();
+ } else {
+ ModuleDescriptor.Modifier[] mods = new ModuleDescriptor.Modifier[n];
+ if (open) mods[--n] = ModuleDescriptor.Modifier.OPEN;
+ if (synthetic) mods[--n] = ModuleDescriptor.Modifier.SYNTHETIC;
+ if (mandated) mods[--n] = ModuleDescriptor.Modifier.MANDATED;
+ return Set.of(mods);
+ }
+ }
+
+ /**
* Builds a {@code ModuleDescriptor} from the components.
*/
public ModuleDescriptor build(int hashCode) {
assert name != null;
-
return JLMA.newModuleDescriptor(name,
version,
- open,
- automatic,
- synthetic,
+ modifiers(),
requires,
exports,
opens,
--- a/jdk/src/java.base/share/classes/jdk/internal/module/Checks.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/Checks.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
package jdk.internal.module;
/**
- * Utility class for checking module name and binary names.
+ * Utility class for checking module, package, and class names.
*/
public final class Checks {
@@ -58,8 +58,6 @@
throw new IllegalArgumentException(name + ": Invalid module name"
+ ": '" + id + "' is not a Java identifier");
}
- //if (!Character.isJavaIdentifierStart(last))
- // throw new IllegalArgumentException(name + ": Module name ends in digit");
return name;
}
@@ -77,8 +75,6 @@
int last = isJavaIdentifier(name, off, name.length() - off);
if (last == -1)
return false;
- //if (!Character.isJavaIdentifierStart(last))
- // return false;
return true;
}
@@ -89,40 +85,62 @@
* package name
*/
public static String requirePackageName(String name) {
- return requireBinaryName("package name", name);
+ return requireTypeName("package name", name);
}
/**
- * Checks a name to ensure that it's a legal type name.
+ * Returns {@code true} if the given name is a legal package name.
+ */
+ public static boolean isPackageName(String name) {
+ return isTypeName(name);
+ }
+
+ /**
+ * Checks a name to ensure that it's a legal qualified class name
*
* @throws IllegalArgumentException if name is null or not a legal
- * type name
+ * qualified class name
*/
public static String requireServiceTypeName(String name) {
- return requireBinaryName("service type name", name);
+ return requireQualifiedClassName("service type name", name);
}
/**
- * Checks a name to ensure that it's a legal type name.
+ * Checks a name to ensure that it's a legal qualified class name.
*
* @throws IllegalArgumentException if name is null or not a legal
- * type name
+ * qualified class name
*/
public static String requireServiceProviderName(String name) {
- return requireBinaryName("service provider name", name);
+ return requireQualifiedClassName("service provider name", name);
}
/**
- * Returns {@code true} if the given name is a legal binary name.
+ * Checks a name to ensure that it's a legal qualified class name in
+ * a named package.
+ *
+ * @throws IllegalArgumentException if name is null or not a legal
+ * qualified class name in a named package
*/
- public static boolean isJavaIdentifier(String name) {
- return isBinaryName(name);
+ public static String requireQualifiedClassName(String what, String name) {
+ requireTypeName(what, name);
+ if (name.indexOf('.') == -1)
+ throw new IllegalArgumentException(name + ": is not a qualified name of"
+ + " a Java class in a named package");
+ return name;
}
/**
- * Returns {@code true} if the given name is a legal binary name.
+ * Returns {@code true} if the given name is a legal class name.
*/
- public static boolean isBinaryName(String name) {
+ public static boolean isClassName(String name) {
+ return isTypeName(name);
+ }
+
+ /**
+ * Returns {@code true} if the given name is a legal type name.
+ */
+ private static boolean isTypeName(String name) {
int next;
int off = 0;
while ((next = name.indexOf('.', off)) != -1) {
@@ -135,12 +153,12 @@
}
/**
- * Checks if the given name is a legal binary name.
+ * Checks if the given name is a legal type name.
*
* @throws IllegalArgumentException if name is null or not a legal
- * binary name
+ * type name
*/
- public static String requireBinaryName(String what, String name) {
+ private static String requireTypeName(String what, String name) {
if (name == null)
throw new IllegalArgumentException("Null " + what);
int next;
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileAttributes.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 jdk.internal.module;
import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Builder;
import java.lang.module.ModuleDescriptor.Requires;
import java.lang.module.ModuleDescriptor.Exports;
import java.lang.module.ModuleDescriptor.Opens;
@@ -98,14 +99,17 @@
// module_flags
int module_flags = cr.readUnsignedShort(off);
- boolean open = ((module_flags & ACC_OPEN) != 0);
- boolean synthetic = ((module_flags & ACC_SYNTHETIC) != 0);
off += 2;
- ModuleDescriptor.Builder builder = JLMA.newModuleBuilder(mn,
- false,
- open,
- synthetic);
+ Set<ModuleDescriptor.Modifier> modifiers = new HashSet<>();
+ if ((module_flags & ACC_OPEN) != 0)
+ modifiers.add(ModuleDescriptor.Modifier.OPEN);
+ if ((module_flags & ACC_SYNTHETIC) != 0)
+ modifiers.add(ModuleDescriptor.Modifier.SYNTHETIC);
+ if ((module_flags & ACC_MANDATED) != 0)
+ modifiers.add(ModuleDescriptor.Modifier.MANDATED);
+
+ Builder builder = JLMA.newModuleBuilder(mn, false, modifiers);
// module_version
String module_version = cr.readUTF8(off, buf);
@@ -142,19 +146,13 @@
mods.add(Requires.Modifier.MANDATED);
}
-
// requires_version
- Version compiledVersion = null;
String requires_version = cr.readUTF8(off, buf);
off += 2;
- if (requires_version != null) {
- compiledVersion = Version.parse(requires_version);
- }
-
- if (compiledVersion == null) {
+ if (requires_version == null) {
builder.requires(mods, dn);
} else {
- builder.requires(mods, dn, compiledVersion);
+ JLMA.requires(builder, mods, dn, requires_version);
}
}
@@ -283,11 +281,14 @@
attr.putShort(module_name_index);
// module_flags
+ Set<ModuleDescriptor.Modifier> modifiers = descriptor.modifiers();
int module_flags = 0;
- if (descriptor.isOpen())
+ if (modifiers.contains(ModuleDescriptor.Modifier.OPEN))
module_flags |= ACC_OPEN;
- if (descriptor.isSynthetic())
+ if (modifiers.contains(ModuleDescriptor.Modifier.SYNTHETIC))
module_flags |= ACC_SYNTHETIC;
+ if (modifiers.contains(ModuleDescriptor.Modifier.MANDATED))
+ module_flags |= ACC_MANDATED;
attr.putShort(module_flags);
// module_version
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileConstants.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ClassFileConstants.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,8 +46,8 @@
// access, requires, exports, and opens flags
public static final int ACC_MODULE = 0x8000;
public static final int ACC_OPEN = 0x0020;
- public static final int ACC_TRANSITIVE = 0x0010;
- public static final int ACC_STATIC_PHASE = 0x0020;
+ public static final int ACC_TRANSITIVE = 0x0020;
+ public static final int ACC_STATIC_PHASE = 0x0040;
public static final int ACC_SYNTHETIC = 0x1000;
public static final int ACC_MANDATED = 0x8000;
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleBootstrap.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,6 +46,7 @@
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
+import java.util.stream.Stream;
import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader;
@@ -114,7 +115,12 @@
long t0 = System.nanoTime();
// system modules (may be patched)
- ModuleFinder systemModules = ModuleFinder.ofSystem();
+ ModuleFinder systemModules;
+ if (SystemModules.MODULE_NAMES.length > 0) {
+ systemModules = SystemModuleFinder.getInstance();
+ } else {
+ systemModules = ModuleFinder.ofSystem();
+ }
PerfCounters.systemModulesTime.addElapsedTimeFrom(t0);
@@ -275,10 +281,10 @@
// run the resolver to create the configuration
Configuration cf = SharedSecrets.getJavaLangModuleAccess()
- .resolveRequiresAndUses(finder,
- roots,
- needPostResolutionChecks,
- traceOutput);
+ .resolveAndBind(finder,
+ roots,
+ needPostResolutionChecks,
+ traceOutput);
// time to create configuration
PerfCounters.resolveTime.addElapsedTimeFrom(t3);
@@ -318,20 +324,20 @@
// if needed check that there are no split packages in the set of
// resolved modules for the boot layer
if (SystemModules.hasSplitPackages() || needPostResolutionChecks) {
- Map<String, String> packageToModule = new HashMap<>();
- for (ResolvedModule resolvedModule : cf.modules()) {
- ModuleDescriptor descriptor =
- resolvedModule.reference().descriptor();
- String name = descriptor.name();
- for (String p : descriptor.packages()) {
- String other = packageToModule.putIfAbsent(p, name);
- if (other != null) {
- fail("Package " + p + " in both module "
- + name + " and module " + other);
- }
+ Map<String, String> packageToModule = new HashMap<>();
+ for (ResolvedModule resolvedModule : cf.modules()) {
+ ModuleDescriptor descriptor =
+ resolvedModule.reference().descriptor();
+ String name = descriptor.name();
+ for (String p : descriptor.packages()) {
+ String other = packageToModule.putIfAbsent(p, name);
+ if (other != null) {
+ fail("Package " + p + " in both module "
+ + name + " and module " + other);
}
}
}
+ }
long t4 = System.nanoTime();
@@ -380,10 +386,9 @@
Set<String> otherMods)
{
// resolve all root modules
- Configuration cf = Configuration.empty()
- .resolveRequires(finder,
- ModuleFinder.of(),
- roots);
+ Configuration cf = Configuration.empty().resolve(finder,
+ ModuleFinder.of(),
+ roots);
// module name -> reference
Map<String, ModuleReference> map = new HashMap<>();
@@ -416,7 +421,7 @@
/**
* Creates a finder from the module path that is the value of the given
- * system property.
+ * system property and optionally patched by --patch-module
*/
private static ModuleFinder createModulePathFinder(String prop) {
String s = System.getProperty(prop);
@@ -429,7 +434,7 @@
for (String dir: dirs) {
paths[i++] = Paths.get(dir);
}
- return ModuleFinder.of(paths);
+ return ModulePath.of(patcher, paths);
}
}
@@ -528,6 +533,7 @@
if (!extraOpens.isEmpty()) {
addExtraExportsOrOpens(bootLayer, extraOpens, true);
}
+
}
private static void addExtraExportsOrOpens(Layer bootLayer,
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,6 @@
import java.lang.module.ModuleDescriptor.Requires;
import java.lang.module.ModuleDescriptor.Exports;
import java.lang.module.ModuleDescriptor.Opens;
-import java.lang.module.ModuleDescriptor.Version;
import java.nio.ByteBuffer;
import java.nio.BufferUnderflowException;
import java.util.ArrayList;
@@ -51,7 +50,6 @@
import jdk.internal.misc.JavaLangModuleAccess;
import jdk.internal.misc.SharedSecrets;
-import jdk.internal.module.ModuleResolution;
import static jdk.internal.module.ClassFileConstants.*;
@@ -221,7 +219,7 @@
Set<String> attributes = new HashSet<>();
Builder builder = null;
- Set<String> packages = null;
+ Set<String> allPackages = null;
String mainClass = null;
String[] osValues = null;
ModuleHashes hashes = null;
@@ -245,7 +243,7 @@
break;
case MODULE_PACKAGES :
- packages = readModulePackagesAttribute(in, cpool);
+ allPackages = readModulePackagesAttribute(in, cpool);
break;
case MODULE_MAIN_CLASS :
@@ -284,51 +282,44 @@
throw invalidModuleDescriptor(MODULE + " attribute not found");
}
+ // ModuleMainClass and ModuleTarget attributes
+ if (mainClass != null) {
+ builder.mainClass(mainClass);
+ }
+ if (osValues != null) {
+ if (osValues[0] != null) builder.osName(osValues[0]);
+ if (osValues[1] != null) builder.osArch(osValues[1]);
+ if (osValues[2] != null) builder.osVersion(osValues[2]);
+ }
+
// If the ModulePackages attribute is not present then the packageFinder
// is used to find the set of packages
boolean usedPackageFinder = false;
- if (packages == null && packageFinder != null) {
+ if (allPackages == null && packageFinder != null) {
try {
- packages = new HashSet<>(packageFinder.get());
+ allPackages = packageFinder.get();
} catch (UncheckedIOException x) {
throw x.getCause();
}
usedPackageFinder = true;
}
- if (packages != null) {
- Set<String> exportedPackages = JLMA.exportedPackages(builder);
- Set<String> openPackages = JLMA.openPackages(builder);
- if (packages.containsAll(exportedPackages)
- && packages.containsAll(openPackages)) {
- packages.removeAll(exportedPackages);
- packages.removeAll(openPackages);
- } else {
- // the set of packages is not complete
- Set<String> exportedAndOpenPackages = new HashSet<>();
- exportedAndOpenPackages.addAll(exportedPackages);
- exportedAndOpenPackages.addAll(openPackages);
- for (String pn : exportedAndOpenPackages) {
- if (!packages.contains(pn)) {
- String tail;
- if (usedPackageFinder) {
- tail = " not found by package finder";
- } else {
- tail = " missing from ModulePackages attribute";
- }
- throw invalidModuleDescriptor("Package " + pn + tail);
- }
+ if (allPackages != null) {
+ Set<String> knownPackages = JLMA.packages(builder);
+ if (!allPackages.containsAll(knownPackages)) {
+ Set<String> missingPackages = new HashSet<>(knownPackages);
+ missingPackages.removeAll(allPackages);
+ assert !missingPackages.isEmpty();
+ String missingPackage = missingPackages.iterator().next();
+ String tail;
+ if (usedPackageFinder) {
+ tail = " not found in module";
+ } else {
+ tail = " missing from ModulePackages class file attribute";
}
- assert false; // should not get here
- }
- builder.contains(packages);
- }
+ throw invalidModuleDescriptor("Package " + missingPackage + tail);
- if (mainClass != null)
- builder.mainClass(mainClass);
- if (osValues != null) {
- if (osValues[0] != null) builder.osName(osValues[0]);
- if (osValues[1] != null) builder.osArch(osValues[1]);
- if (osValues[2] != null) builder.osVersion(osValues[2]);
+ }
+ builder.packages(allPackages);
}
ModuleDescriptor descriptor = builder.build();
@@ -347,10 +338,17 @@
String mn = cpool.getModuleName(module_name_index);
int module_flags = in.readUnsignedShort();
+
+ Set<ModuleDescriptor.Modifier> modifiers = new HashSet<>();
boolean open = ((module_flags & ACC_OPEN) != 0);
- boolean synthetic = ((module_flags & ACC_SYNTHETIC) != 0);
+ if (open)
+ modifiers.add(ModuleDescriptor.Modifier.OPEN);
+ if ((module_flags & ACC_SYNTHETIC) != 0)
+ modifiers.add(ModuleDescriptor.Modifier.SYNTHETIC);
+ if ((module_flags & ACC_MANDATED) != 0)
+ modifiers.add(ModuleDescriptor.Modifier.MANDATED);
- Builder builder = JLMA.newModuleBuilder(mn, false, open, synthetic);
+ Builder builder = JLMA.newModuleBuilder(mn, false, modifiers);
int module_version_index = in.readUnsignedShort();
if (module_version_index != 0) {
@@ -381,16 +379,11 @@
}
int requires_version_index = in.readUnsignedShort();
- Version compiledVersion = null;
- if (requires_version_index != 0) {
- String vs = cpool.getUtf8(requires_version_index);
- compiledVersion = Version.parse(vs);
- }
-
- if (compiledVersion == null) {
+ if (requires_version_index == 0) {
builder.requires(mods, dn);
} else {
- builder.requires(mods, dn, compiledVersion);
+ String vs = cpool.getUtf8(requires_version_index);
+ JLMA.requires(builder, mods, dn, vs);
}
if (dn.equals("java.base"))
@@ -629,10 +622,7 @@
/**
* Return true if the given attribute name is the name of a pre-defined
- * attribute that is not allowed in the class file.
- *
- * Except for Module, InnerClasses, SourceFile, SourceDebugExtension, and
- * Deprecated, none of the pre-defined attributes in JVMS 4.7 may appear.
+ * attribute in JVMS 4.7 that is not allowed in a module-info class.
*/
private static boolean isAttributeDisallowed(String name) {
Set<String> notAllowed = predefinedNotAllowed;
@@ -640,6 +630,7 @@
notAllowed = Set.of(
"ConstantValue",
"Code",
+ "Deprecated",
"StackMapTable",
"Exceptions",
"EnclosingMethod",
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleInfoExtender.java Wed Jul 05 22:52:22 2017 +0200
@@ -56,7 +56,7 @@
// the packages in the ModulePackages attribute
private Set<String> packages;
- // the value of the module_version in Module attribute
+ // the value for the module version in the Module attribute
private Version version;
// the value of the ModuleMainClass attribute
@@ -78,7 +78,11 @@
}
/**
- * Sets the set of packages for the ModulePackages attribute
+ * Sets the packages for the ModulePackages attribute
+ *
+ * @apiNote This method does not check that the package names are legal
+ * package names or that the set of packages is a super set of the
+ * packages in the module.
*/
public ModuleInfoExtender packages(Set<String> packages) {
this.packages = Collections.unmodifiableSet(packages);
@@ -86,7 +90,7 @@
}
/**
- * Sets the value of the module_version in Module attribute.
+ * Sets the value for the module version in the Module attribute
*/
public ModuleInfoExtender version(Version version) {
this.version = version;
@@ -95,6 +99,9 @@
/**
* Sets the value of the ModuleMainClass attribute.
+ *
+ * @apiNote This method does not check that the main class is a legal
+ * class name in a named package.
*/
public ModuleInfoExtender mainClass(String mainClass) {
this.mainClass = mainClass;
@@ -133,7 +140,7 @@
/**
* A ClassVisitor that supports adding class file attributes. If an
- * attribute already exists then the first occurence of the attribute
+ * attribute already exists then the first occurrence of the attribute
* is replaced.
*/
private static class AttributeAddingClassVisitor extends ClassVisitor {
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleLoaderMap.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,13 +41,6 @@
* are generated at build time.
*/
final class ModuleLoaderMap {
- /*
- * The list of boot modules and platform modules are generated at build time.
- */
- private static final String[] BOOT_MODULES
- = new String[] { "@@BOOT_MODULE_NAMES@@" };
- private static final String[] PLATFORM_MODULES
- = new String[] { "@@PLATFORM_MODULE_NAMES@@" };
/**
* Returns the function to map modules in the given configuration to the
@@ -55,6 +48,10 @@
*/
static Function<String, ClassLoader> mappingFunction(Configuration cf) {
+ // The list of boot modules and platform modules are generated at build time.
+ final String[] BOOT_MODULES = new String[] { "@@BOOT_MODULE_NAMES@@" };
+ final String[] PLATFORM_MODULES = new String[] { "@@PLATFORM_MODULE_NAMES@@" };
+
Set<String> bootModules = new HashSet<>(BOOT_MODULES.length);
for (String mn : BOOT_MODULES) {
bootModules.add(mn);
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModulePatcher.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Builder;
import java.lang.module.ModuleReader;
import java.lang.module.ModuleReference;
import java.net.MalformedURLException;
@@ -54,6 +55,7 @@
import java.util.stream.Stream;
import jdk.internal.loader.Resource;
+import jdk.internal.loader.ResourceHelper;
import jdk.internal.misc.JavaLangModuleAccess;
import jdk.internal.misc.SharedSecrets;
import sun.net.www.ParseUtil;
@@ -108,8 +110,11 @@
if (paths == null)
return mref;
- // scan the JAR file or directory tree to get the set of packages
+ // Scan the JAR file or directory tree to get the set of packages.
+ // For automatic modules then packages that do not contain class files
+ // must be ignored.
Set<String> packages = new HashSet<>();
+ boolean isAutomatic = descriptor.isAutomatic();
try {
for (Path file : paths) {
if (Files.isRegularFile(file)) {
@@ -118,8 +123,10 @@
// is not supported by the boot class loader
try (JarFile jf = new JarFile(file.toFile())) {
jf.stream()
+ .filter(e -> !e.isDirectory()
+ && (!isAutomatic || e.getName().endsWith(".class")))
.map(e -> toPackageName(file, e))
- .filter(Checks::isJavaIdentifier)
+ .filter(Checks::isPackageName)
.forEach(packages::add);
}
@@ -129,8 +136,10 @@
Path top = file;
Files.find(top, Integer.MAX_VALUE,
((path, attrs) -> attrs.isRegularFile()))
+ .filter(path -> !isAutomatic
+ || path.toString().endsWith(".class"))
.map(path -> toPackageName(top, path))
- .filter(Checks::isJavaIdentifier)
+ .filter(Checks::isPackageName)
.forEach(packages::add);
}
@@ -141,10 +150,30 @@
}
// if there are new packages then we need a new ModuleDescriptor
- Set<String> original = descriptor.packages();
- packages.addAll(original);
- if (packages.size() > original.size()) {
- descriptor = JLMA.newModuleDescriptor(descriptor, packages);
+ packages.removeAll(descriptor.packages());
+ if (!packages.isEmpty()) {
+ Builder builder = JLMA.newModuleBuilder(descriptor.name(),
+ /*strict*/ false,
+ descriptor.modifiers());
+ if (!descriptor.isAutomatic()) {
+ descriptor.requires().forEach(builder::requires);
+ descriptor.exports().forEach(builder::exports);
+ descriptor.opens().forEach(builder::opens);
+ descriptor.uses().forEach(builder::uses);
+ }
+ descriptor.provides().forEach(builder::provides);
+
+ descriptor.version().ifPresent(builder::version);
+ descriptor.mainClass().ifPresent(builder::mainClass);
+ descriptor.osName().ifPresent(builder::osName);
+ descriptor.osArch().ifPresent(builder::osArch);
+ descriptor.osVersion().ifPresent(builder::osVersion);
+
+ // original + new packages
+ builder.packages(descriptor.packages());
+ builder.packages(packages);
+
+ descriptor = builder.build();
}
// return a module reference to the patched module
@@ -471,23 +500,14 @@
@Override
public Resource find(String name) throws IOException {
- Path file = Paths.get(name.replace('/', File.separatorChar));
- if (file.getRoot() == null) {
- file = dir.resolve(file);
- } else {
- // drop the root component so that the resource is
- // located relative to the module directory
- int n = file.getNameCount();
- if (n == 0)
- return null;
- file = dir.resolve(file.subpath(0, n));
+ Path path = ResourceHelper.toFilePath(name);
+ if (path != null) {
+ Path file = dir.resolve(path);
+ if (Files.isRegularFile(file)) {
+ return newResource(name, dir, file);
+ }
}
-
- if (Files.isRegularFile(file)) {
- return newResource(name, dir, file);
- } else {
- return null;
- }
+ return null;
}
private Resource newResource(String name, Path top, Path file) {
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModulePath.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModulePath.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* 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.lang.module.FindException;
import java.lang.module.InvalidModuleDescriptorException;
import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleDescriptor.Requires;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
import java.net.URI;
@@ -70,12 +69,11 @@
/**
* A {@code ModuleFinder} that locates modules on the file system by searching
- * a sequence of directories or packaged modules.
- *
- * The {@code ModuleFinder} can be created to work in either the run-time
- * or link-time phases. In both cases it locates modular JAR and exploded
- * modules. When created for link-time then it additionally locates
- * modules in JMOD files.
+ * a sequence of directories or packaged modules. The ModuleFinder can be
+ * created to work in either the run-time or link-time phases. In both cases it
+ * locates modular JAR and exploded modules. When created for link-time then it
+ * additionally locates modules in JMOD files. The ModuleFinder can also
+ * optionally patch any modules that it locates with a ModulePatcher.
*/
public class ModulePath implements ModuleFinder {
@@ -87,6 +85,9 @@
// true for the link phase (supports modules packaged in JMOD format)
private final boolean isLinkPhase;
+ // for patching modules, can be null
+ private final ModulePatcher patcher;
+
// the entries on this module path
private final Path[] entries;
private int next;
@@ -94,19 +95,51 @@
// map of module name to module reference map for modules already located
private final Map<String, ModuleReference> cachedModules = new HashMap<>();
- public ModulePath(Runtime.Version version, boolean isLinkPhase, Path... entries) {
+
+ private ModulePath(Runtime.Version version,
+ boolean isLinkPhase,
+ ModulePatcher patcher,
+ Path... entries) {
this.releaseVersion = version;
this.isLinkPhase = isLinkPhase;
+ this.patcher = patcher;
this.entries = entries.clone();
for (Path entry : this.entries) {
Objects.requireNonNull(entry);
}
}
- public ModulePath(Path... entries) {
- this(JarFile.runtimeVersion(), false, entries);
+ /**
+ * Returns a ModuleFinder that that locates modules on the file system by
+ * searching a sequence of directories and/or packaged modules. The modules
+ * may be patched by the given ModulePatcher.
+ */
+ public static ModuleFinder of(ModulePatcher patcher, Path... entries) {
+ return new ModulePath(JarFile.runtimeVersion(), false, patcher, entries);
}
+ /**
+ * Returns a ModuleFinder that that locates modules on the file system by
+ * searching a sequence of directories and/or packaged modules.
+ */
+ public static ModuleFinder of(Path... entries) {
+ return of((ModulePatcher)null, entries);
+ }
+
+ /**
+ * Returns a ModuleFinder that that locates modules on the file system by
+ * searching a sequence of directories and/or packaged modules.
+ *
+ * @param version The release version to use for multi-release JAR files
+ * @param isLinkPhase {@code true} if the link phase to locate JMOD files
+ */
+ public static ModuleFinder of(Runtime.Version version,
+ boolean isLinkPhase,
+ Path... entries) {
+ return new ModulePath(version, isLinkPhase, null, entries);
+ }
+
+
@Override
public Optional<ModuleReference> find(String name) {
Objects.requireNonNull(name);
@@ -195,8 +228,7 @@
if (attrs.isDirectory()) {
Path mi = entry.resolve(MODULE_INFO);
if (!Files.exists(mi)) {
- // does not exist or unable to determine so assume a
- // directory of modules
+ // assume a directory of modules
return scanDirectory(entry);
}
}
@@ -206,10 +238,16 @@
if (mref != null) {
String name = mref.descriptor().name();
return Collections.singletonMap(name, mref);
+ }
+
+ // not recognized
+ String msg;
+ if (!isLinkPhase && entry.toString().endsWith(".jmod")) {
+ msg = "JMOD format not supported at execution time";
} else {
- // skipped
- return Collections.emptyMap();
+ msg = "Module format not recognized";
}
+ throw new FindException(msg + ": " + entry);
} catch (IOException ioe) {
throw new FindException(ioe);
@@ -266,14 +304,11 @@
/**
- * Locates a packaged or exploded module, returning a {@code ModuleReference}
- * to the module. Returns {@code null} if the entry is skipped because it is
- * to a directory that does not contain a module-info.class or it's a hidden
- * file.
+ * Reads a packaged or exploded module, returning a {@code ModuleReference}
+ * to the module. Returns {@code null} if the entry is not recognized.
*
* @throws IOException if an I/O error occurs
- * @throws FindException if the file is not recognized as a module or an
- * error occurs parsing its module descriptor
+ * @throws FindException if an error occurs parsing its module descriptor
*/
private ModuleReference readModule(Path entry, BasicFileAttributes attrs)
throws IOException
@@ -282,24 +317,16 @@
if (attrs.isDirectory()) {
return readExplodedModule(entry); // may return null
- }
-
- String fn = entry.getFileName().toString();
- if (attrs.isRegularFile()) {
- if (fn.endsWith(".jar")) {
- return readJar(entry);
- } else if (fn.endsWith(".jmod")) {
- if (isLinkPhase)
+ } else {
+ String fn = entry.getFileName().toString();
+ if (attrs.isRegularFile()) {
+ if (fn.endsWith(".jar")) {
+ return readJar(entry);
+ } else if (isLinkPhase && fn.endsWith(".jmod")) {
return readJMod(entry);
- throw new FindException("JMOD files not supported: " + entry);
+ }
}
- }
-
- // skip hidden files
- if (fn.startsWith(".") || Files.isHidden(entry)) {
return null;
- } else {
- throw new FindException("Unrecognized module: " + entry);
}
} catch (InvalidModuleDescriptorException e) {
@@ -327,7 +354,7 @@
}
}
- // -- jmod files --
+ // -- JMOD files --
private Set<String> jmodPackages(JmodFile jf) {
return jf.stream()
@@ -339,7 +366,7 @@
}
/**
- * Returns a {@code ModuleReference} to a module in jmod file on the
+ * Returns a {@code ModuleReference} to a module in JMOD file on the
* file system.
*
* @throws IOException
@@ -362,7 +389,7 @@
/**
* Returns the service type corresponding to the name of a services
- * configuration file if it is a valid Java identifier.
+ * configuration file if it is a legal type name.
*
* For example, if called with "META-INF/services/p.S" then this method
* returns a container with the value "p.S".
@@ -374,7 +401,7 @@
String prefix = cf.substring(0, index);
if (prefix.equals(SERVICES_PREFIX)) {
String sn = cf.substring(index);
- if (Checks.isJavaIdentifier(sn))
+ if (Checks.isClassName(sn))
return Optional.of(sn);
}
}
@@ -403,11 +430,10 @@
*
* 1. The module name (and optionally the version) is derived from the file
* name of the JAR file
- * 2. All packages are exported and open
- * 3. It has no non-exported/non-open packages
- * 4. The contents of any META-INF/services configuration files are mapped
+ * 2. All packages are derived from the .class files in the JAR file
+ * 3. The contents of any META-INF/services configuration files are mapped
* to "provides" declarations
- * 5. The Main-Class attribute in the main attributes of the JAR manifest
+ * 4. The Main-Class attribute in the main attributes of the JAR manifest
* is mapped to the module descriptor mainClass
*/
private ModuleDescriptor deriveModuleDescriptor(JarFile jf)
@@ -443,9 +469,7 @@
mn = cleanModuleName(mn);
// Builder throws IAE if module name is empty or invalid
- ModuleDescriptor.Builder builder
- = ModuleDescriptor.automaticModule(mn)
- .requires(Set.of(Requires.Modifier.MANDATED), "java.base");
+ ModuleDescriptor.Builder builder = ModuleDescriptor.newAutomaticModule(mn);
if (vs != null)
builder.version(vs);
@@ -453,17 +477,22 @@
Map<Boolean, Set<String>> map = VersionedStream.stream(jf)
.filter(e -> !e.isDirectory())
.map(JarEntry::getName)
+ .filter(e -> (e.endsWith(".class") ^ e.startsWith(SERVICES_PREFIX)))
.collect(Collectors.partitioningBy(e -> e.startsWith(SERVICES_PREFIX),
Collectors.toSet()));
- Set<String> resources = map.get(Boolean.FALSE);
+ Set<String> classFiles = map.get(Boolean.FALSE);
Set<String> configFiles = map.get(Boolean.TRUE);
- // all packages are exported and open
- resources.stream()
+
+ // the packages containing class files
+ Set<String> packages = classFiles.stream()
.map(this::toPackageName)
.flatMap(Optional::stream)
.distinct()
- .forEach(pn -> builder.exports(pn).opens(pn));
+ .collect(Collectors.toSet());
+
+ // all packages are exported and open
+ builder.packages(packages);
// map names of service configuration files to service names
Set<String> serviceNames = configFiles.stream()
@@ -481,6 +510,11 @@
String cn;
while ((cn = nextLine(reader)) != null) {
if (cn.length() > 0) {
+ String pn = packageName(cn);
+ if (!packages.contains(pn)) {
+ String msg = "Provider class " + cn + " not in module";
+ throw new IOException(msg);
+ }
providerClasses.add(cn);
}
}
@@ -494,8 +528,15 @@
if (man != null) {
Attributes attrs = man.getMainAttributes();
String mainClass = attrs.getValue(Attributes.Name.MAIN_CLASS);
- if (mainClass != null)
- builder.mainClass(mainClass.replace("/", "."));
+ if (mainClass != null) {
+ mainClass = mainClass.replace("/", ".");
+ String pn = packageName(mainClass);
+ if (!packages.contains(pn)) {
+ String msg = "Main-Class " + mainClass + " not in module";
+ throw new IOException(msg);
+ }
+ builder.mainClass(mainClass);
+ }
}
return builder.build();
@@ -569,10 +610,10 @@
try {
ModuleDescriptor md = deriveModuleDescriptor(jf);
attrs = new ModuleInfo.Attributes(md, null, null);
- } catch (IllegalArgumentException iae) {
+ } catch (IllegalArgumentException e) {
throw new FindException(
"Unable to derive module descriptor for: "
- + jf.getName(), iae);
+ + jf.getName(), e);
}
} else {
@@ -580,7 +621,7 @@
() -> jarPackages(jf));
}
- return ModuleReferences.newJarModule(attrs, file);
+ return ModuleReferences.newJarModule(attrs, patcher, file);
}
}
@@ -617,7 +658,15 @@
// for now
return null;
}
- return ModuleReferences.newExplodedModule(attrs, dir);
+ return ModuleReferences.newExplodedModule(attrs, patcher, dir);
+ }
+
+ /**
+ * Maps a type name to its package name.
+ */
+ private static String packageName(String cn) {
+ int index = cn.lastIndexOf('.');
+ return (index == -1) ? "" : cn.substring(0, index);
}
/**
@@ -629,19 +678,18 @@
*/
private Optional<String> toPackageName(String name) {
assert !name.endsWith("/");
-
int index = name.lastIndexOf("/");
if (index == -1) {
if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
throw new IllegalArgumentException(name
- + " found in top-level directory:"
+ + " found in top-level directory"
+ " (unnamed package not allowed in module)");
}
return Optional.empty();
}
String pn = name.substring(0, index).replace('/', '.');
- if (Checks.isJavaIdentifier(pn)) {
+ if (Checks.isPackageName(pn)) {
return Optional.of(pn);
} else {
// not a valid package name
@@ -654,7 +702,7 @@
* name.
*
* @throws IllegalArgumentException if the name is a class file in
- * the top-level directory (and it's not module-info.class)
+ * the top-level directory (and it's not module-info.class)
*/
private Optional<String> toPackageName(Path file) {
assert file.getRoot() == null;
@@ -664,14 +712,14 @@
String name = file.toString();
if (name.endsWith(".class") && !name.equals(MODULE_INFO)) {
throw new IllegalArgumentException(name
- + " found in in top-level directory"
+ + " found in top-level directory"
+ " (unnamed package not allowed in module)");
}
return Optional.empty();
}
String pn = parent.toString().replace(File.separatorChar, '.');
- if (Checks.isJavaIdentifier(pn)) {
+ if (Checks.isPackageName(pn)) {
return Optional.of(pn);
} else {
// not a valid package name
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferenceImpl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferenceImpl.java Wed Jul 05 22:52:22 2017 +0200
@@ -163,7 +163,14 @@
@Override
public String toString() {
- return super.toString();
+ StringBuilder sb = new StringBuilder();
+ sb.append("[module ");
+ sb.append(descriptor().name());
+ sb.append(", location=");
+ sb.append(location().orElseThrow(() -> new InternalError()));
+ if (isPatched()) sb.append(" (patched)");
+ sb.append("]");
+ return sb.toString();
}
}
--- a/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java Wed Jul 05 22:52:22 2017 +0200
@@ -36,7 +36,6 @@
import java.nio.ByteBuffer;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -51,7 +50,7 @@
import java.util.zip.ZipFile;
import jdk.internal.jmod.JmodFile;
-import jdk.internal.misc.JavaLangAccess;
+import jdk.internal.loader.ResourceHelper;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.ModuleHashes.HashSupplier;
import jdk.internal.util.jar.VersionedStream;
@@ -65,20 +64,16 @@
*/
class ModuleReferences {
-
- private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
-
private ModuleReferences() { }
/**
- * Creates a ModuleReference to a module or to patched module when
- * creating modules for the boot Layer and --patch-module is specified.
+ * Creates a ModuleReference to a possibly-patched module
*/
private static ModuleReference newModule(ModuleInfo.Attributes attrs,
URI uri,
Supplier<ModuleReader> supplier,
+ ModulePatcher patcher,
HashSupplier hasher) {
-
ModuleReference mref = new ModuleReferenceImpl(attrs.descriptor(),
uri,
supplier,
@@ -86,38 +81,42 @@
attrs.recordedHashes(),
hasher,
attrs.moduleResolution());
- if (JLA.getBootLayer() == null)
- mref = ModuleBootstrap.patcher().patchIfNeeded(mref);
+ if (patcher != null)
+ mref = patcher.patchIfNeeded(mref);
return mref;
}
/**
- * Creates a ModuleReference to a module packaged as a modular JAR.
+ * Creates a ModuleReference to a possibly-patched module in a modular JAR.
*/
- static ModuleReference newJarModule(ModuleInfo.Attributes attrs, Path file) {
+ static ModuleReference newJarModule(ModuleInfo.Attributes attrs,
+ ModulePatcher patcher,
+ Path file) {
URI uri = file.toUri();
Supplier<ModuleReader> supplier = () -> new JarModuleReader(file, uri);
HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
- return newModule(attrs, uri, supplier, hasher);
+ return newModule(attrs, uri, supplier, patcher, hasher);
}
/**
- * Creates a ModuleReference to a module packaged as a JMOD.
+ * Creates a ModuleReference to a module in a JMOD file.
*/
static ModuleReference newJModModule(ModuleInfo.Attributes attrs, Path file) {
URI uri = file.toUri();
Supplier<ModuleReader> supplier = () -> new JModModuleReader(file, uri);
HashSupplier hasher = (a) -> ModuleHashes.computeHash(file, a);
- return newModule(attrs, uri, supplier, hasher);
+ return newModule(attrs, uri, supplier, null, hasher);
}
/**
- * Creates a ModuleReference to an exploded module.
+ * Creates a ModuleReference to a possibly-patched exploded module.
*/
- static ModuleReference newExplodedModule(ModuleInfo.Attributes attrs, Path dir) {
+ static ModuleReference newExplodedModule(ModuleInfo.Attributes attrs,
+ ModulePatcher patcher,
+ Path dir) {
Supplier<ModuleReader> supplier = () -> new ExplodedModuleReader(dir);
- return newModule(attrs, dir.toUri(), supplier, null);
+ return newModule(attrs, dir.toUri(), supplier, patcher, null);
}
@@ -243,7 +242,8 @@
}
private JarEntry getEntry(String name) {
- return jf.getJarEntry(Objects.requireNonNull(name));
+ JarEntry entry = jf.getJarEntry(Objects.requireNonNull(name));
+ return (entry == null || entry.isDirectory()) ? null : entry;
}
@Override
@@ -370,32 +370,33 @@
}
/**
- * Returns a Path to access to the given resource.
- */
- private Path toPath(String name) {
- Path path = Paths.get(name.replace('/', File.separatorChar));
- if (path.getRoot() == null) {
- return dir.resolve(path);
- } else {
- // drop the root component so that the resource is
- // located relative to the module directory
- int n = path.getNameCount();
- return (n > 0) ? dir.resolve(path.subpath(0, n)) : null;
- }
- }
-
- /**
* Throws IOException if the module reader is closed;
*/
private void ensureOpen() throws IOException {
if (closed) throw new IOException("ModuleReader is closed");
}
+ /**
+ * Returns a Path to access the given resource. Returns null if the
+ * resource name does not convert to a file path that locates a regular
+ * file in the module.
+ */
+ private Path toFilePath(String name) {
+ Path path = ResourceHelper.toFilePath(name);
+ if (path != null) {
+ Path file = dir.resolve(path);
+ if (Files.isRegularFile(file)) {
+ return file;
+ }
+ }
+ return null;
+ }
+
@Override
public Optional<URI> find(String name) throws IOException {
ensureOpen();
- Path path = toPath(name);
- if (path != null && Files.isRegularFile(path)) {
+ Path path = toFilePath(name);
+ if (path != null) {
try {
return Optional.of(path.toUri());
} catch (IOError e) {
@@ -409,8 +410,8 @@
@Override
public Optional<InputStream> open(String name) throws IOException {
ensureOpen();
- Path path = toPath(name);
- if (path != null && Files.isRegularFile(path)) {
+ Path path = toFilePath(name);
+ if (path != null) {
return Optional.of(Files.newInputStream(path));
} else {
return Optional.empty();
@@ -420,8 +421,8 @@
@Override
public Optional<ByteBuffer> read(String name) throws IOException {
ensureOpen();
- Path path = toPath(name);
- if (path != null && Files.isRegularFile(path)) {
+ Path path = toFilePath(name);
+ if (path != null) {
return Optional.of(ByteBuffer.wrap(Files.readAllBytes(path)));
} else {
return Optional.empty();
--- a/jdk/src/java.base/share/classes/jdk/internal/module/Modules.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/Modules.java Wed Jul 05 22:52:22 2017 +0200
@@ -82,8 +82,8 @@
String name,
Set<String> packages)
{
- ModuleDescriptor descriptor = ModuleDescriptor.module(name)
- .contains(packages)
+ ModuleDescriptor descriptor = ModuleDescriptor.newModule(name)
+ .packages(packages)
.build();
return JLRMA.defineModule(loader, descriptor, null);
@@ -185,7 +185,8 @@
/**
* Adds a package to a module's content.
*
- * This method is a no-op if the module already contains the package.
+ * This method is a no-op if the module already contains the package or the
+ * module is an unnamed module.
*/
public static void addPackage(Module m, String pn) {
JLRMA.addPackage(m, pn);
--- a/jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/module/SystemModuleFinder.java Wed Jul 05 22:52:22 2017 +0200
@@ -80,8 +80,6 @@
= PerfCounter.newPerfCounter("jdk.module.finder.jimage.packages");
private static final PerfCounter exportsCount
= PerfCounter.newPerfCounter("jdk.module.finder.jimage.exports");
- // ImageReader used to access all modules in the image
- private static final ImageReader imageReader;
// singleton finder to find modules in the run-time images
private static final SystemModuleFinder INSTANCE;
@@ -96,13 +94,28 @@
*/
static {
long t0 = System.nanoTime();
- imageReader = ImageReaderFactory.getImageReader();
INSTANCE = new SystemModuleFinder();
initTime.addElapsedTimeFrom(t0);
}
+ /**
+ * Holder class for the ImageReader
+ */
+ private static class SystemImage {
+ static final ImageReader READER;
+ static {
+ long t0 = System.nanoTime();
+ READER = ImageReaderFactory.getImageReader();
+ initTime.addElapsedTimeFrom(t0);
+ }
+
+ static ImageReader reader() {
+ return READER;
+ }
+ }
+
private static boolean isFastPathSupported() {
return SystemModules.MODULE_NAMES.length > 0;
}
@@ -114,7 +127,7 @@
// this happens when java.base is patched with java.base
// from an exploded image
- return imageReader.getModuleNames();
+ return SystemImage.reader().getModuleNames();
}
// the set of modules in the run-time image
@@ -151,6 +164,7 @@
descriptors = new ModuleDescriptor[n];
recordedHashes = new ModuleHashes[n];
moduleResolutions = new ModuleResolution[n];
+ ImageReader imageReader = SystemImage.reader();
for (int i = 0; i < names.length; i++) {
String mn = names[i];
ImageLocation loc = imageReader.findLocation(mn, "module-info.class");
@@ -291,6 +305,7 @@
Objects.requireNonNull(name);
if (closed)
throw new IOException("ModuleReader is closed");
+ ImageReader imageReader = SystemImage.reader();
if (imageReader != null) {
return imageReader.findLocation(module, name);
} else {
@@ -330,7 +345,7 @@
public Optional<ByteBuffer> read(String name) throws IOException {
ImageLocation location = findImageLocation(name);
if (location != null) {
- return Optional.of(imageReader.getResourceBuffer(location));
+ return Optional.of(SystemImage.reader().getResourceBuffer(location));
} else {
return Optional.empty();
}
@@ -372,7 +387,7 @@
stack = new ArrayDeque<>();
// push the root node to the stack to get started
- ImageReader.Node dir = imageReader.findNode(moduleRoot);
+ ImageReader.Node dir = SystemImage.reader().findNode(moduleRoot);
if (dir == null || !dir.isDirectory())
throw new IOException(moduleRoot + " not a directory");
stack.push(dir);
@@ -390,7 +405,7 @@
String name = node.getName();
if (node.isDirectory()) {
// build node
- ImageReader.Node dir = imageReader.findNode(name);
+ ImageReader.Node dir = SystemImage.reader().findNode(name);
assert dir.isDirectory();
stack.push(dir);
} else {
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -211,15 +211,7 @@
if (currentModule == memberModule)
return true; // same module (named or unnamed)
- // memberClass may be primitive or array class
- Class<?> c = memberClass;
- while (c.isArray()) {
- c = c.getComponentType();
- }
- if (c.isPrimitive())
- return true;
-
- String pkg = c.getPackageName();
+ String pkg = memberClass.getPackageName();
boolean allowed = memberModule.isExported(pkg, currentModule);
if (allowed && memberModule.isNamed() && printStackTraceWhenAccessSucceeds()) {
if (!SharedSecrets.getJavaLangReflectModuleAccess()
@@ -237,10 +229,6 @@
private static boolean isSameClassPackage(Class<?> c1, Class<?> c2) {
if (c1.getClassLoader() != c2.getClassLoader())
return false;
- while (c1.isArray())
- c1 = c1.getComponentType();
- while (c2.isArray())
- c2 = c2.getComponentType();
return Objects.equals(c1.getPackageName(), c2.getPackageName());
}
@@ -378,12 +366,6 @@
}
}
- public static void enableStackTraces() {
- printStackWhenAccessFails = true;
- printStackWhenAccessSucceeds = true;
- printStackPropertiesSet = true;
- }
-
public static boolean printStackTraceWhenAccessFails() {
ensurePrintStackPropertiesSet();
return printStackWhenAccessFails;
@@ -413,11 +395,7 @@
if (m2.isNamed())
memberSuffix = " (in " + m2 + ")";
- Class<?> c = memberClass;
- while (c.isArray()) {
- c = c.getComponentType();
- }
- String memberPackageName = c.getPackageName();
+ String memberPackageName = memberClass.getPackageName();
String msg = currentClass + currentSuffix + " cannot access ";
if (m2.isExported(memberPackageName, m1)) {
--- a/jdk/src/java.base/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the foundational APIs of the Java SE Platform.
+ *
+ * @since 9
*/
module java.base {
--- a/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/VerifyAccess.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -39,6 +39,7 @@
private VerifyAccess() { } // cannot instantiate
+ private static final int UNCONDITIONAL_ALLOWED = java.lang.invoke.MethodHandles.Lookup.UNCONDITIONAL;
private static final int MODULE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.MODULE;
private static final int PACKAGE_ONLY = 0;
private static final int PACKAGE_ALLOWED = java.lang.invoke.MethodHandles.Lookup.PACKAGE;
@@ -92,7 +93,7 @@
int allowedModes) {
if (allowedModes == 0) return false;
assert((allowedModes & PUBLIC) != 0 &&
- (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED)) == 0);
+ (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);
// The symbolic reference class (refc) must always be fully verified.
if (!isClassAccessible(refc, lookupClass, allowedModes)) {
return false;
@@ -173,7 +174,7 @@
int allowedModes) {
if (allowedModes == 0) return false;
assert((allowedModes & PUBLIC) != 0 &&
- (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED)) == 0);
+ (allowedModes & ~(ALL_ACCESS_MODES|PACKAGE_ALLOWED|MODULE_ALLOWED|UNCONDITIONAL_ALLOWED)) == 0);
int mods = getClassModifiers(refc);
if (isPublic(mods)) {
@@ -191,22 +192,17 @@
(lookupModule == refModule))
return true;
- // check readability
- if (lookupModule.canRead(refModule)) {
+ // check readability when UNCONDITIONAL not allowed
+ if (((allowedModes & UNCONDITIONAL_ALLOWED) != 0)
+ || lookupModule.canRead(refModule)) {
// check that refc is in an exported package
- Class<?> c = refc;
- while (c.isArray()) {
- c = c.getComponentType();
- }
- if (c.isPrimitive())
- return true;
if ((allowedModes & MODULE_ALLOWED) != 0) {
- if (refModule.isExported(c.getPackageName(), lookupModule))
+ if (refModule.isExported(refc.getPackageName(), lookupModule))
return true;
} else {
// exported unconditionally
- if (refModule.isExported(c.getPackageName()))
+ if (refModule.isExported(refc.getPackageName()))
return true;
}
--- a/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/launcher/LauncherHelper.java Wed Jul 05 22:52:22 2017 +0200
@@ -591,8 +591,8 @@
c = Class.forName(m, cn);
}
} catch (LinkageError le) {
- abort(null, "java.launcher.module.error3",
- mainClass, m.getName(), le.getLocalizedMessage());
+ abort(null, "java.launcher.module.error3", mainClass, m.getName(),
+ le.getClass().getName() + ": " + le.getLocalizedMessage());
}
if (c == null) {
abort(null, "java.launcher.module.error2", mainClass, mainModule);
@@ -645,7 +645,8 @@
}
}
} catch (LinkageError le) {
- abort(le, "java.launcher.cls.error6", cn, le.getLocalizedMessage());
+ abort(le, "java.launcher.cls.error6", cn,
+ le.getClass().getName() + ": " + le.getLocalizedMessage());
}
return mainClass;
}
@@ -966,6 +967,10 @@
ostream.print("open ");
if (md.isAutomatic())
ostream.print("automatic ");
+ if (md.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC))
+ ostream.print("synthetic ");
+ if (md.modifiers().contains(ModuleDescriptor.Modifier.MANDATED))
+ ostream.print("mandated ");
ostream.println("module " + midAndLocation(md, mref.location()));
// unqualified exports (sorted by package)
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java Wed Jul 05 22:52:22 2017 +0200
@@ -32,7 +32,9 @@
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
+import java.security.AccessController;
import java.security.Permission;
+import java.security.PrivilegedAction;
import jdk.internal.jimage.ImageLocation;
import jdk.internal.jimage.ImageReader;
@@ -51,7 +53,11 @@
public class JavaRuntimeURLConnection extends URLConnection {
// ImageReader to access resources in jimage
- private static final ImageReader reader = ImageReaderFactory.getImageReader();
+ private static final ImageReader reader;
+ static {
+ PrivilegedAction<ImageReader> pa = ImageReaderFactory::getImageReader;
+ reader = AccessController.doPrivileged(pa);
+ }
// the module and resource name in the URL
private final String module;
--- a/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,6 +37,7 @@
import java.security.Signature;
import java.security.SignatureException;
import java.security.Timestamp;
+import java.security.cert.CertPathValidatorException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
@@ -48,6 +49,7 @@
import java.util.Set;
import sun.security.timestamp.TimestampToken;
+import sun.security.util.ConstraintsParameters;
import sun.security.util.Debug;
import sun.security.util.DerEncoder;
import sun.security.util.DerInputStream;
@@ -321,6 +323,8 @@
data = content.getContentBytes();
}
+ ConstraintsParameters cparams =
+ new ConstraintsParameters(timestamp);
String digestAlgname = getDigestAlgorithmId().getName();
byte[] dataSigned;
@@ -347,11 +351,11 @@
if (messageDigest == null) // fail if there is no message digest
return null;
- // check that algorithm is not restricted
- if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET,
- digestAlgname, null)) {
- throw new SignatureException("Digest check failed. " +
- "Disabled algorithm used: " + digestAlgname);
+ // check that digest algorithm is not restricted
+ try {
+ JAR_DISABLED_CHECK.permits(digestAlgname, cparams);
+ } catch (CertPathValidatorException e) {
+ throw new SignatureException(e.getMessage(), e);
}
MessageDigest md = MessageDigest.getInstance(digestAlgname);
@@ -385,17 +389,18 @@
String algname = AlgorithmId.makeSigAlg(
digestAlgname, encryptionAlgname);
- // check that algorithm is not restricted
- if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, algname, null)) {
- throw new SignatureException("Signature check failed. " +
- "Disabled algorithm used: " + algname);
+ // check that jar signature algorithm is not restricted
+ try {
+ JAR_DISABLED_CHECK.permits(algname, cparams);
+ } catch (CertPathValidatorException e) {
+ throw new SignatureException(e.getMessage(), e);
}
X509Certificate cert = getCertificate(block);
- PublicKey key = cert.getPublicKey();
if (cert == null) {
return null;
}
+ PublicKey key = cert.getPublicKey();
// check if the public key is restricted
if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
import java.security.AlgorithmConstraints;
import java.security.CryptoPrimitive;
import java.security.Timestamp;
+import java.security.cert.CertPathValidator;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@@ -53,9 +54,10 @@
import java.security.spec.DSAPublicKeySpec;
import sun.security.util.AnchorCertificates;
-import sun.security.util.CertConstraintParameters;
+import sun.security.util.ConstraintsParameters;
import sun.security.util.Debug;
import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.validator.Validator;
import sun.security.x509.X509CertImpl;
import sun.security.x509.X509CRLImpl;
import sun.security.x509.AlgorithmId;
@@ -79,6 +81,7 @@
private final Date pkixdate;
private PublicKey prevPubKey;
private final Timestamp jarTimestamp;
+ private final String variant;
private static final Set<CryptoPrimitive> SIGNATURE_PRIMITIVE_SET =
Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
@@ -109,64 +112,36 @@
*
* @param anchor the trust anchor selected to validate the target
* certificate
- */
- public AlgorithmChecker(TrustAnchor anchor) {
- this(anchor, certPathDefaultConstraints, null);
- }
-
- /**
- * Create a new {@code AlgorithmChecker} with the
- * given {@code TrustAnchor} and {@code AlgorithmConstraints}.
- *
- * @param anchor the trust anchor selected to validate the target
- * certificate
- * @param constraints the algorithm constraints (or null)
- *
- * @throws IllegalArgumentException if the {@code anchor} is null
+ * @param variant is the Validator variants of the operation. A null value
+ * passed will set it to Validator.GENERIC.
*/
- public AlgorithmChecker(TrustAnchor anchor,
- AlgorithmConstraints constraints) {
- this(anchor, constraints, null);
- }
-
- /**
- * Create a new {@code AlgorithmChecker} with the
- * given {@code AlgorithmConstraints}.
- * <p>
- * Note that this constructor will be used to check a certification
- * path where the trust anchor is unknown, or a certificate list which may
- * contain the trust anchor. This constructor is used by SunJSSE.
- *
- * @param constraints the algorithm constraints (or null)
- */
- public AlgorithmChecker(AlgorithmConstraints constraints) {
- this.prevPubKey = null;
- this.trustedPubKey = null;
- this.constraints = constraints;
- this.pkixdate = null;
- this.jarTimestamp = null;
+ public AlgorithmChecker(TrustAnchor anchor, String variant) {
+ this(anchor, certPathDefaultConstraints, null, variant);
}
/**
* Create a new {@code AlgorithmChecker} with the given
- * {@code Timestamp}.
+ * {@code AlgorithmConstraints}, {@code Timestamp}, and/or {@code Variant}.
* <p>
- * Note that this constructor will be used to check a certification
- * path for signed JAR files that are timestamped.
+ * Note that this constructor can initialize a variation of situations where
+ * the AlgorithmConstraints, Timestamp, or Variant maybe known.
*
+ * @param constraints the algorithm constraints (or null)
* @param jarTimestamp Timestamp passed for JAR timestamp constraint
* checking. Set to null if not applicable.
+ * @param variant is the Validator variants of the operation. A null value
+ * passed will set it to Validator.GENERIC.
*/
- public AlgorithmChecker(Timestamp jarTimestamp) {
+ public AlgorithmChecker(AlgorithmConstraints constraints,
+ Timestamp jarTimestamp, String variant) {
this.prevPubKey = null;
this.trustedPubKey = null;
- this.constraints = certPathDefaultConstraints;
- if (jarTimestamp == null) {
- throw new IllegalArgumentException(
- "Timestamp cannot be null");
- }
- this.pkixdate = jarTimestamp.getTimestamp();
+ this.constraints = (constraints == null ? certPathDefaultConstraints :
+ constraints);
+ this.pkixdate = (jarTimestamp != null ? jarTimestamp.getTimestamp() :
+ null);
this.jarTimestamp = jarTimestamp;
+ this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
}
/**
@@ -178,12 +153,13 @@
* @param constraints the algorithm constraints (or null)
* @param pkixdate Date the constraints are checked against. The value is
* either the PKIXParameter date or null for the current date.
+ * @param variant is the Validator variants of the operation. A null value
+ * passed will set it to Validator.GENERIC.
*
* @throws IllegalArgumentException if the {@code anchor} is null
*/
public AlgorithmChecker(TrustAnchor anchor,
- AlgorithmConstraints constraints,
- Date pkixdate) {
+ AlgorithmConstraints constraints, Date pkixdate, String variant) {
if (anchor != null) {
if (anchor.getTrustedCert() != null) {
@@ -207,6 +183,7 @@
this.constraints = constraints;
this.pkixdate = pkixdate;
this.jarTimestamp = null;
+ this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
}
/**
@@ -217,11 +194,13 @@
* certificate
* @param pkixdate Date the constraints are checked against. The value is
* either the PKIXParameter date or null for the current date.
+ * @param variant is the Validator variants of the operation. A null value
+ * passed will set it to Validator.GENERIC.
*
* @throws IllegalArgumentException if the {@code anchor} is null
*/
- public AlgorithmChecker(TrustAnchor anchor, Date pkixdate) {
- this(anchor, certPathDefaultConstraints, pkixdate);
+ public AlgorithmChecker(TrustAnchor anchor, Date pkixdate, String variant) {
+ this(anchor, certPathDefaultConstraints, pkixdate, variant);
}
// Check this 'cert' for restrictions in the AnchorCertificates
@@ -286,6 +265,28 @@
null, null, -1, PKIXReason.INVALID_KEY_USAGE);
}
+ X509CertImpl x509Cert;
+ AlgorithmId algorithmId;
+ try {
+ x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
+ algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
+ } catch (CertificateException ce) {
+ throw new CertPathValidatorException(ce);
+ }
+
+ AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
+ PublicKey currPubKey = cert.getPublicKey();
+ String currSigAlg = x509Cert.getSigAlgName();
+
+ // Check the signature algorithm and parameters against constraints.
+ if (!constraints.permits(SIGNATURE_PRIMITIVE_SET, currSigAlg,
+ currSigAlgParams)) {
+ throw new CertPathValidatorException(
+ "Algorithm constraints check failed on signature " +
+ "algorithm: " + currSigAlg, null, null, -1,
+ BasicReason.ALGORITHM_CONSTRAINED);
+ }
+
// Assume all key usage bits are set if key usage is not present
Set<CryptoPrimitive> primitives = KU_PRIMITIVE_SET;
@@ -322,101 +323,74 @@
}
}
- PublicKey currPubKey = cert.getPublicKey();
-
- if (constraints instanceof DisabledAlgorithmConstraints) {
- // Check against DisabledAlgorithmConstraints certpath constraints.
- // permits() will throw exception on failure.
- ((DisabledAlgorithmConstraints)constraints).permits(primitives,
- new CertConstraintParameters((X509Certificate)cert,
- trustedMatch, pkixdate, jarTimestamp));
- // If there is no previous key, set one and exit
- if (prevPubKey == null) {
- prevPubKey = currPubKey;
- return;
- }
- }
+ ConstraintsParameters cp =
+ new ConstraintsParameters((X509Certificate)cert,
+ trustedMatch, pkixdate, jarTimestamp, variant);
- X509CertImpl x509Cert;
- AlgorithmId algorithmId;
- try {
- x509Cert = X509CertImpl.toImpl((X509Certificate)cert);
- algorithmId = (AlgorithmId)x509Cert.get(X509CertImpl.SIG_ALG);
- } catch (CertificateException ce) {
- throw new CertPathValidatorException(ce);
- }
-
- AlgorithmParameters currSigAlgParams = algorithmId.getParameters();
- String currSigAlg = x509Cert.getSigAlgName();
+ // Check against local constraints if it is DisabledAlgorithmConstraints
+ if (constraints instanceof DisabledAlgorithmConstraints) {
+ ((DisabledAlgorithmConstraints)constraints).permits(currSigAlg, cp);
+ // DisabledAlgorithmsConstraints does not check primitives, so key
+ // additional key check.
- // If 'constraints' is not of DisabledAlgorithmConstraints, check all
- // everything individually
- if (!(constraints instanceof DisabledAlgorithmConstraints)) {
- // Check the current signature algorithm
- if (!constraints.permits(
- SIGNATURE_PRIMITIVE_SET,
- currSigAlg, currSigAlgParams)) {
- throw new CertPathValidatorException(
- "Algorithm constraints check failed on signature " +
- "algorithm: " + currSigAlg, null, null, -1,
- BasicReason.ALGORITHM_CONSTRAINED);
- }
-
+ } else {
+ // Perform the default constraints checking anyway.
+ certPathDefaultConstraints.permits(currSigAlg, cp);
+ // Call locally set constraints to check key with primitives.
if (!constraints.permits(primitives, currPubKey)) {
throw new CertPathValidatorException(
- "Algorithm constraints check failed on keysize: " +
- sun.security.util.KeyUtil.getKeySize(currPubKey),
+ "Algorithm constraints check failed on key " +
+ currPubKey.getAlgorithm() + " with size of " +
+ sun.security.util.KeyUtil.getKeySize(currPubKey) +
+ "bits",
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
+ // If there is no previous key, set one and exit
+ if (prevPubKey == null) {
+ prevPubKey = currPubKey;
+ return;
+ }
+
// Check with previous cert for signature algorithm and public key
- if (prevPubKey != null) {
- if (!constraints.permits(
- SIGNATURE_PRIMITIVE_SET,
- currSigAlg, prevPubKey, currSigAlgParams)) {
- throw new CertPathValidatorException(
+ if (!constraints.permits(
+ SIGNATURE_PRIMITIVE_SET,
+ currSigAlg, prevPubKey, currSigAlgParams)) {
+ throw new CertPathValidatorException(
"Algorithm constraints check failed on " +
"signature algorithm: " + currSigAlg,
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+ }
+
+ // Inherit key parameters from previous key
+ if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
+ // Inherit DSA parameters from previous key
+ if (!(prevPubKey instanceof DSAPublicKey)) {
+ throw new CertPathValidatorException("Input key is not " +
+ "of a appropriate type for inheriting parameters");
}
- // Inherit key parameters from previous key
- if (PKIX.isDSAPublicKeyWithoutParams(currPubKey)) {
- // Inherit DSA parameters from previous key
- if (!(prevPubKey instanceof DSAPublicKey)) {
- throw new CertPathValidatorException("Input key is not " +
- "of a appropriate type for inheriting parameters");
- }
-
- DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
- if (params == null) {
- throw new CertPathValidatorException(
+ DSAParams params = ((DSAPublicKey)prevPubKey).getParams();
+ if (params == null) {
+ throw new CertPathValidatorException(
"Key parameters missing from public key.");
- }
+ }
- try {
- BigInteger y = ((DSAPublicKey)currPubKey).getY();
- KeyFactory kf = KeyFactory.getInstance("DSA");
- DSAPublicKeySpec ks = new DSAPublicKeySpec(y,
- params.getP(),
- params.getQ(),
- params.getG());
- currPubKey = kf.generatePublic(ks);
- } catch (GeneralSecurityException e) {
- throw new CertPathValidatorException("Unable to generate " +
+ try {
+ BigInteger y = ((DSAPublicKey)currPubKey).getY();
+ KeyFactory kf = KeyFactory.getInstance("DSA");
+ DSAPublicKeySpec ks = new DSAPublicKeySpec(y, params.getP(),
+ params.getQ(), params.getG());
+ currPubKey = kf.generatePublic(ks);
+ } catch (GeneralSecurityException e) {
+ throw new CertPathValidatorException("Unable to generate " +
"key with inherited parameters: " + e.getMessage(), e);
- }
}
}
// reset the previous public key
prevPubKey = currPubKey;
-
- // check the extended key usage, ignore the check now
- // List<String> extendedKeyUsages = x509Cert.getExtendedKeyUsage();
-
- // DO NOT remove any unresolved critical extensions
}
/**
@@ -456,8 +430,10 @@
*
* @param key the public key to verify the CRL signature
* @param crl the target CRL
+ * @param variant is the Validator variants of the operation. A null value
+ * passed will set it to Validator.GENERIC.
*/
- static void check(PublicKey key, X509CRL crl)
+ static void check(PublicKey key, X509CRL crl, String variant)
throws CertPathValidatorException {
X509CRLImpl x509CRLImpl = null;
@@ -468,7 +444,7 @@
}
AlgorithmId algorithmId = x509CRLImpl.getSigAlgId();
- check(key, algorithmId);
+ check(key, algorithmId, variant);
}
/**
@@ -476,20 +452,16 @@
*
* @param key the public key to verify the CRL signature
* @param algorithmId signature algorithm Algorithm ID
+ * @param variant is the Validator variants of the operation. A null value
+ * passed will set it to Validator.GENERIC.
*/
- static void check(PublicKey key, AlgorithmId algorithmId)
+ static void check(PublicKey key, AlgorithmId algorithmId, String variant)
throws CertPathValidatorException {
String sigAlgName = algorithmId.getName();
AlgorithmParameters sigAlgParams = algorithmId.getParameters();
- if (!certPathDefaultConstraints.permits(
- SIGNATURE_PRIMITIVE_SET, sigAlgName, key, sigAlgParams)) {
- throw new CertPathValidatorException(
- "Algorithm constraints check failed on signature algorithm: " +
- sigAlgName + " is disabled",
- null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
- }
+ certPathDefaultConstraints.permits(new ConstraintsParameters(
+ sigAlgName, sigAlgParams, key, variant));
}
-
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/DistributionPointFetcher.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,6 +33,7 @@
import java.util.*;
import sun.security.util.Debug;
+import sun.security.validator.Validator;
import static sun.security.x509.PKIXExtensions.*;
import sun.security.x509.*;
@@ -66,6 +67,20 @@
* an X509CRLSelector with certificateChecking set.
*/
public static Collection<X509CRL> getCRLs(X509CRLSelector selector,
+ boolean signFlag, PublicKey prevKey, String provider,
+ List<CertStore> certStores, boolean[] reasonsMask,
+ Set<TrustAnchor> trustAnchors, Date validity, String variant)
+ throws CertStoreException
+ {
+ return getCRLs(selector, signFlag, prevKey, null, provider, certStores,
+ reasonsMask, trustAnchors, validity, variant);
+ }
+ /**
+ * Return the X509CRLs matching this selector. The selector must be
+ * an X509CRLSelector with certificateChecking set.
+ */
+ // Called by com.sun.deploy.security.RevocationChecker
+ public static Collection<X509CRL> getCRLs(X509CRLSelector selector,
boolean signFlag,
PublicKey prevKey,
String provider,
@@ -76,7 +91,7 @@
throws CertStoreException
{
return getCRLs(selector, signFlag, prevKey, null, provider, certStores,
- reasonsMask, trustAnchors, validity);
+ reasonsMask, trustAnchors, validity, Validator.VAR_GENERIC);
}
/**
@@ -91,7 +106,8 @@
List<CertStore> certStores,
boolean[] reasonsMask,
Set<TrustAnchor> trustAnchors,
- Date validity)
+ Date validity,
+ String variant)
throws CertStoreException
{
X509Certificate cert = selector.getCertificateChecking();
@@ -120,7 +136,7 @@
DistributionPoint point = t.next();
Collection<X509CRL> crls = getCRLs(selector, certImpl,
point, reasonsMask, signFlag, prevKey, prevCert, provider,
- certStores, trustAnchors, validity);
+ certStores, trustAnchors, validity, variant);
results.addAll(crls);
}
if (debug != null) {
@@ -145,7 +161,7 @@
X509CertImpl certImpl, DistributionPoint point, boolean[] reasonsMask,
boolean signFlag, PublicKey prevKey, X509Certificate prevCert,
String provider, List<CertStore> certStores,
- Set<TrustAnchor> trustAnchors, Date validity)
+ Set<TrustAnchor> trustAnchors, Date validity, String variant)
throws CertStoreException {
// check for full name
@@ -208,7 +224,7 @@
selector.setIssuerNames(null);
if (selector.match(crl) && verifyCRL(certImpl, point, crl,
reasonsMask, signFlag, prevKey, prevCert, provider,
- trustAnchors, certStores, validity)) {
+ trustAnchors, certStores, validity, variant)) {
crls.add(crl);
}
} catch (IOException | CRLException e) {
@@ -316,7 +332,7 @@
X509CRL crl, boolean[] reasonsMask, boolean signFlag,
PublicKey prevKey, X509Certificate prevCert, String provider,
Set<TrustAnchor> trustAnchors, List<CertStore> certStores,
- Date validity) throws CRLException, IOException {
+ Date validity, String variant) throws CRLException, IOException {
if (debug != null) {
debug.println("DistributionPointFetcher.verifyCRL: " +
@@ -663,7 +679,7 @@
// check the crl signature algorithm
try {
- AlgorithmChecker.check(prevKey, crl);
+ AlgorithmChecker.check(prevKey, crl, variant);
} catch (CertPathValidatorException cpve) {
if (debug != null) {
debug.println("CRL signature algorithm check failed: " + cpve);
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,7 @@
import sun.security.action.GetIntegerAction;
import sun.security.util.Debug;
+import sun.security.validator.Validator;
import sun.security.x509.AccessDescription;
import sun.security.x509.AuthorityInfoAccessExtension;
import sun.security.x509.GeneralName;
@@ -94,42 +95,6 @@
private OCSP() {}
- /**
- * Obtains the revocation status of a certificate using OCSP using the most
- * common defaults. The OCSP responder URI is retrieved from the
- * certificate's AIA extension. The OCSP responder certificate is assumed
- * to be the issuer's certificate (or issued by the issuer CA).
- *
- * @param cert the certificate to be checked
- * @param issuerCert the issuer certificate
- * @return the RevocationStatus
- * @throws IOException if there is an exception connecting to or
- * communicating with the OCSP responder
- * @throws CertPathValidatorException if an exception occurs while
- * encoding the OCSP Request or validating the OCSP Response
- */
- public static RevocationStatus check(X509Certificate cert,
- X509Certificate issuerCert)
- throws IOException, CertPathValidatorException {
- CertId certId = null;
- URI responderURI = null;
- try {
- X509CertImpl certImpl = X509CertImpl.toImpl(cert);
- responderURI = getResponderURI(certImpl);
- if (responderURI == null) {
- throw new CertPathValidatorException
- ("No OCSP Responder URI in certificate");
- }
- certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
- } catch (CertificateException | IOException e) {
- throw new CertPathValidatorException
- ("Exception while encoding OCSPRequest", e);
- }
- OCSPResponse ocspResponse = check(Collections.singletonList(certId),
- responderURI, new OCSPResponse.IssuerInfo(issuerCert), null, null,
- Collections.<Extension>emptyList());
- return (RevocationStatus)ocspResponse.getSingleResponse(certId);
- }
/**
* Obtains the revocation status of a certificate using OCSP.
@@ -146,6 +111,8 @@
* @throws CertPathValidatorException if an exception occurs while
* encoding the OCSP Request or validating the OCSP Response
*/
+
+ // Called by com.sun.deploy.security.TrustDecider
public static RevocationStatus check(X509Certificate cert,
X509Certificate issuerCert,
URI responderURI,
@@ -154,27 +121,27 @@
throws IOException, CertPathValidatorException
{
return check(cert, issuerCert, responderURI, responderCert, date,
- Collections.<Extension>emptyList());
+ Collections.<Extension>emptyList(), Validator.VAR_GENERIC);
}
- // Called by com.sun.deploy.security.TrustDecider
+
public static RevocationStatus check(X509Certificate cert,
- X509Certificate issuerCert,
- URI responderURI,
- X509Certificate responderCert,
- Date date, List<Extension> extensions)
+ X509Certificate issuerCert, URI responderURI,
+ X509Certificate responderCert, Date date, List<Extension> extensions,
+ String variant)
throws IOException, CertPathValidatorException
{
- return check(cert, responderURI, null, issuerCert, responderCert, date, extensions);
+ return check(cert, responderURI, null, issuerCert, responderCert, date,
+ extensions, variant);
}
public static RevocationStatus check(X509Certificate cert,
URI responderURI, TrustAnchor anchor, X509Certificate issuerCert,
X509Certificate responderCert, Date date,
- List<Extension> extensions)
+ List<Extension> extensions, String variant)
throws IOException, CertPathValidatorException
{
- CertId certId = null;
+ CertId certId;
try {
X509CertImpl certImpl = X509CertImpl.toImpl(cert);
certId = new CertId(issuerCert, certImpl.getSerialNumberObject());
@@ -184,7 +151,7 @@
}
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
responderURI, new OCSPResponse.IssuerInfo(anchor, issuerCert),
- responderCert, date, extensions);
+ responderCert, date, extensions, variant);
return (RevocationStatus) ocspResponse.getSingleResponse(certId);
}
@@ -206,10 +173,10 @@
* @throws CertPathValidatorException if an exception occurs while
* encoding the OCSP Request or validating the OCSP Response
*/
- static OCSPResponse check(List<CertId> certIds, URI responderURI,
+ static OCSPResponse check(List<CertId> certIds, URI responderURI,
OCSPResponse.IssuerInfo issuerInfo,
X509Certificate responderCert, Date date,
- List<Extension> extensions)
+ List<Extension> extensions, String variant)
throws IOException, CertPathValidatorException
{
byte[] nonce = null;
@@ -226,7 +193,7 @@
// verify the response
ocspResponse.verify(certIds, issuerInfo, responderCert, date,
- nonce);
+ nonce, variant);
} catch (IOException ioe) {
throw new CertPathValidatorException(
"Unable to determine revocation status due to network error",
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.Objects;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
@@ -375,7 +374,8 @@
}
void verify(List<CertId> certIds, IssuerInfo issuerInfo,
- X509Certificate responderCert, Date date, byte[] nonce)
+ X509Certificate responderCert, Date date, byte[] nonce,
+ String variant)
throws CertPathValidatorException
{
switch (responseStatus) {
@@ -508,7 +508,8 @@
// Check algorithm constraints specified in security property
// "jdk.certpath.disabledAlgorithms".
AlgorithmChecker algChecker =
- new AlgorithmChecker(issuerInfo.getAnchor(), date);
+ new AlgorithmChecker(issuerInfo.getAnchor(), date,
+ variant);
algChecker.init(false);
algChecker.check(signerCert, Collections.<String>emptySet());
@@ -568,7 +569,7 @@
if (signerCert != null) {
// Check algorithm constraints specified in security property
// "jdk.certpath.disabledAlgorithms".
- AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId);
+ AlgorithmChecker.check(signerCert.getPublicKey(), sigAlgId, variant);
if (!verifySignature(signerCert)) {
throw new CertPathValidatorException(
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIX.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -87,6 +87,7 @@
private Set<TrustAnchor> anchors;
private List<X509Certificate> certs;
private Timestamp timestamp;
+ private String variant;
ValidatorParams(CertPath cp, PKIXParameters params)
throws InvalidAlgorithmParameterException
@@ -102,8 +103,9 @@
ValidatorParams(PKIXParameters params)
throws InvalidAlgorithmParameterException
{
- if (params instanceof PKIXTimestampParameters) {
- timestamp = ((PKIXTimestampParameters) params).getTimestamp();
+ if (params instanceof PKIXExtendedParameters) {
+ timestamp = ((PKIXExtendedParameters) params).getTimestamp();
+ variant = ((PKIXExtendedParameters) params).getVariant();
}
this.anchors = params.getTrustAnchors();
@@ -199,6 +201,10 @@
Timestamp timestamp() {
return timestamp;
}
+
+ String variant() {
+ return variant;
+ }
}
static class BuilderParams extends ValidatorParams {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXCertPathValidator.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -173,9 +173,10 @@
// add standard checkers that we will be using
certPathCheckers.add(untrustedChecker);
if (params.timestamp() == null) {
- certPathCheckers.add(new AlgorithmChecker(anchor, params.date()));
+ certPathCheckers.add(new AlgorithmChecker(anchor, params.date(), null));
} else {
- certPathCheckers.add(new AlgorithmChecker(params.timestamp()));
+ certPathCheckers.add(new AlgorithmChecker(null,
+ params.timestamp(), params.variant()));
}
certPathCheckers.add(new KeyChecker(certPathLen,
params.targetCertConstraints()));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXExtendedParameters.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.certpath;
+
+import java.security.InvalidAlgorithmParameterException;
+import java.security.Timestamp;
+import java.security.cert.CertSelector;
+import java.security.cert.CertStore;
+import java.security.cert.PKIXBuilderParameters;
+import java.security.cert.PKIXCertPathChecker;
+import java.security.cert.TrustAnchor;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is a wrapper for PKIXBuilderParameters so that a Timestamp object
+ * and a string for the variant type, can be passed when doing certpath
+ * checking.
+ */
+
+public class PKIXExtendedParameters extends PKIXBuilderParameters {
+
+ private final PKIXBuilderParameters p;
+ private Timestamp jarTimestamp;
+ private final String variant;
+
+ public PKIXExtendedParameters(PKIXBuilderParameters params,
+ Timestamp timestamp, String variant)
+ throws InvalidAlgorithmParameterException {
+ super(params.getTrustAnchors(), null);
+ p = params;
+ jarTimestamp = timestamp;
+ this.variant = variant;
+ }
+
+ public Timestamp getTimestamp() {
+ return jarTimestamp;
+ }
+ public void setTimestamp(Timestamp t) {
+ jarTimestamp = t;
+ }
+
+ public String getVariant() {
+ return variant;
+ }
+
+ @Override
+ public void setDate(Date d) {
+ p.setDate(d);
+ }
+
+ @Override
+ public void addCertPathChecker(PKIXCertPathChecker c) {
+ p.addCertPathChecker(c);
+ }
+
+ @Override
+ public void setMaxPathLength(int maxPathLength) {
+ p.setMaxPathLength(maxPathLength);
+ }
+
+ @Override
+ public int getMaxPathLength() {
+ return p.getMaxPathLength();
+ }
+
+ @Override
+ public String toString() {
+ return p.toString();
+ }
+
+ @Override
+ public Set<TrustAnchor> getTrustAnchors() {
+ return p.getTrustAnchors();
+ }
+
+ @Override
+ public void setTrustAnchors(Set<TrustAnchor> trustAnchors)
+ throws InvalidAlgorithmParameterException {
+ // To avoid problems with PKIXBuilderParameter's constructors
+ if (p == null) {
+ return;
+ }
+ p.setTrustAnchors(trustAnchors);
+ }
+
+ @Override
+ public Set<String> getInitialPolicies() {
+ return p.getInitialPolicies();
+ }
+
+ @Override
+ public void setInitialPolicies(Set<String> initialPolicies) {
+ p.setInitialPolicies(initialPolicies);
+ }
+
+ @Override
+ public void setCertStores(List<CertStore> stores) {
+ p.setCertStores(stores);
+ }
+
+ @Override
+ public void addCertStore(CertStore store) {
+ p.addCertStore(store);
+ }
+
+ @Override
+ public List<CertStore> getCertStores() {
+ return p.getCertStores();
+ }
+
+ @Override
+ public void setRevocationEnabled(boolean val) {
+ p.setRevocationEnabled(val);
+ }
+
+ @Override
+ public boolean isRevocationEnabled() {
+ return p.isRevocationEnabled();
+ }
+
+ @Override
+ public void setExplicitPolicyRequired(boolean val) {
+ p.setExplicitPolicyRequired(val);
+ }
+
+ @Override
+ public boolean isExplicitPolicyRequired() {
+ return p.isExplicitPolicyRequired();
+ }
+
+ @Override
+ public void setPolicyMappingInhibited(boolean val) {
+ p.setPolicyMappingInhibited(val);
+ }
+
+ @Override
+ public boolean isPolicyMappingInhibited() {
+ return p.isPolicyMappingInhibited();
+ }
+
+ @Override
+ public void setAnyPolicyInhibited(boolean val) {
+ p.setAnyPolicyInhibited(val);
+ }
+
+ @Override
+ public boolean isAnyPolicyInhibited() {
+ return p.isAnyPolicyInhibited();
+ }
+
+ @Override
+ public void setPolicyQualifiersRejected(boolean qualifiersRejected) {
+ p.setPolicyQualifiersRejected(qualifiersRejected);
+ }
+
+ @Override
+ public boolean getPolicyQualifiersRejected() {
+ return p.getPolicyQualifiersRejected();
+ }
+
+ @Override
+ public Date getDate() {
+ return p.getDate();
+ }
+
+ @Override
+ public void setCertPathCheckers(List<PKIXCertPathChecker> checkers) {
+ p.setCertPathCheckers(checkers);
+ }
+
+ @Override
+ public List<PKIXCertPathChecker> getCertPathCheckers() {
+ return p.getCertPathCheckers();
+ }
+
+ @Override
+ public String getSigProvider() {
+ return p.getSigProvider();
+ }
+
+ @Override
+ public void setSigProvider(String sigProvider) {
+ p.setSigProvider(sigProvider);
+ }
+
+ @Override
+ public CertSelector getTargetCertConstraints() {
+ return p.getTargetCertConstraints();
+ }
+
+ @Override
+ public void setTargetCertConstraints(CertSelector selector) {
+ // To avoid problems with PKIXBuilderParameter's constructors
+ if (p == null) {
+ return;
+ }
+ p.setTargetCertConstraints(selector);
+ }
+
+}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/PKIXTimestampParameters.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,218 +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 sun.security.provider.certpath;
-
-import java.security.InvalidAlgorithmParameterException;
-import java.security.Timestamp;
-import java.security.cert.CertSelector;
-import java.security.cert.CertStore;
-import java.security.cert.PKIXBuilderParameters;
-import java.security.cert.PKIXCertPathChecker;
-import java.security.cert.TrustAnchor;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-
-/**
- * This class is a wrapper for PKIXBuilderParameters so that a Timestamp object
- * can be passed alone when PKIXCertPath is checking signed jar files.
- */
-
-public class PKIXTimestampParameters extends PKIXBuilderParameters {
-
- private final PKIXBuilderParameters p;
- private Timestamp jarTimestamp;
-
- public PKIXTimestampParameters(PKIXBuilderParameters params,
- Timestamp timestamp) throws InvalidAlgorithmParameterException {
- super(params.getTrustAnchors(), null);
- p = params;
- jarTimestamp = timestamp;
- }
-
- public Timestamp getTimestamp() {
- return jarTimestamp;
- }
- public void setTimestamp(Timestamp t) {
- jarTimestamp = t;
- }
-
- @Override
- public void setDate(Date d) {
- p.setDate(d);
- }
-
- @Override
- public void addCertPathChecker(PKIXCertPathChecker c) {
- p.addCertPathChecker(c);
- }
-
- @Override
- public void setMaxPathLength(int maxPathLength) {
- p.setMaxPathLength(maxPathLength);
- }
-
- @Override
- public int getMaxPathLength() {
- return p.getMaxPathLength();
- }
-
- @Override
- public String toString() {
- return p.toString();
- }
-
- @Override
- public Set<TrustAnchor> getTrustAnchors() {
- return p.getTrustAnchors();
- }
-
- @Override
- public void setTrustAnchors(Set<TrustAnchor> trustAnchors)
- throws InvalidAlgorithmParameterException {
- // To avoid problems with PKIXBuilderParameter's constructors
- if (p == null) {
- return;
- }
- p.setTrustAnchors(trustAnchors);
- }
-
- @Override
- public Set<String> getInitialPolicies() {
- return p.getInitialPolicies();
- }
-
- @Override
- public void setInitialPolicies(Set<String> initialPolicies) {
- p.setInitialPolicies(initialPolicies);
- }
-
- @Override
- public void setCertStores(List<CertStore> stores) {
- p.setCertStores(stores);
- }
-
- @Override
- public void addCertStore(CertStore store) {
- p.addCertStore(store);
- }
-
- @Override
- public List<CertStore> getCertStores() {
- return p.getCertStores();
- }
-
- @Override
- public void setRevocationEnabled(boolean val) {
- p.setRevocationEnabled(val);
- }
-
- @Override
- public boolean isRevocationEnabled() {
- return p.isRevocationEnabled();
- }
-
- @Override
- public void setExplicitPolicyRequired(boolean val) {
- p.setExplicitPolicyRequired(val);
- }
-
- @Override
- public boolean isExplicitPolicyRequired() {
- return p.isExplicitPolicyRequired();
- }
-
- @Override
- public void setPolicyMappingInhibited(boolean val) {
- p.setPolicyMappingInhibited(val);
- }
-
- @Override
- public boolean isPolicyMappingInhibited() {
- return p.isPolicyMappingInhibited();
- }
-
- @Override
- public void setAnyPolicyInhibited(boolean val) {
- p.setAnyPolicyInhibited(val);
- }
-
- @Override
- public boolean isAnyPolicyInhibited() {
- return p.isAnyPolicyInhibited();
- }
-
- @Override
- public void setPolicyQualifiersRejected(boolean qualifiersRejected) {
- p.setPolicyQualifiersRejected(qualifiersRejected);
- }
-
- @Override
- public boolean getPolicyQualifiersRejected() {
- return p.getPolicyQualifiersRejected();
- }
-
- @Override
- public Date getDate() {
- return p.getDate();
- }
-
- @Override
- public void setCertPathCheckers(List<PKIXCertPathChecker> checkers) {
- p.setCertPathCheckers(checkers);
- }
-
- @Override
- public List<PKIXCertPathChecker> getCertPathCheckers() {
- return p.getCertPathCheckers();
- }
-
- @Override
- public String getSigProvider() {
- return p.getSigProvider();
- }
-
- @Override
- public void setSigProvider(String sigProvider) {
- p.setSigProvider(sigProvider);
- }
-
- @Override
- public CertSelector getTargetCertConstraints() {
- return p.getTargetCertConstraints();
- }
-
- @Override
- public void setTargetCertConstraints(CertSelector selector) {
- // To avoid problems with PKIXBuilderParameter's constructors
- if (p == null) {
- return;
- }
- p.setTargetCertConstraints(selector);
- }
-
-}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -579,7 +579,7 @@
approvedCRLs.addAll(DistributionPointFetcher.getCRLs(
sel, signFlag, prevKey, prevCert,
params.sigProvider(), certStores,
- reasonsMask, anchors, null));
+ reasonsMask, anchors, null, params.variant()));
}
} catch (CertStoreException e) {
if (e instanceof CertStoreTypeException) {
@@ -727,7 +727,7 @@
}
}
response.verify(Collections.singletonList(certId), issuerInfo,
- responderCert, params.date(), nonce);
+ responderCert, params.date(), nonce, params.variant());
} else {
URI responderURI = (this.responderURI != null)
@@ -741,7 +741,7 @@
response = OCSP.check(Collections.singletonList(certId),
responderURI, issuerInfo, responderCert, null,
- ocspExtensions);
+ ocspExtensions, params.variant());
}
} catch (IOException e) {
throw new CertPathValidatorException(
@@ -853,7 +853,7 @@
if (DistributionPointFetcher.verifyCRL(
certImpl, point, crl, reasonsMask, signFlag,
prevKey, null, params.sigProvider(), anchors,
- certStores, params.date()))
+ certStores, params.date(), params.variant()))
{
results.add(crl);
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/SunCertPathBuilder.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -344,7 +344,7 @@
// add the algorithm checker
checkers.add(new AlgorithmChecker(builder.trustAnchor,
- buildParams.date()));
+ buildParams.date(), null));
BasicChecker basicChecker = null;
if (nextState.keyParamsNeeded()) {
--- a/jdk/src/java.base/share/classes/sun/security/ssl/EllipticCurvesExtension.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/EllipticCurvesExtension.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -43,6 +43,9 @@
final class EllipticCurvesExtension extends HelloExtension {
+ /* Class and subclass dynamic debugging support */
+ private static final Debug debug = Debug.getInstance("ssl");
+
private static final int ARBITRARY_PRIME = 0xff01;
private static final int ARBITRARY_CHAR2 = 0xff02;
@@ -159,6 +162,11 @@
} // ignore unknown curves
}
}
+ if (idList.isEmpty() && JsseJce.isEcAvailable()) {
+ throw new IllegalArgumentException(
+ "System property jdk.tls.namedGroups(" + property + ") " +
+ "contains no supported elliptic curves");
+ }
} else { // default curves
int[] ids;
if (requireFips) {
@@ -183,16 +191,17 @@
}
}
- if (idList.isEmpty()) {
- throw new IllegalArgumentException(
- "System property jdk.tls.namedGroups(" + property + ") " +
- "contains no supported elliptic curves");
- } else {
- supportedCurveIds = new int[idList.size()];
- int i = 0;
- for (Integer id : idList) {
- supportedCurveIds[i++] = id;
- }
+ if (debug != null && idList.isEmpty()) {
+ Debug.log(
+ "Initialized [jdk.tls.namedGroups|default] list contains " +
+ "no available elliptic curves. " +
+ (property != null ? "(" + property + ")" : "[Default]"));
+ }
+
+ supportedCurveIds = new int[idList.size()];
+ int i = 0;
+ for (Integer id : idList) {
+ supportedCurveIds[i++] = id;
}
}
--- a/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,6 +37,7 @@
import sun.security.provider.certpath.AlgorithmChecker;
import sun.security.action.GetPropertyAction;
+import sun.security.validator.Validator;
public abstract class SSLContextImpl extends SSLContextSpi {
@@ -1436,7 +1437,7 @@
constraints = new SSLAlgorithmConstraints(sslSocket, true);
}
- checkAlgorithmConstraints(chain, constraints);
+ checkAlgorithmConstraints(chain, constraints, isClient);
}
}
@@ -1478,12 +1479,12 @@
constraints = new SSLAlgorithmConstraints(engine, true);
}
- checkAlgorithmConstraints(chain, constraints);
+ checkAlgorithmConstraints(chain, constraints, isClient);
}
}
private void checkAlgorithmConstraints(X509Certificate[] chain,
- AlgorithmConstraints constraints) throws CertificateException {
+ AlgorithmConstraints constraints, boolean isClient) throws CertificateException {
try {
// Does the certificate chain end with a trusted certificate?
@@ -1501,7 +1502,9 @@
// A forward checker, need to check from trust to target
if (checkedLength >= 0) {
- AlgorithmChecker checker = new AlgorithmChecker(constraints);
+ AlgorithmChecker checker =
+ new AlgorithmChecker(constraints, null,
+ (isClient ? Validator.VAR_TLS_CLIENT : Validator.VAR_TLS_SERVER));
checker.init(false);
for (int i = checkedLength; i >= 0; i--) {
Certificate cert = chain[i];
--- a/jdk/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/ssl/X509KeyManagerImpl.java Wed Jul 05 22:52:22 2017 +0200
@@ -39,6 +39,7 @@
import javax.net.ssl.*;
import sun.security.provider.certpath.AlgorithmChecker;
+import sun.security.validator.Validator;
/**
* The new X509 key manager implementation. The main differences to the
@@ -661,6 +662,15 @@
return CheckResult.OK;
}
+
+ public String getValidator() {
+ if (this == CLIENT) {
+ return Validator.VAR_TLS_CLIENT;
+ } else if (this == SERVER) {
+ return Validator.VAR_TLS_SERVER;
+ }
+ return Validator.VAR_GENERIC;
+ }
}
// enum for the result of the extension check
@@ -774,7 +784,8 @@
// check the algorithm constraints
if (constraints != null &&
- !conformsToAlgorithmConstraints(constraints, chain)) {
+ !conformsToAlgorithmConstraints(constraints, chain,
+ checkType.getValidator())) {
if (useDebug) {
debug.println("Ignoring alias " + alias +
@@ -811,9 +822,10 @@
}
private static boolean conformsToAlgorithmConstraints(
- AlgorithmConstraints constraints, Certificate[] chain) {
+ AlgorithmConstraints constraints, Certificate[] chain,
+ String variant) {
- AlgorithmChecker checker = new AlgorithmChecker(constraints);
+ AlgorithmChecker checker = new AlgorithmChecker(constraints, null, variant);
try {
checker.init(false);
} catch (CertPathValidatorException cpve) {
--- a/jdk/src/java.base/share/classes/sun/security/util/CertConstraintParameters.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +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 sun.security.util;
-
-import java.security.Timestamp;
-import java.security.cert.X509Certificate;
-import java.util.Date;
-
-/**
- * This class is a wrapper for keeping state and passing objects between PKIX,
- * AlgorithmChecker, and DisabledAlgorithmConstraints.
- */
-public class CertConstraintParameters {
- // A certificate being passed to check against constraints.
- private final X509Certificate cert;
- // This is true if the trust anchor in the certificate chain matches a cert
- // in AnchorCertificates
- private final boolean trustedMatch;
- // PKIXParameter date
- private final Date pkixDate;
- // Timestamp of the signed JAR file
- private final Timestamp jarTimestamp;
-
- public CertConstraintParameters(X509Certificate c, boolean match,
- Date pkixdate, Timestamp jarTime) {
- cert = c;
- trustedMatch = match;
- pkixDate = pkixdate;
- jarTimestamp = jarTime;
- }
-
- public CertConstraintParameters(X509Certificate c) {
- this(c, false, null, null);
- }
-
- // Returns if the trust anchor has a match if anchor checking is enabled.
- public boolean isTrustedMatch() {
- return trustedMatch;
- }
-
- public X509Certificate getCertificate() {
- return cert;
- }
-
- public Date getPKIXParamDate() {
- return pkixDate;
- }
-
- public Timestamp getJARTimestamp() {
- return jarTimestamp;
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/ConstraintsParameters.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2016, 2017 Oracle and/or its affiliates. All rights reserved.
+ * 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.util;
+
+import sun.security.validator.Validator;
+
+import java.security.AlgorithmParameters;
+import java.security.Key;
+import java.security.Timestamp;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+
+/**
+ * This class contains parameters for checking against constraints that extend
+ * past the publicly available parameters in java.security.AlgorithmConstraints.
+
+ * This is currently on passed between between PKIX, AlgorithmChecker,
+ * and DisabledAlgorithmConstraints.
+ */
+public class ConstraintsParameters {
+ /*
+ * The below 3 values are used the same as the permit() methods
+ * published in java.security.AlgorithmConstraints.
+ */
+ // Algorithm string to be checked against constraints
+ private final String algorithm;
+ // AlgorithmParameters to the algorithm being checked
+ private final AlgorithmParameters algParams;
+ // Public Key being checked against constraints
+ private final Key publicKey;
+
+ /*
+ * New values that are checked against constraints that the current public
+ * API does not support.
+ */
+ // A certificate being passed to check against constraints.
+ private final X509Certificate cert;
+ // This is true if the trust anchor in the certificate chain matches a cert
+ // in AnchorCertificates
+ private final boolean trustedMatch;
+ // PKIXParameter date
+ private final Date pkixDate;
+ // Timestamp of the signed JAR file
+ private final Timestamp jarTimestamp;
+ private final String variant;
+
+ public ConstraintsParameters(X509Certificate c, boolean match,
+ Date pkixdate, Timestamp jarTime, String variant) {
+ cert = c;
+ trustedMatch = match;
+ pkixDate = pkixdate;
+ jarTimestamp = jarTime;
+ this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
+ algorithm = null;
+ algParams = null;
+ publicKey = null;
+ }
+
+ public ConstraintsParameters(String algorithm, AlgorithmParameters params,
+ Key key, String variant) {
+ this.algorithm = algorithm;
+ algParams = params;
+ this.publicKey = key;
+ cert = null;
+ trustedMatch = false;
+ pkixDate = null;
+ jarTimestamp = null;
+ this.variant = (variant == null ? Validator.VAR_GENERIC : variant);
+ }
+
+
+ public ConstraintsParameters(X509Certificate c) {
+ this(c, false, null, null,
+ Validator.VAR_GENERIC);
+ }
+
+ public ConstraintsParameters(Timestamp jarTime) {
+ this(null, false, null, jarTime, Validator.VAR_GENERIC);
+ }
+
+ public String getAlgorithm() {
+ return algorithm;
+ }
+
+ public AlgorithmParameters getAlgParams() {
+ return algParams;
+ }
+
+ public Key getPublicKey() {
+ return publicKey;
+ }
+ // Returns if the trust anchor has a match if anchor checking is enabled.
+ public boolean isTrustedMatch() {
+ return trustedMatch;
+ }
+
+ public X509Certificate getCertificate() {
+ return cert;
+ }
+
+ public Date getPKIXParamDate() {
+ return pkixDate;
+ }
+
+ public Timestamp getJARTimestamp() {
+ return jarTimestamp;
+ }
+
+ public String getVariant() {
+ return variant;
+ }
+}
--- a/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,6 +25,8 @@
package sun.security.util;
+import sun.security.validator.Validator;
+
import java.security.CryptoPrimitive;
import java.security.AlgorithmParameters;
import java.security.Key;
@@ -32,10 +34,12 @@
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
+import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -100,12 +104,6 @@
@Override
public final boolean permits(Set<CryptoPrimitive> primitives,
String algorithm, AlgorithmParameters parameters) {
-
- if (primitives == null || primitives.isEmpty()) {
- throw new IllegalArgumentException(
- "No cryptographic primitive specified");
- }
-
return checkAlgorithm(disabledAlgorithms, algorithm, decomposer);
}
@@ -133,6 +131,18 @@
return checkConstraints(primitives, algorithm, key, parameters);
}
+ public final void permits(ConstraintsParameters cp)
+ throws CertPathValidatorException {
+ permits(cp.getAlgorithm(), cp);
+ }
+
+ public final void permits(String algorithm, Key key,
+ AlgorithmParameters params, String variant)
+ throws CertPathValidatorException {
+ permits(algorithm, new ConstraintsParameters(algorithm, params, key,
+ (variant == null) ? Validator.VAR_GENERIC : variant));
+ }
+
/*
* Check if a x509Certificate object is permitted. Check if all
* algorithms are allowed, certificate constraints, and the
@@ -140,18 +150,10 @@
*
* Uses new style permit() which throws exceptions.
*/
- public final void permits(Set<CryptoPrimitive> primitives,
- CertConstraintParameters cp) throws CertPathValidatorException {
- checkConstraints(primitives, cp);
- }
- /*
- * Check if Certificate object is within the constraints.
- * Uses new style permit() which throws exceptions.
- */
- public final void permits(Set<CryptoPrimitive> primitives,
- X509Certificate cert) throws CertPathValidatorException {
- checkConstraints(primitives, new CertConstraintParameters(cert));
+ public final void permits(String algorithm, ConstraintsParameters cp)
+ throws CertPathValidatorException {
+ algorithmConstraints.permits(algorithm, cp);
}
// Check if a string is contained inside the property
@@ -174,7 +176,7 @@
throw new IllegalArgumentException("The key cannot be null");
}
- // check the signature algorithm
+ // check the signature algorithm with parameters
if (algorithm != null && algorithm.length() != 0) {
if (!permits(primitives, algorithm, parameters)) {
return false;
@@ -190,36 +192,6 @@
return algorithmConstraints.permits(key);
}
- /*
- * Check algorithm constraints with Certificate
- * Uses new style permit() which throws exceptions.
- */
- private void checkConstraints(Set<CryptoPrimitive> primitives,
- CertConstraintParameters cp) throws CertPathValidatorException {
-
- X509Certificate cert = cp.getCertificate();
- String algorithm = cert.getSigAlgName();
-
- // Check signature algorithm is not disabled
- if (!permits(primitives, algorithm, null)) {
- throw new CertPathValidatorException(
- "Algorithm constraints check failed on disabled "+
- "signature algorithm: " + algorithm,
- null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
- }
-
- // Check key algorithm is not disabled
- if (!permits(primitives, cert.getPublicKey().getAlgorithm(), null)) {
- throw new CertPathValidatorException(
- "Algorithm constraints check failed on disabled "+
- "public key algorithm: " + algorithm,
- null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
- }
-
- // Check the certificate and key constraints
- algorithmConstraints.permits(cp);
-
- }
/**
* Key and Certificate Constraints
@@ -234,13 +206,13 @@
* 'true' means the operation is allowed.
* 'false' means it failed the constraints and is disallowed.
*
- * When passing CertConstraintParameters through permit(), an exception
+ * When passing ConstraintsParameters through permit(), an exception
* will be thrown on a failure to better identify why the operation was
* disallowed.
*/
private static class Constraints {
- private Map<String, Set<Constraint>> constraintsMap = new HashMap<>();
+ private Map<String, List<Constraint>> constraintsMap = new HashMap<>();
private static class Holder {
private static final Pattern DENY_AFTER_PATTERN = Pattern.compile(
@@ -260,23 +232,22 @@
// Check if constraint is a complete disabling of an
// algorithm or has conditions.
- String algorithm;
- String policy;
int space = constraintEntry.indexOf(' ');
- if (space > 0) {
- algorithm = AlgorithmDecomposer.hashName(
- constraintEntry.substring(0, space).
- toUpperCase(Locale.ENGLISH));
- policy = constraintEntry.substring(space + 1);
- } else {
- algorithm = constraintEntry.toUpperCase(Locale.ENGLISH);
- if (!constraintsMap.containsKey(algorithm)) {
- constraintsMap.putIfAbsent(algorithm,
- new HashSet<>());
- }
+ String algorithm = AlgorithmDecomposer.hashName(
+ ((space > 0 ? constraintEntry.substring(0, space) :
+ constraintEntry).
+ toUpperCase(Locale.ENGLISH)));
+ List<Constraint> constraintList =
+ constraintsMap.getOrDefault(algorithm,
+ new ArrayList<>(1));
+ constraintsMap.putIfAbsent(algorithm, constraintList);
+ if (space <= 0) {
+ constraintList.add(new DisabledConstraint(algorithm));
continue;
}
+ String policy = constraintEntry.substring(space + 1);
+
// Convert constraint conditions into Constraint classes
Constraint c, lastConstraint = null;
// Allow only one jdkCA entry per constraint entry
@@ -315,7 +286,7 @@
c = new jdkCAConstraint(algorithm);
jdkCALimit = true;
- } else if(entry.startsWith("denyAfter") &&
+ } else if (entry.startsWith("denyAfter") &&
(matcher = Holder.DENY_AFTER_PATTERN.matcher(entry))
.matches()) {
if (debug != null) {
@@ -332,6 +303,12 @@
c = new DenyAfterConstraint(algorithm, year, month,
day);
denyAfterLimit = true;
+ } else if (entry.startsWith("usage")) {
+ String s[] = (entry.substring(5)).trim().split(" ");
+ c = new UsageConstraint(algorithm, s);
+ if (debug != null) {
+ debug.println("Constraints usage length is " + s.length);
+ }
} else {
throw new IllegalArgumentException("Error in security" +
" property. Constraint unknown: " + entry);
@@ -340,11 +317,7 @@
// Link multiple conditions for a single constraint
// into a linked list.
if (lastConstraint == null) {
- if (!constraintsMap.containsKey(algorithm)) {
- constraintsMap.putIfAbsent(algorithm,
- new HashSet<>());
- }
- constraintsMap.get(algorithm).add(c);
+ constraintList.add(c);
} else {
lastConstraint.nextConstraint = c;
}
@@ -354,17 +327,17 @@
}
// Get applicable constraints based off the signature algorithm
- private Set<Constraint> getConstraints(String algorithm) {
+ private List<Constraint> getConstraints(String algorithm) {
return constraintsMap.get(algorithm);
}
// Check if KeySizeConstraints permit the specified key
public boolean permits(Key key) {
- Set<Constraint> set = getConstraints(key.getAlgorithm());
- if (set == null) {
+ List<Constraint> list = getConstraints(key.getAlgorithm());
+ if (list == null) {
return true;
}
- for (Constraint constraint : set) {
+ for (Constraint constraint : list) {
if (!constraint.permits(key)) {
if (debug != null) {
debug.println("keySizeConstraint: failed key " +
@@ -377,31 +350,35 @@
}
// Check if constraints permit this cert.
- public void permits(CertConstraintParameters cp)
+ public void permits(String algorithm, ConstraintsParameters cp)
throws CertPathValidatorException {
X509Certificate cert = cp.getCertificate();
if (debug != null) {
- debug.println("Constraints.permits(): " + cert.getSigAlgName());
+ debug.println("Constraints.permits(): " + algorithm +
+ " Variant: " + cp.getVariant());
}
// Get all signature algorithms to check for constraints
- Set<String> algorithms =
- AlgorithmDecomposer.decomposeOneHash(cert.getSigAlgName());
- if (algorithms == null || algorithms.isEmpty()) {
- return;
+ Set<String> algorithms = new HashSet<>();
+ if (algorithm != null) {
+ algorithms.addAll(AlgorithmDecomposer.decomposeOneHash(algorithm));
}
- // Attempt to add the public key algorithm to the set
- algorithms.add(cert.getPublicKey().getAlgorithm());
-
+ // Attempt to add the public key algorithm if cert provided
+ if (cert != null) {
+ algorithms.add(cert.getPublicKey().getAlgorithm());
+ }
+ if (cp.getPublicKey() != null) {
+ algorithms.add(cp.getPublicKey().getAlgorithm());
+ }
// Check all applicable constraints
- for (String algorithm : algorithms) {
- Set<Constraint> set = getConstraints(algorithm);
- if (set == null) {
+ for (String alg : algorithms) {
+ List<Constraint> list = getConstraints(alg);
+ if (list == null) {
continue;
}
- for (Constraint constraint : set) {
+ for (Constraint constraint : list) {
constraint.permits(cp);
}
}
@@ -467,17 +444,17 @@
/**
* Check if an algorithm constraint is permitted with a given
- * CertConstraintParameters.
+ * ConstraintsParameters.
*
* If the check inside of {@code permits()} fails, it must call
- * {@code next()} with the same {@code CertConstraintParameters}
+ * {@code next()} with the same {@code ConstraintsParameters}
* parameter passed if multiple constraints need to be checked.
*
* @param cp CertConstraintParameter containing certificate info
* @throws CertPathValidatorException if constraint disallows.
*
*/
- public abstract void permits(CertConstraintParameters cp)
+ public abstract void permits(ConstraintsParameters cp)
throws CertPathValidatorException;
/**
@@ -491,12 +468,12 @@
* were disallowed, the last constraint will throw
* {@code CertPathValidatorException}.
*
- * @param cp CertConstraintParameters
+ * @param cp ConstraintsParameters
* @return 'true' if constraint allows the operation, 'false' if
* we are at the end of the constraint list or,
* {@code nextConstraint} is null.
*/
- boolean next(CertConstraintParameters cp)
+ boolean next(ConstraintsParameters cp)
throws CertPathValidatorException {
if (nextConstraint != null) {
nextConstraint.permits(cp);
@@ -525,6 +502,14 @@
}
return false;
}
+
+ String extendedMsg(ConstraintsParameters cp) {
+ return (cp.getCertificate() == null ? "." :
+ " used with certificate: " +
+ cp.getCertificate().getSubjectX500Principal() +
+ (cp.getVariant() != Validator.VAR_GENERIC ?
+ ". Usage was " + cp.getVariant() : "."));
+ }
}
/*
@@ -537,11 +522,11 @@
}
/*
- * Check if CertConstraintParameters has a trusted match, if it does
+ * Check if ConstraintsParameters has a trusted match, if it does
* call next() for any following constraints. If it does not, exit
* as this constraint(s) does not restrict the operation.
*/
- public void permits(CertConstraintParameters cp)
+ public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
if (debug != null) {
debug.println("jdkCAConstraints.permits(): " + algorithm);
@@ -554,8 +539,7 @@
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on certificate " +
- "anchor limits. " + algorithm + " used with " +
- cp.getCertificate().getSubjectX500Principal(),
+ "anchor limits. " + algorithm + extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -615,7 +599,7 @@
* constraints. Throw an exception if this is the last constraint.
*/
@Override
- public void permits(CertConstraintParameters cp)
+ public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
Date currentDate;
String errmsg;
@@ -628,7 +612,7 @@
errmsg = "PKIXParameter date: ";
} else {
currentDate = new Date();
- errmsg = "Certificate date: ";
+ errmsg = "Current date: ";
}
if (!denyAfterDate.after(currentDate)) {
@@ -637,9 +621,9 @@
}
throw new CertPathValidatorException(
"denyAfter constraint check failed: " + algorithm +
- " used with Constraint date: " +
- dateFormat.format(denyAfterDate) + "; "
- + errmsg + dateFormat.format(currentDate),
+ " used with Constraint date: " +
+ dateFormat.format(denyAfterDate) + "; " + errmsg +
+ dateFormat.format(currentDate) + extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -661,6 +645,48 @@
}
/*
+ * The usage constraint is for the "usage" keyword. It checks against the
+ * variant value in ConstraintsParameters.
+ */
+ private static class UsageConstraint extends Constraint {
+ String[] usages;
+
+ UsageConstraint(String algorithm, String[] usages) {
+ this.algorithm = algorithm;
+ this.usages = usages;
+ }
+
+ public void permits(ConstraintsParameters cp)
+ throws CertPathValidatorException {
+ for (String usage : usages) {
+
+ String v = null;
+ if (usage.compareToIgnoreCase("TLSServer") == 0) {
+ v = Validator.VAR_TLS_SERVER;
+ } else if (usage.compareToIgnoreCase("TLSClient") == 0) {
+ v = Validator.VAR_TLS_CLIENT;
+ } else if (usage.compareToIgnoreCase("SignedJAR") == 0) {
+ v = Validator.VAR_PLUGIN_CODE_SIGNING;
+ }
+
+ if (debug != null) {
+ debug.println("Checking if usage constraint " + v +
+ " matches " + cp.getVariant());
+ }
+ if (cp.getVariant().compareTo(v) == 0) {
+ if (next(cp)) {
+ return;
+ }
+ throw new CertPathValidatorException("Usage constraint " +
+ usage + " check failed: " + algorithm +
+ extendedMsg(cp),
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+ }
+ }
+ }
+ }
+
+ /*
* This class contains constraints dealing with the key size
* support limits per algorithm. e.g. "keySize <= 1024"
*/
@@ -713,17 +739,22 @@
* constraint Any permitted constraint will exit the linked list
* to allow the operation.
*/
- public void permits(CertConstraintParameters cp)
+ public void permits(ConstraintsParameters cp)
throws CertPathValidatorException {
- if (!permitsImpl(cp.getCertificate().getPublicKey())) {
+ Key key = null;
+ if (cp.getPublicKey() != null) {
+ key = cp.getPublicKey();
+ } else if (cp.getCertificate() != null) {
+ key = cp.getCertificate().getPublicKey();
+ }
+ if (key != null && !permitsImpl(key)) {
if (nextConstraint != null) {
nextConstraint.permits(cp);
return;
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on keysize limits. "
- + algorithm + " " + size + "bit key used with "
- + cp.getCertificate().getSubjectX500Principal(),
+ + algorithm + " " + size + "bit key" + extendedMsg(cp),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -762,5 +793,26 @@
return true;
}
}
+
+ /*
+ * This constraint is used for the complete disabling of the algorithm.
+ */
+ private static class DisabledConstraint extends Constraint {
+ DisabledConstraint(String algo) {
+ algorithm = algo;
+ }
+
+ public void permits(ConstraintsParameters cp)
+ throws CertPathValidatorException {
+ throw new CertPathValidatorException(
+ "Algorithm constraints check failed on disabled " +
+ "algorithm: " + algorithm + extendedMsg(cp),
+ null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
+ }
+
+ public boolean permits(Key key) {
+ return false;
+ }
+ }
}
--- a/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,25 +28,23 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.CodeSigner;
-import java.security.CryptoPrimitive;
+import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
+import java.security.Timestamp;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.util.ArrayList;
import java.util.Base64;
-import java.util.Collections;
-import java.util.EnumSet;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
-import java.util.Set;
import java.util.jar.Attributes;
import java.util.jar.JarException;
import java.util.jar.JarFile;
@@ -61,9 +59,6 @@
/* Are we debugging ? */
private static final Debug debug = Debug.getInstance("jar");
- private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
- Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
-
private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
new DisabledAlgorithmConstraints(
DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
@@ -97,6 +92,14 @@
/* for generating certpath objects */
private CertificateFactory certificateFactory = null;
+ /** Algorithms that have been checked if they are weak. */
+ private Map<String, Boolean> permittedAlgs= new HashMap<>();
+
+ /** TSA timestamp of signed jar. The newest timestamp is used. If there
+ * was no TSA timestamp used when signed, current time is used ("null").
+ */
+ private Timestamp timestamp = null;
+
/**
* Create the named SignatureFileVerifier.
*
@@ -222,15 +225,8 @@
/** get digest from cache */
- private MessageDigest getDigest(String algorithm) throws SignatureException {
- // check that algorithm is not restricted
- if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, algorithm, null)) {
- SignatureException e =
- new SignatureException("SignatureFile check failed. " +
- "Disabled algorithm used: " + algorithm);
- throw e;
- }
-
+ private MessageDigest getDigest(String algorithm)
+ throws SignatureException {
if (createdDigests == null)
createdDigests = new HashMap<>();
@@ -302,6 +298,27 @@
if (newSigners == null)
return;
+ /*
+ * Look for the latest timestamp in the signature block. If an entry
+ * has no timestamp, use current time (aka null).
+ */
+ for (CodeSigner s: newSigners) {
+ if (debug != null) {
+ debug.println("Gathering timestamp for: " + s.toString());
+ }
+ if (s.getTimestamp() == null) {
+ timestamp = null;
+ break;
+ } else if (timestamp == null) {
+ timestamp = s.getTimestamp();
+ } else {
+ if (timestamp.getTimestamp().before(
+ s.getTimestamp().getTimestamp())) {
+ timestamp = s.getTimestamp();
+ }
+ }
+ }
+
Iterator<Map.Entry<String,Attributes>> entries =
sf.getEntries().entrySet().iterator();
@@ -345,6 +362,68 @@
}
/**
+ * Check if algorithm is permitted using the permittedAlgs Map.
+ * If the algorithm is not in the map, check against disabled algorithms and
+ * store the result. If the algorithm is in the map use that result.
+ * False is returned for weak algorithm, true for good algorithms.
+ */
+ boolean permittedCheck(String key, String algorithm) {
+ Boolean permitted = permittedAlgs.get(algorithm);
+ if (permitted == null) {
+ try {
+ JAR_DISABLED_CHECK.permits(algorithm,
+ new ConstraintsParameters(timestamp));
+ } catch(GeneralSecurityException e) {
+ permittedAlgs.put(algorithm, Boolean.FALSE);
+ permittedAlgs.put(key.toUpperCase(), Boolean.FALSE);
+ if (debug != null) {
+ if (e.getMessage() != null) {
+ debug.println(key + ": " + e.getMessage());
+ } else {
+ debug.println(key + ": " + algorithm +
+ " was disabled, no exception msg given.");
+ e.printStackTrace();
+ }
+ }
+ return false;
+ }
+
+ permittedAlgs.put(algorithm, Boolean.TRUE);
+ return true;
+ }
+
+ // Algorithm has already been checked, return the value from map.
+ return permitted.booleanValue();
+ }
+
+ /**
+ * With a given header (*-DIGEST*), return a string that lists all the
+ * algorithms associated with the header.
+ * If there are none, return "Unknown Algorithm".
+ */
+ String getWeakAlgorithms(String header) {
+ String w = "";
+ try {
+ for (String key : permittedAlgs.keySet()) {
+ if (key.endsWith(header)) {
+ w += key.substring(0, key.length() - header.length()) + " ";
+ }
+ }
+ } catch (RuntimeException e) {
+ w = "Unknown Algorithm(s). Error processing " + header + ". " +
+ e.getMessage();
+ }
+
+ // This means we have an error in finding weak algorithms, run in
+ // debug mode to see permittedAlgs map's values.
+ if (w.length() == 0) {
+ return "Unknown Algorithm(s)";
+ }
+
+ return w;
+ }
+
+ /**
* See if the whole manifest was signed.
*/
private boolean verifyManifestHash(Manifest sf,
@@ -354,6 +433,7 @@
{
Attributes mattr = sf.getMainAttributes();
boolean manifestSigned = false;
+ boolean weakAlgs = true;
// go through all the attributes and process *-Digest-Manifest entries
for (Map.Entry<Object,Object> se : mattr.entrySet()) {
@@ -364,6 +444,15 @@
// 16 is length of "-Digest-Manifest"
String algorithm = key.substring(0, key.length()-16);
+ // Check if this algorithm is permitted, skip if false.
+ if (!permittedCheck(key, algorithm)) {
+ continue;
+ }
+
+ // A non-weak algorithm was used, any weak algorithms found do
+ // not need to be reported.
+ weakAlgs = false;
+
manifestDigests.add(key);
manifestDigests.add(se.getValue());
MessageDigest digest = getDigest(algorithm);
@@ -373,15 +462,14 @@
Base64.getMimeDecoder().decode((String)se.getValue());
if (debug != null) {
- debug.println("Signature File: Manifest digest " +
- digest.getAlgorithm());
- debug.println( " sigfile " + toHex(expectedHash));
- debug.println( " computed " + toHex(computedHash));
- debug.println();
+ debug.println("Signature File: Manifest digest " +
+ algorithm);
+ debug.println( " sigfile " + toHex(expectedHash));
+ debug.println( " computed " + toHex(computedHash));
+ debug.println();
}
- if (MessageDigest.isEqual(computedHash,
- expectedHash)) {
+ if (MessageDigest.isEqual(computedHash, expectedHash)) {
manifestSigned = true;
} else {
//XXX: we will continue and verify each section
@@ -389,15 +477,31 @@
}
}
}
+
+ if (debug != null) {
+ debug.println("PermittedAlgs mapping: ");
+ for (String key : permittedAlgs.keySet()) {
+ debug.println(key + " : " +
+ permittedAlgs.get(key).toString());
+ }
+ }
+
+ // If there were only weak algorithms used, throw an exception.
+ if (weakAlgs) {
+ String weakAlgorithms = getWeakAlgorithms("-DIGEST-MANIFEST");
+ throw new SignatureException("Manifest hash check failed " +
+ "(DIGEST-MANIFEST). Disabled algorithm(s) used: " +
+ weakAlgorithms);
+ }
return manifestSigned;
}
- private boolean verifyManifestMainAttrs(Manifest sf,
- ManifestDigester md)
+ private boolean verifyManifestMainAttrs(Manifest sf, ManifestDigester md)
throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean attrsVerified = true;
+ boolean weakAlgs = true;
// go through all the attributes and process
// digest entries for the manifest main attributes
@@ -408,6 +512,15 @@
String algorithm =
key.substring(0, key.length() - ATTR_DIGEST.length());
+ // Check if this algorithm is permitted, skip if false.
+ if (!permittedCheck(key, algorithm)) {
+ continue;
+ }
+
+ // A non-weak algorithm was used, any weak algorithms found do
+ // not need to be reported.
+ weakAlgs = false;
+
MessageDigest digest = getDigest(algorithm);
if (digest != null) {
ManifestDigester.Entry mde =
@@ -425,8 +538,7 @@
debug.println();
}
- if (MessageDigest.isEqual(computedHash,
- expectedHash)) {
+ if (MessageDigest.isEqual(computedHash, expectedHash)) {
// good
} else {
// we will *not* continue and verify each section
@@ -442,6 +554,23 @@
}
}
+ if (debug != null) {
+ debug.println("PermittedAlgs mapping: ");
+ for (String key : permittedAlgs.keySet()) {
+ debug.println(key + " : " +
+ permittedAlgs.get(key).toString());
+ }
+ }
+
+ // If there were only weak algorithms used, throw an exception.
+ if (weakAlgs) {
+ String weakAlgorithms = getWeakAlgorithms("-DIGEST-" +
+ ManifestDigester.MF_MAIN_ATTRS);
+ throw new SignatureException("Manifest Main Attribute check " +
+ "failed (DIGEST-" + ManifestDigester.MF_MAIN_ATTRS +
+ "). " + "Disabled algorithm(s) used: " + weakAlgorithms);
+ }
+
// this method returns 'true' if either:
// . manifest main attributes were not signed, or
// . manifest main attributes were signed and verified
@@ -464,6 +593,7 @@
{
boolean oneDigestVerified = false;
ManifestDigester.Entry mde = md.get(name,block.isOldStyle());
+ boolean weakAlgs = true;
if (mde == null) {
throw new SecurityException(
@@ -471,7 +601,6 @@
}
if (sfAttr != null) {
-
//sun.security.util.HexDumpEncoder hex = new sun.security.util.HexDumpEncoder();
//hex.encodeBuffer(data, System.out);
@@ -483,6 +612,15 @@
// 7 is length of "-Digest"
String algorithm = key.substring(0, key.length()-7);
+ // Check if this algorithm is permitted, skip if false.
+ if (!permittedCheck(key, algorithm)) {
+ continue;
+ }
+
+ // A non-weak algorithm was used, any weak algorithms found do
+ // not need to be reported.
+ weakAlgs = false;
+
MessageDigest digest = getDigest(algorithm);
if (digest != null) {
@@ -532,6 +670,23 @@
}
}
}
+
+ if (debug != null) {
+ debug.println("PermittedAlgs mapping: ");
+ for (String key : permittedAlgs.keySet()) {
+ debug.println(key + " : " +
+ permittedAlgs.get(key).toString());
+ }
+ }
+
+ // If there were only weak algorithms used, throw an exception.
+ if (weakAlgs) {
+ String weakAlgorithms = getWeakAlgorithms("DIGEST");
+ throw new SignatureException("Manifest Main Attribute check " +
+ "failed (DIGEST). " + "Disabled algorithm(s) used: " +
+ weakAlgorithms);
+ }
+
return oneDigestVerified;
}
--- a/jdk/src/java.base/share/classes/sun/security/validator/PKIXValidator.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/validator/PKIXValidator.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
import javax.security.auth.x500.X500Principal;
import sun.security.action.GetBooleanAction;
import sun.security.provider.certpath.AlgorithmChecker;
-import sun.security.provider.certpath.PKIXTimestampParameters;
+import sun.security.provider.certpath.PKIXExtendedParameters;
/**
* Validator implementation built on the PKIX CertPath API. This
@@ -199,9 +199,9 @@
PKIXBuilderParameters pkixParameters = null;
if (parameter instanceof Timestamp && plugin) {
try {
- pkixParameters = new PKIXTimestampParameters(
+ pkixParameters = new PKIXExtendedParameters(
(PKIXBuilderParameters) parameterTemplate.clone(),
- (Timestamp) parameter);
+ (Timestamp) parameter, variant);
} catch (InvalidAlgorithmParameterException e) {
// ignore exception
}
@@ -211,7 +211,8 @@
// add new algorithm constraints checker
if (constraints != null) {
- pkixParameters.addCertPathChecker(new AlgorithmChecker(constraints));
+ pkixParameters.addCertPathChecker(
+ new AlgorithmChecker(constraints, null, variant));
}
// attach it to the PKIXBuilderParameters.
--- a/jdk/src/java.base/share/classes/sun/security/validator/SimpleValidator.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/classes/sun/security/validator/SimpleValidator.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -155,12 +155,14 @@
// create default algorithm constraints checker
TrustAnchor anchor = new TrustAnchor(anchorCert, null);
- AlgorithmChecker defaultAlgChecker = new AlgorithmChecker(anchor);
+ AlgorithmChecker defaultAlgChecker =
+ new AlgorithmChecker(anchor, variant);
// create application level algorithm constraints checker
AlgorithmChecker appAlgChecker = null;
if (constraints != null) {
- appAlgChecker = new AlgorithmChecker(anchor, constraints);
+ appAlgChecker = new AlgorithmChecker(anchor, constraints, null,
+ variant);
}
// verify top down, starting at the certificate issued by
--- a/jdk/src/java.base/share/conf/security/java.security Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/conf/security/java.security Wed Jul 05 22:52:22 2017 +0200
@@ -116,6 +116,13 @@
# Example:
# jdk.security.provider.preferred=AES/GCM/NoPadding:SunJCE, \
# MessageDigest.SHA-256:SUN, Group.HmacSHA2:SunJCE
+#
+#ifdef solaris-sparc
+# Optional Solaris-SPARC configuration for non-FIPS 140 configurations.
+# jdk.security.provider.preferred=AES:SunJCE, SHA1:SUN, Group.SHA2:SUN, \
+# HmacSHA1:SunJCE, Group.HmacSHA2:SunJCE
+#
+#endif
#jdk.security.provider.preferred=
@@ -240,6 +247,7 @@
#
# The default value is an empty string, which is equivalent to
# securerandom.drbg.config=Hash_DRBG,SHA-256,128,none
+#
securerandom.drbg.config=
#
@@ -262,23 +270,27 @@
# The default is to have a single system-wide policy file,
# and a policy file in the user's home directory.
+#
policy.url.1=file:${java.home}/conf/security/java.policy
policy.url.2=file:${user.home}/.java.policy
# whether or not we expand properties in the policy file
# if this is set to false, properties (${...}) will not be expanded in policy
# files.
+#
policy.expandProperties=true
# whether or not we allow an extra policy to be passed on the command line
# with -Djava.security.policy=somefile. Comment out this line to disable
# this feature.
+#
policy.allowSystemProperty=true
# whether or not we look into the IdentityScope for trusted Identities
# when encountering a 1.1 signed JAR file. If the identity is found
# and is trusted, we grant it AllPermission. Note: the default policy
# provider (sun.security.provider.PolicyFile) does not support this property.
+#
policy.ignoreIdentityScope=false
#
@@ -360,7 +372,6 @@
# For this reason the default caching policy is to maintain these
# results for 10 seconds.
#
-#
networkaddress.cache.negative.ttl=10
#
@@ -460,8 +471,10 @@
# Example,
# krb5.kdc.bad.policy = tryLast
# krb5.kdc.bad.policy = tryLess:2,2000
+#
krb5.kdc.bad.policy = tryLast
+#
# Algorithm restrictions for certification path (CertPath) processing
#
# In some environments, certain algorithms or key lengths may be undesirable
@@ -481,7 +494,8 @@
# (see below)
#
# Constraint:
-# KeySizeConstraint | CAConstraint | DenyAfterConstraint
+# KeySizeConstraint | CAConstraint | DenyAfterConstraint |
+# UsageConstraint
#
# KeySizeConstraint:
# keySize Operator KeyLength
@@ -498,6 +512,9 @@
# DenyAfterConstraint:
# denyAfter YYYY-MM-DD
#
+# UsageConstraint:
+# usage [TLSServer] [TLSClient] [SignedJAR]
+#
# The "AlgorithmName" is the standard algorithm name of the disabled
# algorithm. See "Java Cryptography Architecture Standard Algorithm Name
# Documentation" for information about Standard Algorithm Names. Matching
@@ -547,6 +564,19 @@
# Example: To deny usage of RSA 2048 bit certificates after Feb 3 2020,
# use the following: "RSA keySize == 2048 & denyAfter 2020-02-03"
#
+# UsageConstraint:
+# usage [TLSServer] [TLSClient] [SignedJAR]
+# This constraint prohibits the specified algorithm for
+# a specified usage. This should be used when disabling an algorithm
+# for all usages is not practical. 'TLSServer' restricts the algorithm
+# in TLS server certificate chains when server authentication is
+# performed. 'TLSClient' restricts the algorithm in TLS client
+# certificate chains when client authentication is performed.
+# 'SignedJAR' constrains use of certificates in signed jar files.
+# The usage type follows the keyword and more than one usage type can
+# be specified with a whitespace delimiter.
+# Example: "SHA1 usage TLSServer TLSClient"
+#
# When an algorithm must satisfy more than one constraint, it must be
# delimited by an ampersand '&'. For example, to restrict certificates in a
# chain that terminate at a distribution provided trust anchor and contain
@@ -572,35 +602,6 @@
RSA keySize < 1024, DSA keySize < 1024, EC keySize < 224
#
-# RMI Registry Serial Filter
-#
-# The filter pattern uses the same format as jdk.serialFilter.
-# This filter can override the builtin filter if additional types need to be
-# allowed or rejected from the RMI Registry.
-#
-# Note: This property is currently used by the JDK Reference implementation.
-# It is not guaranteed to be examined and used by other implementations.
-#
-#sun.rmi.registry.registryFilter=pattern;pattern
-#
-# RMI Distributed Garbage Collector (DGC) Serial Filter
-#
-# The filter pattern uses the same format as jdk.serialFilter.
-# This filter can override the builtin filter if additional types need to be
-# allowed or rejected from the RMI DGC.
-#
-# Note: This property is currently used by the JDK Reference implementation.
-# It is not guaranteed to be examined and used by other implementations.
-#
-# The builtin DGC filter can approximately be represented as the filter pattern:
-#
-#sun.rmi.transport.dgcFilter=\
-# java.rmi.server.ObjID;\
-# java.rmi.server.UID;\
-# java.rmi.dgc.VMID;\
-# java.rmi.dgc.Lease;\
-# maxdepth=5;maxarray=10000
-
# Algorithm restrictions for signed JAR files
#
# In some environments, certain algorithms or key lengths may be undesirable
@@ -615,17 +616,20 @@
# " DisabledAlgorithm { , DisabledAlgorithm } "
#
# DisabledAlgorithm:
-# AlgorithmName [Constraint]
+# AlgorithmName [Constraint] { '&' Constraint }
#
# AlgorithmName:
# (see below)
#
# Constraint:
-# KeySizeConstraint
+# KeySizeConstraint | DenyAfterConstraint
#
# KeySizeConstraint:
# keySize Operator KeyLength
#
+# DenyAfterConstraint:
+# denyAfter YYYY-MM-DD
+#
# Operator:
# <= | < | == | != | >= | >
#
@@ -636,9 +640,12 @@
# implementation. It is not guaranteed to be examined and used by other
# implementations.
#
+# See "jdk.certpath.disabledAlgorithms" for syntax descriptions.
+#
jdk.jar.disabledAlgorithms=MD2, MD5, RSA keySize < 1024, \
DSA keySize < 1024
+#
# Algorithm restrictions for Secure Socket Layer/Transport Layer Security
# (SSL/TLS/DTLS) processing
#
@@ -939,3 +946,32 @@
#
#jdk.serialFilter=pattern;pattern
+#
+# RMI Registry Serial Filter
+#
+# The filter pattern uses the same format as jdk.serialFilter.
+# This filter can override the builtin filter if additional types need to be
+# allowed or rejected from the RMI Registry.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+#sun.rmi.registry.registryFilter=pattern;pattern
+#
+# RMI Distributed Garbage Collector (DGC) Serial Filter
+#
+# The filter pattern uses the same format as jdk.serialFilter.
+# This filter can override the builtin filter if additional types need to be
+# allowed or rejected from the RMI DGC.
+#
+# Note: This property is currently used by the JDK Reference implementation.
+# It is not guaranteed to be examined and used by other implementations.
+#
+# The builtin DGC filter can approximately be represented as the filter pattern:
+#
+#sun.rmi.transport.dgcFilter=\
+# java.rmi.server.ObjID;\
+# java.rmi.server.UID;\
+# java.rmi.dgc.VMID;\
+# java.rmi.dgc.Lease;\
+# maxdepth=5;maxarray=10000
--- a/jdk/src/java.base/share/lib/security/default.policy Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/lib/security/default.policy Wed Jul 05 22:52:22 2017 +0200
@@ -102,6 +102,8 @@
};
grant codeBase "jrt:/java.xml.ws" {
+ permission java.net.NetPermission
+ "getProxySelector";
permission java.lang.RuntimePermission
"accessClassInPackage.com.sun.org.apache.xml.internal.resolver";
permission java.lang.RuntimePermission
@@ -213,3 +215,7 @@
permission java.lang.RuntimePermission "accessClassInPackage.com.sun.java.swing.plaf.*";
permission java.lang.RuntimePermission "accessClassInPackage.com.apple.*";
};
+
+grant codeBase "jrt:/jdk.vm.compiler" {
+ permission java.security.AllPermission;
+};
--- a/jdk/src/java.base/share/native/launcher/main.c Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/native/launcher/main.c Wed Jul 05 22:52:22 2017 +0200
@@ -130,10 +130,10 @@
// Add first arg, which is the app name
JLI_List_add(args, JLI_StringDup(argv[0]));
- // Append JAVA_OPTIONS
- if (JLI_AddArgsFromEnvVar(args, JAVA_OPTIONS)) {
+ // Append JDK_JAVA_OPTIONS
+ if (JLI_AddArgsFromEnvVar(args, JDK_JAVA_OPTIONS)) {
// JLI_SetTraceLauncher is not called yet
- // Show _JAVA_OPTIONS content along with JAVA_OPTIONS to aid diagnosis
+ // Show _JAVA_OPTIONS content along with JDK_JAVA_OPTIONS to aid diagnosis
if (getenv(JLDEBUG_ENV_ENTRY)) {
char *tmp = getenv("_JAVA_OPTIONS");
if (NULL != tmp) {
--- a/jdk/src/java.base/share/native/libjli/args.c Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/native/libjli/args.c Wed Jul 05 22:52:22 2017 +0200
@@ -34,7 +34,7 @@
#define NO_JNI
#endif
#define JLI_ReportMessage(...) printf(__VA_ARGS__)
- #define JAVA_OPTIONS "JAVA_OPTIONS"
+ #define JDK_JAVA_OPTIONS "JDK_JAVA_OPTIONS"
int IsWhiteSpaceOption(const char* name) { return 1; }
#else
#include "java.h"
@@ -429,10 +429,6 @@
}
jboolean JLI_AddArgsFromEnvVar(JLI_List args, const char *var_name) {
-
-#ifndef ENABLE_JAVA_OPTIONS
- return JNI_FALSE;
-#else
char *env = getenv(var_name);
char *p, *arg;
char quote;
@@ -519,7 +515,6 @@
}
return JNI_TRUE;
-#endif
}
#ifdef DEBUG_ARGFILE
--- a/jdk/src/java.base/share/native/libjli/java.h Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/share/native/libjli/java.h Wed Jul 05 22:52:22 2017 +0200
@@ -71,7 +71,7 @@
#define SPLASH_FILE_ENV_ENTRY "_JAVA_SPLASH_FILE"
#define SPLASH_JAR_ENV_ENTRY "_JAVA_SPLASH_JAR"
-#define JAVA_OPTIONS "JAVA_OPTIONS"
+#define JDK_JAVA_OPTIONS "JDK_JAVA_OPTIONS"
/*
* Pointers to the needed JNI invocation API, initialized by LoadJavaVM.
--- a/jdk/src/java.base/windows/native/libjli/cmdtoargs.c Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.base/windows/native/libjli/cmdtoargs.c Wed Jul 05 22:52:22 2017 +0200
@@ -205,9 +205,9 @@
size_t i, cnt;
JLI_List envArgs = JLI_List_new(1);
- if (JLI_AddArgsFromEnvVar(envArgs, JAVA_OPTIONS)) {
+ if (JLI_AddArgsFromEnvVar(envArgs, JDK_JAVA_OPTIONS)) {
// JLI_SetTraceLauncher is not called yet
- // Show _JAVA_OPTIONS content along with JAVA_OPTIONS to aid diagnosis
+ // Show _JAVA_OPTIONS content along with JDK_JAVA_OPTIONS to aid diagnosis
if (getenv(JLDEBUG_ENV_ENTRY)) {
char *tmp = getenv("_JAVA_OPTIONS");
if (NULL != tmp) {
--- a/jdk/src/java.datatransfer/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.datatransfer/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines an API for transferring data between and within applications.
+ *
+ * @since 9
*/
module java.datatransfer {
exports java.awt.datatransfer;
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxPopup.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxPopup.java Wed Jul 05 22:52:22 2017 +0200
@@ -154,9 +154,15 @@
protected JList<Object> createList() {
return new JList<Object>(comboBox.getModel()) {
@Override
+ @SuppressWarnings("deprecation")
public void processMouseEvent(MouseEvent e) {
if (e.isMetaDown()) {
- e = new MouseEvent((Component)e.getSource(), e.getID(), e.getWhen(), e.getModifiers() ^ InputEvent.META_MASK, e.getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), MouseEvent.NOBUTTON);
+ e = new MouseEvent((Component) e.getSource(), e.getID(),
+ e.getWhen(),
+ e.getModifiers() ^ InputEvent.META_MASK,
+ e.getX(), e.getY(), e.getXOnScreen(),
+ e.getYOnScreen(), e.getClickCount(),
+ e.isPopupTrigger(), MouseEvent.NOBUTTON);
}
super.processMouseEvent(e);
}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameDockIconUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameDockIconUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -137,6 +137,7 @@
}
@Override
+ @SuppressWarnings("deprecation")
public void mouseEntered(final MouseEvent e) {
if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0) return;
String title = fFrame.getTitle();
@@ -146,6 +147,7 @@
}
@Override
+ @SuppressWarnings("deprecation")
public void mouseExited(final MouseEvent e) {
if (fDockLabel != null && (e.getModifiers() & InputEvent.BUTTON1_MASK) == 0) fDockLabel.hide();
}
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaInternalFrameUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -555,6 +555,7 @@
}
@Override
+ @SuppressWarnings("deprecation")
public void mouseDragged(final MouseEvent e) {
// do not forward drags
// if (didForwardEvent(e)) return;
@@ -621,7 +622,7 @@
return didForwardEvent;
}
-
+ @SuppressWarnings("deprecation")
boolean didForwardEventInternal(final MouseEvent e) {
if (fDraggingFrame) return false;
@@ -927,11 +928,15 @@
return (w - x) + (h - y) < 12;
}
+ @SuppressWarnings("deprecation")
void forwardEventToFrame(final MouseEvent e) {
final Point pt = new Point();
final Component c = getComponentToForwardTo(e, pt);
if (c == null) return;
- c.dispatchEvent(new MouseEvent(c, e.getID(), e.getWhen(), e.getModifiers(), pt.x, pt.y, e.getClickCount(), e.isPopupTrigger(), e.getButton()));
+ c.dispatchEvent(
+ new MouseEvent(c, e.getID(), e.getWhen(), e.getModifiers(),
+ pt.x, pt.y, e.getClickCount(),
+ e.isPopupTrigger(), e.getButton()));
}
Component getComponentToForwardTo(final MouseEvent e, final Point dst) {
@@ -993,6 +998,7 @@
public void mouseMoved(final MouseEvent e) { }
@Override
+ @SuppressWarnings("deprecation")
public void mouseWheelMoved(final MouseWheelEvent e) {
final Point pt = new Point();
final Component c = getComponentToForwardTo(e, pt);
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuPainter.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuPainter.java Wed Jul 05 22:52:22 2017 +0200
@@ -74,7 +74,10 @@
kUCapsLockGlyph = 0x21EA;
static final int ALT_GRAPH_MASK = 1 << 5; // New to Java2
- static final int sUnsupportedModifiersMask = ~(InputEvent.CTRL_MASK | InputEvent.ALT_MASK | InputEvent.SHIFT_MASK | InputEvent.META_MASK | ALT_GRAPH_MASK);
+ @SuppressWarnings("deprecation")
+ static final int sUnsupportedModifiersMask =
+ ~(InputEvent.CTRL_MASK | InputEvent.ALT_MASK | InputEvent.SHIFT_MASK
+ | InputEvent.META_MASK | ALT_GRAPH_MASK);
interface Client {
public void paintBackground(Graphics g, JComponent c, int menuWidth, int menuHeight);
@@ -86,6 +89,7 @@
}
// Return a string with the proper modifier glyphs
+ @SuppressWarnings("deprecation")
private static String getKeyModifiersUnicode(final int modifiers, final boolean isLeftToRight) {
final StringBuilder buf = new StringBuilder(2);
// Order (from StandardMenuDef.c): control, option(alt), shift, cmd
--- a/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneCopyFromBasicUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -515,6 +515,7 @@
/**
* Adds the specified mnemonic at the specified index.
*/
+ @SuppressWarnings("deprecation")
private void addMnemonic(final int index, final int mnemonic) {
if (mnemonicToIndexMap == null) {
initMnemonics();
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -1224,6 +1224,7 @@
* Changes the target of the AWTEvent from awt component to appropriate
* swing delegate.
*/
+ @SuppressWarnings("deprecation")
private AWTEvent createDelegateEvent(final AWTEvent e) {
// TODO modifiers should be changed to getModifiers()|getModifiersEx()?
AWTEvent delegateEvent = null;
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWListPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/LWListPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -302,6 +302,7 @@
}
@Override
+ @SuppressWarnings("deprecation")
protected void processMouseEvent(final MouseEvent e) {
super.processMouseEvent(e);
if (e.getID() == MouseEvent.MOUSE_CLICKED && e.getClickCount() == 2) {
@@ -314,6 +315,7 @@
}
@Override
+ @SuppressWarnings("deprecation")
protected void processKeyEvent(final KeyEvent e) {
super.processKeyEvent(e);
if (e.getID() == KeyEvent.KEY_PRESSED && e.getKeyCode() == KeyEvent.VK_ENTER) {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -93,6 +93,7 @@
InputEvent triggerEvent = trigger.getTriggerEvent();
Point dragOrigin = new Point(trigger.getDragOrigin());
+ @SuppressWarnings("deprecation")
int extModifiers = (triggerEvent.getModifiers() | triggerEvent.getModifiersEx());
long timestamp = triggerEvent.getWhen();
int clickCount = ((triggerEvent instanceof MouseEvent) ? (((MouseEvent) triggerEvent).getClickCount()) : 1);
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenuItem.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CMenuItem.java Wed Jul 05 22:52:22 2017 +0200
@@ -63,7 +63,7 @@
CMenuComponent parent = (CMenuComponent)LWToolkit.targetToPeer(getTarget().getParent());
return parent.executeGet(ptr->nativeCreate(ptr, isSeparator()));
}
-
+ @SuppressWarnings("deprecation")
public void setLabel(String label, char keyChar, int keyCode, int modifiers) {
int keyMask = modifiers;
if (keyCode == KeyEvent.VK_UNDEFINED) {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPopupMenu.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPopupMenu.java Wed Jul 05 22:52:22 2017 +0200
@@ -46,6 +46,7 @@
private native long nativeShowPopupMenu(long modelPtr, int x, int y);
@Override
+ @SuppressWarnings("deprecation")
public void show(Event e) {
Component origin = (Component)e.target;
if (origin != null) {
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -68,6 +68,7 @@
public void setResizable(boolean resizable) {}
public void setEnabled(boolean enable) {}
public void setBounds(int x, int y, int width, int height) {}
+ @SuppressWarnings("deprecation")
public boolean handleEvent(Event e) { return false; }
public void setForeground(Color c) {}
public void setBackground(Color c) {}
--- a/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java Wed Jul 05 22:52:22 2017 +0200
@@ -532,6 +532,7 @@
* @since 1.1
*/
@Override
+ @SuppressWarnings("deprecation")
public int getMenuShortcutKeyMask() {
return Event.META_MASK;
}
@@ -768,6 +769,7 @@
* stroke.
*/
@Override
+ @SuppressWarnings("deprecation")
public int getFocusAcceleratorKeyMask() {
return InputEvent.CTRL_MASK | InputEvent.ALT_MASK;
}
@@ -777,6 +779,7 @@
* printable character.
*/
@Override
+ @SuppressWarnings("deprecation")
public boolean isPrintableCharacterModifiersMask(int mods) {
return ((mods & (InputEvent.META_MASK | InputEvent.CTRL_MASK)) == 0);
}
--- a/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/macosx/native/libawt_lwawt/awt/JavaComponentAccessibility.m Wed Jul 05 22:52:22 2017 +0200
@@ -136,7 +136,7 @@
fJavaRole = [javaRole retain];
fAccessible = (*env)->NewWeakGlobalRef(env, accessible);
-
+ (*env)->ExceptionClear(env); // in case of OOME
jobject jcomponent = [(AWTView *)fView awtComponent:env];
fComponent = (*env)->NewWeakGlobalRef(env, jcomponent);
(*env)->DeleteLocalRef(env, jcomponent);
--- a/jdk/src/java.desktop/share/classes/com/sun/awt/AWTUtilities.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/awt/AWTUtilities.java Wed Jul 05 22:52:22 2017 +0200
@@ -456,8 +456,7 @@
"The component argument should not be null.");
}
- AWTAccessor.getComponentAccessor().setMixingCutoutShape(component,
- shape);
+ component.setMixingCutoutShape(shape);
}
}
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifDesktopIconUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifDesktopIconUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -236,7 +236,7 @@
}
});
}
-
+ @SuppressWarnings("deprecation")
void forwardEventToParent(MouseEvent e) {
getParent().dispatchEvent(new MouseEvent(
getParent(), e.getID(), e.getWhen(), e.getModifiers(),
@@ -329,7 +329,7 @@
}
});
}
-
+ @SuppressWarnings("deprecation")
void forwardEventToParent(MouseEvent e) {
getParent().dispatchEvent(new MouseEvent(
getParent(), e.getID(), e.getWhen(), e.getModifiers(),
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifGraphicsUtils.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifGraphicsUtils.java Wed Jul 05 22:52:22 2017 +0200
@@ -139,10 +139,11 @@
}
/**
- * This method is not being used to paint menu item since
+ * @deprecated This method is not being used to paint menu item since
* 6.0 This code left for compatibility only. Do not use or
* override it, this will not cause any visible effect.
*/
+ @Deprecated(since = "9")
public static void paintMenuItem(Graphics g, JComponent c,
Icon checkIcon, Icon arrowIcon,
Color background, Color foreground,
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifInternalFrameTitlePane.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifInternalFrameTitlePane.java Wed Jul 05 22:52:22 2017 +0200
@@ -361,7 +361,7 @@
}
});
}
-
+ @SuppressWarnings("deprecation")
void forwardEventToParent(MouseEvent e) {
getParent().dispatchEvent(new MouseEvent(
getParent(), e.getID(), e.getWhen(), e.getModifiers(),
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java Wed Jul 05 22:52:22 2017 +0200
@@ -523,7 +523,8 @@
Object optionPaneMessageAreaBorder = new BorderUIResource.EmptyBorderUIResource(10,10,12,10);
-
+ @SuppressWarnings("deprecation")
+ final int metaMask = KeyEvent.META_MASK;
Object[] defaults = {
"Desktop.background", table.get("desktop"),
@@ -635,8 +636,7 @@
"Menu.submenuPopupOffsetX", -2,
"Menu.submenuPopupOffsetY", 3,
"Menu.shortcutKeys", new int[]{
- SwingUtilities2.getSystemMnemonicKeyMask(),
- KeyEvent.META_MASK
+ SwingUtilities2.getSystemMnemonicKeyMask(), metaMask
},
"Menu.cancelMode", "hideMenuTree",
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifPopupMenuUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifPopupMenuUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -107,6 +107,7 @@
};
}
+ @SuppressWarnings("deprecation")
public boolean isPopupTrigger(MouseEvent e) {
return ((e.getID()==MouseEvent.MOUSE_PRESSED)
&& ((e.getModifiers() & MouseEvent.BUTTON3_MASK)!=0));
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifTextUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifTextUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -155,6 +155,7 @@
/**
* Default bindings all keymaps implementing the Motif feel.
*/
+ @SuppressWarnings("deprecation")
static final JTextComponent.KeyBinding[] defaultBindings = {
new JTextComponent.KeyBinding(KeyStroke.getKeyStroke(KeyEvent.VK_INSERT,
InputEvent.CTRL_MASK),
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsRootPaneUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -165,8 +165,11 @@
}
public boolean postProcessKeyEvent(KeyEvent ev) {
- if(ev.isConsumed()) {
- // do not manage consumed event
+ if(ev.isConsumed() && ev.getKeyCode() != KeyEvent.VK_ALT) {
+ // mnemonic combination, it's consumed, but we need
+ // set altKeyPressed to false, otherwise after selection
+ // component by mnemonic combination a menu will be open
+ altKeyPressed = false;
return false;
}
if (ev.getKeyCode() == KeyEvent.VK_ALT) {
--- a/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTabbedPaneUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/com/sun/java/swing/plaf/windows/WindowsTabbedPaneUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -63,6 +63,7 @@
private boolean contentOpaque = true;
+ @SuppressWarnings("deprecation")
protected void installDefaults() {
super.installDefaults();
contentOpaque = UIManager.getBoolean("TabbedPane.contentOpaque");
--- a/jdk/src/java.desktop/share/classes/java/awt/AWTEvent.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/AWTEvent.java Wed Jul 05 22:52:22 2017 +0200
@@ -292,8 +292,12 @@
/**
* Constructs an AWTEvent object from the parameters of a 1.0-style event.
+ *
* @param event the old-style event
+ * @deprecated It is recommended that {@link #AWTEvent(Object, int)} be used
+ * instead
*/
+ @Deprecated(since = "9")
public AWTEvent(Event event) {
this(event.target, event.id);
}
@@ -436,6 +440,7 @@
* event class in java.awt.event because we don't want to make
* it public and it needs to be called from java.awt.
*/
+ @SuppressWarnings("deprecation")
Event convertToOld() {
Object src = getSource();
int newid = id;
--- a/jdk/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/AWTKeyStroke.java Wed Jul 05 22:52:22 2017 +0200
@@ -350,6 +350,7 @@
* @throws NullPointerException if {@code anEvent} is null
* @return the {@code AWTKeyStroke} that precipitated the event
*/
+ @SuppressWarnings("deprecation")
public static AWTKeyStroke getAWTKeyStrokeForEvent(KeyEvent anEvent) {
int id = anEvent.getID();
switch(id) {
@@ -397,6 +398,7 @@
* @throws IllegalArgumentException if {@code s} is {@code null},
* or is formatted incorrectly
*/
+ @SuppressWarnings("deprecation")
public static AWTKeyStroke getAWTKeyStroke(String s) {
if (s == null) {
throw new IllegalArgumentException("String cannot be null");
@@ -708,6 +710,7 @@
}
}
+ @SuppressWarnings("deprecation")
private static int mapOldModifiers(int modifiers) {
if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
modifiers |= InputEvent.SHIFT_DOWN_MASK;
@@ -737,6 +740,7 @@
return modifiers;
}
+ @SuppressWarnings("deprecation")
private static int mapNewModifiers(int modifiers) {
if ((modifiers & InputEvent.SHIFT_DOWN_MASK) != 0) {
modifiers |= InputEvent.SHIFT_MASK;
--- a/jdk/src/java.desktop/share/classes/java/awt/Component.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/Component.java Wed Jul 05 22:52:22 2017 +0200
@@ -5036,6 +5036,7 @@
*
* Returns whether or not event was dispatched to an ancestor
*/
+ @SuppressWarnings("deprecation")
boolean dispatchMouseWheelToAncestor(MouseWheelEvent e) {
int newX, newY;
newX = e.getX() + getX(); // Coordinates take into account at least
@@ -10379,7 +10380,11 @@
}
/**
- * Sets a 'mixing-cutout' shape for the given component.
+ * Sets a 'mixing-cutout' shape for this lightweight component.
+ *
+ * This method is used exclusively for the purposes of the
+ * Heavyweight/Lightweight Components Mixing feature and will
+ * have no effect if applied to a heavyweight component.
*
* By default a lightweight component is treated as an opaque rectangle for
* the purposes of the Heavyweight/Lightweight Components Mixing feature.
@@ -10392,7 +10397,7 @@
* <li>{@code null} - reverts the default cutout shape (the rectangle equal
* to the component's {@code getBounds()})
* <li><i>empty-shape</i> - does not cut out anything from heavyweight
- * components. This makes the given lightweight component effectively
+ * components. This makes this lightweight component effectively
* transparent. Note that descendants of the lightweight component still
* affect the shapes of heavyweight components. An example of an
* <i>empty-shape</i> is {@code new Rectangle()}.
@@ -10406,16 +10411,11 @@
* for the given glass pane component. If a developer needs some other
* 'mixing-cutout' shape for the glass pane (which is rare), this must be
* changed manually after installing the glass pane to the root pane.
- * <p>
- * Note that the 'mixing-cutout' shape neither affects painting, nor the
- * mouse events handling for the given component. It is used exclusively
- * for the purposes of the Heavyweight/Lightweight Components Mixing
- * feature.
*
* @param shape the new 'mixing-cutout' shape
* @since 9
*/
- void setMixingCutoutShape(Shape shape) {
+ public void setMixingCutoutShape(Shape shape) {
Region region = shape == null ? null : Region.getInstance(shape, null);
synchronized (getTreeLock()) {
--- a/jdk/src/java.desktop/share/classes/java/awt/Container.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/Container.java Wed Jul 05 22:52:22 2017 +0200
@@ -4728,6 +4728,7 @@
* Listen for drag events posted in other hw components so we can
* track enter/exit regardless of where a drag originated
*/
+ @SuppressWarnings("deprecation")
public void eventDispatched(AWTEvent e) {
boolean isForeignDrag = (e instanceof MouseEvent) &&
!(e instanceof SunDropTargetEvent) &&
@@ -4826,6 +4827,7 @@
* If the target has been removed, we don't bother to send the
* message.
*/
+ @SuppressWarnings("deprecation")
void retargetMouseEvent(Component target, int id, MouseEvent e) {
if (target == null) {
return; // mouse is over another hw component or target is disabled
--- a/jdk/src/java.desktop/share/classes/java/awt/Event.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/Event.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 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,8 +24,7 @@
*/
package java.awt;
-import java.awt.event.*;
-import java.io.*;
+import java.awt.event.KeyEvent;
/**
* <b>NOTE:</b> The {@code Event} class is obsolete and is
@@ -56,9 +55,12 @@
* {@code Event} class ({@code PGUP},
* {@code PGDN}, {@code F1}, {@code F2}, etc).
*
+ * @deprecated It is recommended that {@code AWTEvent} and its subclasses be
+ * used instead
* @author Sami Shaio
* @since 1.0
*/
+@Deprecated(since = "9")
public class Event implements java.io.Serializable {
private transient long data;
--- a/jdk/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java Wed Jul 05 22:52:22 2017 +0200
@@ -415,6 +415,7 @@
* Initializes a KeyboardFocusManager.
*/
public KeyboardFocusManager() {
+ @SuppressWarnings("deprecation")
AWTKeyStroke[][] defaultFocusTraversalKeyStrokes = {
{
AWTKeyStroke.getAWTKeyStroke(KeyEvent.VK_TAB, 0, false),
--- a/jdk/src/java.desktop/share/classes/java/awt/MenuBar.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/MenuBar.java Wed Jul 05 22:52:22 2017 +0200
@@ -375,6 +375,7 @@
* keydown). Returns true if there is an associated
* keyboard event.
*/
+ @SuppressWarnings("deprecation")
boolean handleShortcut(KeyEvent e) {
// Is it a key event?
int id = e.getID();
--- a/jdk/src/java.desktop/share/classes/java/awt/MenuComponent.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/MenuComponent.java Wed Jul 05 22:52:22 2017 +0200
@@ -379,6 +379,7 @@
}
} else { // backward compatibility
+ @SuppressWarnings("deprecation")
Event olde = e.convertToOld();
if (olde != null) {
postEvent(olde);
--- a/jdk/src/java.desktop/share/classes/java/awt/MenuItem.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/MenuItem.java Wed Jul 05 22:52:22 2017 +0200
@@ -435,6 +435,7 @@
* keydown) and the item is enabled.
* Returns true if there is an associated shortcut.
*/
+ @SuppressWarnings("deprecation")
boolean handleShortcut(KeyEvent e) {
MenuShortcut s = new MenuShortcut(e.getKeyCode(),
(e.getModifiers() & InputEvent.SHIFT_MASK) > 0);
--- a/jdk/src/java.desktop/share/classes/java/awt/MenuShortcut.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/MenuShortcut.java Wed Jul 05 22:52:22 2017 +0200
@@ -180,6 +180,7 @@
* @return a string representation of this MenuShortcut.
* @since 1.1
*/
+ @SuppressWarnings("deprecation")
public String toString() {
int modifiers = 0;
if (!GraphicsEnvironment.isHeadless()) {
--- a/jdk/src/java.desktop/share/classes/java/awt/PopupMenu.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/PopupMenu.java Wed Jul 05 22:52:22 2017 +0200
@@ -154,6 +154,7 @@
* parent's hierarchy
* @exception RuntimeException if the parent is not showing on screen
*/
+ @SuppressWarnings("deprecation")
public void show(Component origin, int x, int y) {
// Use localParent for thread safety.
MenuContainer localParent = parent;
--- a/jdk/src/java.desktop/share/classes/java/awt/Robot.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/Robot.java Wed Jul 05 22:52:22 2017 +0200
@@ -137,6 +137,7 @@
initLegalButtonMask();
}
+ @SuppressWarnings("deprecation")
private static synchronized void initLegalButtonMask() {
if (LEGAL_BUTTON_MASK != 0) return;
--- a/jdk/src/java.desktop/share/classes/java/awt/Toolkit.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/Toolkit.java Wed Jul 05 22:52:22 2017 +0200
@@ -1067,6 +1067,7 @@
* @see java.awt.MenuShortcut
* @since 1.1
*/
+ @SuppressWarnings("deprecation")
public int getMenuShortcutKeyMask() throws HeadlessException {
GraphicsEnvironment.checkHeadless();
--- a/jdk/src/java.desktop/share/classes/java/awt/dnd/DragSourceDragEvent.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/dnd/DragSourceDragEvent.java Wed Jul 05 22:52:22 2017 +0200
@@ -281,6 +281,7 @@
* The mouse modifiers have higher priority than overlaying key
* modifiers.
*/
+ @SuppressWarnings("deprecation")
private void setNewModifiers() {
if ((gestureModifiers & InputEvent.BUTTON1_MASK) != 0) {
gestureModifiers |= InputEvent.BUTTON1_DOWN_MASK;
@@ -305,6 +306,7 @@
/**
* Sets old modifiers by the new ones.
*/
+ @SuppressWarnings("deprecation")
private void setOldModifiers() {
if ((gestureModifiers & InputEvent.BUTTON1_DOWN_MASK) != 0) {
gestureModifiers |= InputEvent.BUTTON1_MASK;
--- a/jdk/src/java.desktop/share/classes/java/awt/event/ActionEvent.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/event/ActionEvent.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,7 +26,6 @@
package java.awt.event;
import java.awt.AWTEvent;
-import java.awt.Event;
import java.lang.annotation.Native;
/**
@@ -63,25 +62,25 @@
* The shift modifier. An indicator that the shift key was held
* down during the event.
*/
- public static final int SHIFT_MASK = Event.SHIFT_MASK;
+ public static final int SHIFT_MASK = 1 << 0;
/**
* The control modifier. An indicator that the control key was held
* down during the event.
*/
- public static final int CTRL_MASK = Event.CTRL_MASK;
+ public static final int CTRL_MASK = 1 << 1;
/**
* The meta modifier. An indicator that the meta key was held
* down during the event.
*/
- public static final int META_MASK = Event.META_MASK;
+ public static final int META_MASK = 1 << 2;
/**
* The alt modifier. An indicator that the alt key was held
* down during the event.
*/
- public static final int ALT_MASK = Event.ALT_MASK;
+ public static final int ALT_MASK = 1 << 3;
/**
@@ -274,6 +273,7 @@
*
* @return a string identifying the event and its associated command
*/
+ @SuppressWarnings("deprecation")
public String paramString() {
String typeStr;
switch(id) {
--- a/jdk/src/java.desktop/share/classes/java/awt/event/InputEvent.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/event/InputEvent.java Wed Jul 05 22:52:22 2017 +0200
@@ -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
@@ -62,51 +62,76 @@
/**
* The Shift key modifier constant.
- * It is recommended that SHIFT_DOWN_MASK be used instead.
+ *
+ * @deprecated It is recommended that SHIFT_DOWN_MASK and
+ * {@link #getModifiersEx()} be used instead
*/
+ @Deprecated(since = "9")
public static final int SHIFT_MASK = Event.SHIFT_MASK;
/**
* The Control key modifier constant.
- * It is recommended that CTRL_DOWN_MASK be used instead.
+ *
+ * @deprecated It is recommended that CTRL_DOWN_MASK and
+ * {@link #getModifiersEx()} be used instead
*/
+ @Deprecated(since = "9")
public static final int CTRL_MASK = Event.CTRL_MASK;
/**
* The Meta key modifier constant.
- * It is recommended that META_DOWN_MASK be used instead.
+ *
+ * @deprecated It is recommended that META_DOWN_MASK and
+ * {@link #getModifiersEx()} be used instead
*/
+ @Deprecated(since = "9")
public static final int META_MASK = Event.META_MASK;
/**
* The Alt key modifier constant.
- * It is recommended that ALT_DOWN_MASK be used instead.
+ *
+ * @deprecated It is recommended that ALT_DOWN_MASK and
+ * {@link #getModifiersEx()} be used instead
*/
+ @Deprecated(since = "9")
public static final int ALT_MASK = Event.ALT_MASK;
/**
* The AltGraph key modifier constant.
+ *
+ * @deprecated It is recommended that ALT_GRAPH_DOWN_MASK and
+ * {@link #getModifiersEx()} be used instead
*/
+ @Deprecated(since = "9")
public static final int ALT_GRAPH_MASK = 1 << 5;
/**
* The Mouse Button1 modifier constant.
- * It is recommended that BUTTON1_DOWN_MASK be used instead.
+ *
+ * @deprecated It is recommended that BUTTON1_DOWN_MASK and
+ * {@link #getModifiersEx()} be used instead
*/
+ @Deprecated(since = "9")
public static final int BUTTON1_MASK = 1 << 4;
/**
* The Mouse Button2 modifier constant.
- * It is recommended that BUTTON2_DOWN_MASK be used instead.
- * Note that BUTTON2_MASK has the same value as ALT_MASK.
+ *
+ * @deprecated It is recommended that BUTTON2_DOWN_MASK and
+ * {@link #getModifiersEx()} be used instead. Note that
+ * BUTTON2_MASK has the same value as ALT_MASK.
*/
+ @Deprecated(since = "9")
public static final int BUTTON2_MASK = Event.ALT_MASK;
/**
* The Mouse Button3 modifier constant.
- * It is recommended that BUTTON3_DOWN_MASK be used instead.
- * Note that BUTTON3_MASK has the same value as META_MASK.
+ *
+ * @deprecated It is recommended that BUTTON3_DOWN_MASK and
+ * {@link #getModifiersEx()} be used instead. Note that
+ * BUTTON3_MASK has the same value as META_MASK.
*/
+ @Deprecated(since = "9")
public static final int BUTTON3_MASK = Event.META_MASK;
/**
@@ -159,7 +184,7 @@
/**
* An array of extended modifiers for additional buttons.
- * @see getButtonDownMasks
+ * @see #getButtonDownMasks()
* There are twenty buttons fit into 4byte space.
* one more bit is reserved for FIRST_HIGH_BIT.
* @since 1.7
@@ -382,7 +407,7 @@
* @return whether or not the Shift modifier is down on this event
*/
public boolean isShiftDown() {
- return (modifiers & SHIFT_MASK) != 0;
+ return (modifiers & SHIFT_DOWN_MASK) != 0;
}
/**
@@ -390,7 +415,7 @@
* @return whether or not the Control modifier is down on this event
*/
public boolean isControlDown() {
- return (modifiers & CTRL_MASK) != 0;
+ return (modifiers & CTRL_DOWN_MASK) != 0;
}
/**
@@ -398,7 +423,7 @@
* @return whether or not the Meta modifier is down on this event
*/
public boolean isMetaDown() {
- return (modifiers & META_MASK) != 0;
+ return (modifiers & META_DOWN_MASK) != 0;
}
/**
@@ -406,7 +431,7 @@
* @return whether or not the Alt modifier is down on this event
*/
public boolean isAltDown() {
- return (modifiers & ALT_MASK) != 0;
+ return (modifiers & ALT_DOWN_MASK) != 0;
}
/**
@@ -414,7 +439,7 @@
* @return whether or not the AltGraph modifier is down on this event
*/
public boolean isAltGraphDown() {
- return (modifiers & ALT_GRAPH_MASK) != 0;
+ return (modifiers & ALT_GRAPH_DOWN_MASK) != 0;
}
/**
@@ -428,8 +453,12 @@
/**
* Returns the modifier mask for this event.
+ *
* @return the modifier mask for this event
+ * @deprecated It is recommended that extended modifier keys and
+ * {@link #getModifiersEx()} be used instead
*/
+ @Deprecated(since = "9")
public int getModifiers() {
return modifiers & (JDK_1_3_MODIFIERS | HIGH_MODIFIERS);
}
--- a/jdk/src/java.desktop/share/classes/java/awt/event/KeyEvent.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/event/KeyEvent.java Wed Jul 05 22:52:22 2017 +0200
@@ -1169,6 +1169,7 @@
* @see #getKeyLocation()
* @since 1.4
*/
+ @SuppressWarnings("deprecation")
public KeyEvent(Component source, int id, long when, int modifiers,
int keyCode, char keyChar, int keyLocation) {
super(source, id, when, modifiers);
@@ -1561,7 +1562,10 @@
* @return string a text description of the combination of modifier
* keys that were held down during the event
* @see InputEvent#getModifiersExText(int)
+ * @deprecated It is recommended that extended modifier keys and
+ * {@link InputEvent#getModifiersExText(int)} be used instead
*/
+ @Deprecated(since = "9")
public static String getKeyModifiersText(int modifiers) {
StringBuilder buf = new StringBuilder();
if ((modifiers & InputEvent.META_MASK) != 0) {
@@ -1696,6 +1700,7 @@
*
* @return a string identifying the event and its attributes
*/
+ @SuppressWarnings("deprecation")
public String paramString() {
StringBuilder str = new StringBuilder(100);
@@ -1821,6 +1826,7 @@
* Sets new modifiers by the old ones. The key modifiers
* override overlapping mouse modifiers.
*/
+ @SuppressWarnings("deprecation")
private void setNewModifiers() {
if ((modifiers & SHIFT_MASK) != 0) {
modifiers |= SHIFT_DOWN_MASK;
@@ -1845,6 +1851,7 @@
/**
* Sets old modifiers by the new ones.
*/
+ @SuppressWarnings("deprecation")
private void setOldModifiers() {
if ((modifiers & SHIFT_DOWN_MASK) != 0) {
modifiers |= SHIFT_MASK;
@@ -1871,6 +1878,7 @@
* override overlapping mouse modifiers.
* @serial
*/
+ @SuppressWarnings("deprecation")
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject();
--- a/jdk/src/java.desktop/share/classes/java/awt/event/MouseEvent.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/event/MouseEvent.java Wed Jul 05 22:52:22 2017 +0200
@@ -733,6 +733,7 @@
* @see InputEvent#getMaskForButton(int)
* @since 1.6
*/
+ @SuppressWarnings("deprecation")
public MouseEvent(Component source, int id, long when, int modifiers,
int x, int y, int xAbs, int yAbs,
int clickCount, boolean popupTrigger, int button)
@@ -943,6 +944,7 @@
* @see InputEvent#getModifiersExText(int)
* @since 1.4
*/
+ @SuppressWarnings("deprecation")
public static String getMouseModifiersText(int modifiers) {
StringBuilder buf = new StringBuilder();
if ((modifiers & InputEvent.ALT_MASK) != 0) {
@@ -1007,6 +1009,7 @@
*
* @return a string identifying the event and its attributes
*/
+ @SuppressWarnings("deprecation")
public String paramString() {
StringBuilder str = new StringBuilder(80);
@@ -1066,6 +1069,7 @@
* Sets new modifiers by the old ones.
* Also sets button.
*/
+ @SuppressWarnings("deprecation")
private void setNewModifiers() {
if ((modifiers & BUTTON1_MASK) != 0) {
modifiers |= BUTTON1_DOWN_MASK;
@@ -1120,6 +1124,7 @@
/**
* Sets old modifiers by the new ones.
*/
+ @SuppressWarnings("deprecation")
private void setOldModifiers() {
if (id == MOUSE_PRESSED
|| id == MOUSE_RELEASED
@@ -1168,6 +1173,7 @@
* Sets new modifiers by the old ones.
* @serial
*/
+ @SuppressWarnings("deprecation")
private void readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException {
s.defaultReadObject();
--- a/jdk/src/java.desktop/share/classes/java/awt/peer/PopupMenuPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/java/awt/peer/PopupMenuPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -46,5 +46,6 @@
*
* @see PopupMenu#show(java.awt.Component, int, int)
*/
+ @SuppressWarnings("deprecation")
void show(Event e);
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/Autoscroller.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/Autoscroller.java Wed Jul 05 22:52:22 2017 +0200
@@ -82,6 +82,7 @@
/**
* Starts the timer targeting the passed in component.
*/
+ @SuppressWarnings("deprecation")
private void start(JComponent c, MouseEvent e) {
Point screenLocation = c.getLocationOnScreen();
@@ -156,6 +157,7 @@
* ActionListener method. Invoked when the Timer fires. This will scroll
* if necessary.
*/
+ @SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent x) {
JComponent component = Autoscroller.component;
--- a/jdk/src/java.desktop/share/classes/javax/swing/DefaultButtonModel.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/DefaultButtonModel.java Wed Jul 05 22:52:22 2017 +0200
@@ -239,6 +239,7 @@
/**
* {@inheritDoc}
*/
+ @SuppressWarnings("deprecation")
public void setPressed(boolean b) {
if((isPressed() == b) || !isEnabled()) {
return;
--- a/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JComboBox.java Wed Jul 05 22:52:22 2017 +0200
@@ -1235,6 +1235,7 @@
*
* @see EventListenerList
*/
+ @SuppressWarnings("deprecation")
protected void fireActionEvent() {
if (!firingActionEvent) {
// Set flag to ensure that an infinite loop is not created
--- a/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JComponent.java Wed Jul 05 22:52:22 2017 +0200
@@ -429,6 +429,7 @@
* Returns the Set of <code>KeyStroke</code>s to use if the component
* is managing focus for forward focus traversal.
*/
+ @SuppressWarnings("deprecation")
static Set<KeyStroke> getManagingFocusForwardTraversalKeys() {
synchronized(JComponent.class) {
if (managingFocusForwardTraversalKeys == null) {
@@ -445,6 +446,7 @@
* Returns the Set of <code>KeyStroke</code>s to use if the component
* is managing focus for backward focus traversal.
*/
+ @SuppressWarnings("deprecation")
static Set<KeyStroke> getManagingFocusBackwardTraversalKeys() {
synchronized(JComponent.class) {
if (managingFocusBackwardTraversalKeys == null) {
@@ -2886,6 +2888,7 @@
*
* @since 1.3
*/
+ @SuppressWarnings("deprecation")
protected boolean processKeyBinding(KeyStroke ks, KeyEvent e,
int condition, boolean pressed) {
InputMap map = getInputMap(condition, false);
--- a/jdk/src/java.desktop/share/classes/javax/swing/JFileChooser.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JFileChooser.java Wed Jul 05 22:52:22 2017 +0200
@@ -1754,6 +1754,7 @@
* the event
* @see EventListenerList
*/
+ @SuppressWarnings("deprecation")
protected void fireActionPerformed(String command) {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
--- a/jdk/src/java.desktop/share/classes/javax/swing/JLayer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JLayer.java Wed Jul 05 22:52:22 2017 +0200
@@ -286,8 +286,7 @@
super.remove(oldGlassPane);
}
if (glassPane != null) {
- AWTAccessor.getComponentAccessor().setMixingCutoutShape(glassPane,
- new Rectangle());
+ glassPane.setMixingCutoutShape(new Rectangle());
glassPane.setVisible(isGlassPaneVisible);
super.addImpl(glassPane, null, 0);
}
--- a/jdk/src/java.desktop/share/classes/javax/swing/JList.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JList.java Wed Jul 05 22:52:22 2017 +0200
@@ -1516,6 +1516,7 @@
* @see JComponent#setToolTipText
* @see JComponent#getToolTipText
*/
+ @SuppressWarnings("deprecation")
public String getToolTipText(MouseEvent event) {
if(event != null) {
Point p = event.getPoint();
--- a/jdk/src/java.desktop/share/classes/javax/swing/JMenuItem.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JMenuItem.java Wed Jul 05 22:52:22 2017 +0200
@@ -412,6 +412,7 @@
* @param path the <code>MenuElement</code> path array
* @param manager the <code>MenuSelectionManager</code>
*/
+ @SuppressWarnings("deprecation")
public void processMouseEvent(MouseEvent e,MenuElement path[],MenuSelectionManager manager) {
processMenuDragMouseEvent(
new MenuDragMouseEvent(e.getComponent(), e.getID(),
@@ -435,6 +436,7 @@
* @param path the <code>MenuElement</code> path array
* @param manager the <code>MenuSelectionManager</code>
*/
+ @SuppressWarnings("deprecation")
public void processKeyEvent(KeyEvent e,MenuElement path[],MenuSelectionManager manager) {
if (DEBUG) {
System.out.println("in JMenuItem.processKeyEvent/3 for " + getText() +
--- a/jdk/src/java.desktop/share/classes/javax/swing/JPopupMenu.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JPopupMenu.java Wed Jul 05 22:52:22 2017 +0200
@@ -1385,6 +1385,7 @@
* @param path the <code>MenuElement</code> path array
* @param manager the <code>MenuSelectionManager</code>
*/
+ @SuppressWarnings("deprecation")
public void processKeyEvent(KeyEvent e, MenuElement path[],
MenuSelectionManager manager) {
MenuKeyEvent mke = new MenuKeyEvent(e.getComponent(), e.getID(),
--- a/jdk/src/java.desktop/share/classes/javax/swing/JRootPane.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JRootPane.java Wed Jul 05 22:52:22 2017 +0200
@@ -663,8 +663,7 @@
throw new NullPointerException("glassPane cannot be set to null.");
}
- AWTAccessor.getComponentAccessor().setMixingCutoutShape(glass,
- new Rectangle());
+ glass.setMixingCutoutShape(new Rectangle());
boolean visible = false;
if (glassPane != null && glassPane.getParent() == this) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/JTable.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JTable.java Wed Jul 05 22:52:22 2017 +0200
@@ -3410,8 +3410,10 @@
// Convert the event to the renderer's coordinate system
Rectangle cellRect = getCellRect(hitRowIndex, hitColumnIndex, false);
p.translate(-cellRect.x, -cellRect.y);
+ @SuppressWarnings("deprecation")
+ final int modifiers = event.getModifiers();
MouseEvent newEvent = new MouseEvent(component, event.getID(),
- event.getWhen(), event.getModifiers(),
+ event.getWhen(), modifiers,
p.x, p.y,
event.getXOnScreen(),
event.getYOnScreen(),
--- a/jdk/src/java.desktop/share/classes/javax/swing/JTextField.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JTextField.java Wed Jul 05 22:52:22 2017 +0200
@@ -485,6 +485,7 @@
* first order.
* @see EventListenerList
*/
+ @SuppressWarnings("deprecation")
protected void fireActionPerformed() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
--- a/jdk/src/java.desktop/share/classes/javax/swing/JToggleButton.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JToggleButton.java Wed Jul 05 22:52:22 2017 +0200
@@ -372,6 +372,7 @@
/**
* Sets the pressed state of the toggle button.
*/
+ @SuppressWarnings("deprecation")
public void setPressed(boolean b) {
if ((isPressed() == b) || !isEnabled()) {
return;
--- a/jdk/src/java.desktop/share/classes/javax/swing/JTree.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/JTree.java Wed Jul 05 22:52:22 2017 +0200
@@ -1568,9 +1568,10 @@
Rectangle pathBounds = getPathBounds(path);
p.translate(-pathBounds.x, -pathBounds.y);
+ @SuppressWarnings("deprecation")
+ final int modifiers = event.getModifiers();
newEvent = new MouseEvent(rComponent, event.getID(),
- event.getWhen(),
- event.getModifiers(),
+ event.getWhen(), modifiers,
p.x, p.y,
event.getXOnScreen(),
event.getYOnScreen(),
--- a/jdk/src/java.desktop/share/classes/javax/swing/KeyboardManager.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/KeyboardManager.java Wed Jul 05 22:52:22 2017 +0200
@@ -207,6 +207,7 @@
* want a crack at the event.
* If one of them wants it, then it will "DO-THE-RIGHT-THING"
*/
+ @SuppressWarnings("deprecation")
public boolean fireKeyboardAction(KeyEvent e, boolean pressed, Container topAncestor) {
if (e.isConsumed()) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/MenuSelectionManager.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/MenuSelectionManager.java Wed Jul 05 22:52:22 2017 +0200
@@ -212,6 +212,7 @@
*
* @param event a MouseEvent object
*/
+ @SuppressWarnings("deprecation")
public void processMouseEvent(MouseEvent event) {
int screenX,screenY;
Point p;
--- a/jdk/src/java.desktop/share/classes/javax/swing/SwingUtilities.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/SwingUtilities.java Wed Jul 05 22:52:22 2017 +0200
@@ -346,6 +346,7 @@
*
* @return the new mouse event
*/
+ @SuppressWarnings("deprecation")
public static MouseEvent convertMouseEvent(Component source,
MouseEvent sourceEvent,
Component destination) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/ToolTipManager.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/ToolTipManager.java Wed Jul 05 22:52:22 2017 +0200
@@ -89,6 +89,7 @@
*/
protected boolean heavyWeightPopupEnabled = false;
+ @SuppressWarnings("deprecation")
ToolTipManager() {
enterTimer = new Timer(750, new insideTimerAction());
enterTimer.setRepeats(false);
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -1839,6 +1839,7 @@
// key. If it finds a key event that wasn't a navigation key it
// dispatches it to JComboBox.selectWithKeyChar() so that it can do
// type-ahead.
+ @SuppressWarnings("deprecation")
public void keyPressed( KeyEvent e ) {
if ( isNavigationKey(e.getKeyCode(), e.getModifiers()) ) {
lastTime = 0L;
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboPopup.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboPopup.java Wed Jul 05 22:52:22 2017 +0200
@@ -528,6 +528,7 @@
*/
protected JList<Object> createList() {
return new JList<Object>( comboBox.getModel() ) {
+ @SuppressWarnings("deprecation")
public void processMouseEvent(MouseEvent e) {
if (BasicGraphicsUtils.isMenuShortcutKeyDown(e)) {
// Fix for 4234053. Filter out the Control Key from the list.
@@ -1238,6 +1239,7 @@
protected MouseEvent convertMouseEvent( MouseEvent e ) {
Point convertedPoint = SwingUtilities.convertPoint( (Component)e.getSource(),
e.getPoint(), list );
+ @SuppressWarnings("deprecation")
MouseEvent newEvent = new MouseEvent( (Component)e.getSource(),
e.getID(),
e.getWhen(),
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicGraphicsUtils.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicGraphicsUtils.java Wed Jul 05 22:52:22 2017 +0200
@@ -382,6 +382,7 @@
return c.getComponentOrientation().isLeftToRight();
}
+ @SuppressWarnings("deprecation")
static boolean isMenuShortcutKeyDown(InputEvent event) {
return (event.getModifiers() &
Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) != 0;
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -1024,7 +1024,7 @@
return;
}
}
-
+ @SuppressWarnings("deprecation")
public void mouseDragged(MouseEvent e) {
if ( startingBounds == null ) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuItemUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -1026,6 +1026,7 @@
manager.processMouseEvent(e);
}
}
+ @SuppressWarnings("deprecation")
public void mouseEntered(MouseEvent e) {
MenuSelectionManager manager = MenuSelectionManager.defaultManager();
int modifiers = e.getModifiers();
@@ -1037,6 +1038,7 @@
manager.setSelectedPath(getPath());
}
}
+ @SuppressWarnings("deprecation")
public void mouseExited(MouseEvent e) {
MenuSelectionManager manager = MenuSelectionManager.defaultManager();
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicMenuUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -123,6 +123,7 @@
getPropertyPrefix() + ".actionMap");
}
+ @SuppressWarnings("deprecation")
void updateMnemonicBinding() {
int mnemonic = menuItem.getModel().getMnemonic();
int[] shortcutKeys = (int[])DefaultLookup.get(menuItem, this,
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -268,6 +268,7 @@
return list;
}
+ @SuppressWarnings("deprecation")
public boolean isPopupTrigger(MouseEvent e) {
return ((e.getID()==MouseEvent.MOUSE_RELEASED)
&& ((e.getModifiers() & MouseEvent.BUTTON3_MASK)!=0));
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -328,6 +328,7 @@
/**
* Installs the UI defaults.
*/
+ @SuppressWarnings("deprecation")
protected void installDefaults(){
LookAndFeel.installBorder(splitPane, "SplitPane.border");
LookAndFeel.installColors(splitPane, "SplitPane.background",
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTableUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTableUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -868,6 +868,7 @@
public void keyReleased(KeyEvent e) { }
+ @SuppressWarnings("deprecation")
public void keyTyped(KeyEvent e) {
KeyStroke keyStroke = KeyStroke.getKeyStroke(e.getKeyChar(),
e.getModifiers());
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -525,7 +525,7 @@
* adding 'TAB' and 'SHIFT-TAB' to traversalKeysSet in case
* editor is non editable
*/
-
+ @SuppressWarnings("deprecation")
void updateFocusTraversalKeys() {
/*
* Fix for 4514331 Non-editable JTextArea and similar
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalRootPaneUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalRootPaneUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -898,6 +898,7 @@
w.setCursor(lastCursor);
}
+ @SuppressWarnings("deprecation")
public void mouseClicked(MouseEvent ev) {
Window w = (Window)ev.getSource();
Frame f = null;
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalToolTipUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalToolTipUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -192,6 +192,7 @@
// that subclasses that randomly invoke this method will see varying
// results. If this becomes an issue, MetalToolTipUI should no longer be
// shared.
+ @SuppressWarnings("deprecation")
public String getAcceleratorString() {
if (tip == null || isAcceleratorHidden()) {
return "";
--- a/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java Wed Jul 05 22:52:22 2017 +0200
@@ -80,6 +80,7 @@
* Installs the UI defaults.
*/
@Override
+ @SuppressWarnings("deprecation")
protected void installDefaults() {
updateStyle(splitPane);
--- a/jdk/src/java.desktop/share/classes/javax/swing/table/JTableHeader.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/table/JTableHeader.java Wed Jul 05 22:52:22 2017 +0200
@@ -384,6 +384,7 @@
* renderer and, therefore, the proper tip
* @return the tool tip for this component
*/
+ @SuppressWarnings("deprecation")
public String getToolTipText(MouseEvent event) {
String tip = null;
Point p = event.getPoint();
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java Wed Jul 05 22:52:22 2017 +0200
@@ -372,6 +372,7 @@
/**
* Selects word based on the MouseEvent
*/
+ @SuppressWarnings("deprecation")
private void selectWord(MouseEvent e) {
if (selectedWordEvent != null
&& selectedWordEvent.getX() == e.getX()
@@ -405,6 +406,7 @@
* @param e the mouse event
* @see MouseListener#mouseClicked
*/
+ @SuppressWarnings("deprecation")
public void mouseClicked(MouseEvent e) {
if (getComponent() == null) {
return;
@@ -513,6 +515,7 @@
/**
* Adjusts the caret location based on the MouseEvent.
*/
+ @SuppressWarnings("deprecation")
private void adjustCaret(MouseEvent e) {
if ((e.getModifiers() & ActionEvent.SHIFT_MASK) != 0 &&
getDot() != -1) {
--- a/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java Wed Jul 05 22:52:22 2017 +0200
@@ -4103,6 +4103,7 @@
get(FOCUSED_COMPONENT);
}
+ @SuppressWarnings("deprecation")
private int getCurrentEventModifiers() {
int modifiers = 0;
AWTEvent currentEvent = EventQueue.getCurrentEvent();
--- a/jdk/src/java.desktop/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,6 +26,8 @@
/**
* Defines the AWT and Swing user interface toolkits, plus APIs for
* accessibility, audio, imaging, printing, and JavaBeans.
+ *
+ * @since 9
*/
module java.desktop {
requires transitive java.datatransfer;
@@ -88,9 +90,6 @@
exports sun.awt to
jdk.accessibility;
- exports com.sun.awt to
- jdk.desktop;
-
opens javax.swing.plaf.basic to
jdk.jconsole;
opens com.sun.java.swing.plaf.windows to
--- a/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/awt/AWTAccessor.java Wed Jul 05 22:52:22 2017 +0200
@@ -93,12 +93,6 @@
* its parent.
*/
Rectangle getBounds(Component comp);
- /*
- * Sets the shape of a lw component to cut out from hw components.
- *
- * See 6797587, 6776743, 6768307, and 6768332 for details
- */
- void setMixingCutoutShape(Component comp, Shape shape);
/**
* Sets GraphicsConfiguration value for the component.
--- a/jdk/src/java.desktop/share/classes/sun/awt/NullComponentPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/awt/NullComponentPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -126,6 +126,7 @@
public void coalescePaintEvent(PaintEvent e) {
}
+ @SuppressWarnings("deprecation")
public boolean handleEvent(Event e) {
return false;
}
--- a/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/awt/SunToolkit.java Wed Jul 05 22:52:22 2017 +0200
@@ -1049,6 +1049,7 @@
/**
* Returns key modifiers used by Swing to set up a focus accelerator key stroke.
*/
+ @SuppressWarnings("deprecation")
public int getFocusAcceleratorKeyMask() {
return InputEvent.ALT_MASK;
}
@@ -1059,6 +1060,7 @@
* the way things work on Windows: here, pressing ctrl + alt allows user to enter
* characters from the extended character set (like euro sign or math symbols)
*/
+ @SuppressWarnings("deprecation")
public boolean isPrintableCharacterModifiersMask(int mods) {
return ((mods & InputEvent.ALT_MASK) == (mods & InputEvent.CTRL_MASK));
}
--- a/jdk/src/java.desktop/share/classes/sun/swing/FilePane.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/swing/FilePane.java Wed Jul 05 22:52:22 2017 +0200
@@ -1831,6 +1831,7 @@
private class Handler implements MouseListener {
private MouseListener doubleClickListener;
+ @SuppressWarnings("deprecation")
public void mouseClicked(MouseEvent evt) {
JComponent source = (JComponent)evt.getSource();
--- a/jdk/src/java.desktop/share/classes/sun/swing/MenuItemLayoutHelper.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/swing/MenuItemLayoutHelper.java Wed Jul 05 22:52:22 2017 +0200
@@ -175,6 +175,7 @@
arrowSize.origWidth = arrowSize.width;
}
+ @SuppressWarnings("deprecation")
private String getAccText(String acceleratorDelimiter) {
String accText = "";
KeyStroke accelerator = mi.getAccelerator();
--- a/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java Wed Jul 05 22:52:22 2017 +0200
@@ -1460,7 +1460,7 @@
*
* @param ie InputEvent to check
*/
-
+ @SuppressWarnings("deprecation")
private static boolean isAccessClipboardGesture(InputEvent ie) {
boolean allowedGesture = false;
if (ie instanceof KeyEvent) { //we can validate only keyboard gestures
@@ -2129,6 +2129,7 @@
return -1;
}
+ @SuppressWarnings("deprecation")
public static int getSystemMnemonicKeyMask() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
if (toolkit instanceof SunToolkit) {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java Wed Jul 05 22:52:22 2017 +0200
@@ -429,7 +429,7 @@
gtkImagesLoaded = true;
}
}
-
+ @SuppressWarnings("deprecation")
private class ActionPerformer extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
// hide the balloon by any click
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/ListHelper.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/ListHelper.java Wed Jul 05 22:52:22 2017 +0200
@@ -385,7 +385,7 @@
}
return false;
}
-
+ @SuppressWarnings("deprecation")
void handleVSBEvent(MouseEvent e, Rectangle bounds, int x, int y) {
int sbHeight = hsbVis ? bounds.height - SCROLLBAR_WIDTH : bounds.height;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XBaseMenuWindow.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XBaseMenuWindow.java Wed Jul 05 22:52:22 2017 +0200
@@ -1087,7 +1087,9 @@
}
} else {
//Invoke action event
- item.action(mouseEvent.getWhen(), mouseEvent.getModifiers());
+ @SuppressWarnings("deprecation")
+ final int modifiers = mouseEvent.getModifiers();
+ item.action(mouseEvent.getWhen(), modifiers);
ungrabInput();
}
} else {
@@ -1200,7 +1202,9 @@
if (citem instanceof XMenuPeer) {
cwnd.selectItem(citem, true);
} else if (citem != null) {
- citem.action(event.getWhen(), event.getModifiers());
+ @SuppressWarnings("deprecation")
+ final int modifiers = event.getModifiers();
+ citem.action(event.getWhen(), modifiers);
ungrabInput();
}
break;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XButtonPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XButtonPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -120,7 +120,9 @@
if (XToolkit.isLeftMouseButton(e)) {
if (armed)
{
- action(e.getWhen(),e.getModifiers());
+ @SuppressWarnings("deprecation")
+ final int modifiers = e.getModifiers();
+ action(e.getWhen(), modifiers);
}
pressed = false;
armed = false;
@@ -168,7 +170,9 @@
pressed=true;
armed=true;
repaint();
- action(e.getWhen(),e.getModifiers());
+ @SuppressWarnings("deprecation")
+ final int modifiers = e.getModifiers();
+ action(e.getWhen(), modifiers);
}
break;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XChoicePeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XChoicePeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -482,7 +482,7 @@
firstPress = false;
dragStartIdx = -1;
}
-
+ @SuppressWarnings("deprecation")
public void mouseDragged(MouseEvent e) {
/*
* fix for 5003166. On Motif user are unable to drag
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedServerTester.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XEmbedServerTester.java Wed Jul 05 22:52:22 2017 +0200
@@ -452,6 +452,7 @@
waitWindowActivated(res);
return res;
}
+ @SuppressWarnings("deprecation")
private int activateServerNoWait(int prev) {
xembedLog.fine("Activating server");
int res = getEventPos();
@@ -467,6 +468,7 @@
robot.mouseRelease(InputEvent.BUTTON1_MASK);
return res;
}
+ @SuppressWarnings("deprecation")
private int deactivateServer() {
xembedLog.fine("Deactivating server");
int res = getEventPos();
@@ -480,6 +482,7 @@
waitWindowDeactivated(res);
return res;
}
+ @SuppressWarnings("deprecation")
private int focusServer() {
xembedLog.fine("Focusing server");
boolean weFocused = focused;
@@ -740,6 +743,7 @@
private void ungrabKey() {
sendMessage(XEmbedHelper.NON_STANDARD_XEMBED_GTK_UNGRAB_KEY, 0, accel_keysym, accel_mods);
}
+ @SuppressWarnings("deprecation")
private int showModalDialog() {
xembedLog.fine("Showing modal dialog");
int res = getEventPos();
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XListPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XListPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -573,7 +573,7 @@
repaint();
}
}
-
+ @SuppressWarnings("deprecation")
void mousePressed(MouseEvent mouseEvent) {
if (log.isLoggable(PlatformLogger.Level.FINER)) {
log.finer(mouseEvent.toString() + ", hsb " + hsbVis + ", vsb " + vsbVis);
@@ -641,6 +641,7 @@
isMousePressed = true;
}
}
+ @SuppressWarnings("deprecation")
void mouseReleased(MouseEvent mouseEvent) {
if (isEnabled() && mouseEvent.getButton() == MouseEvent.BUTTON1) {
//winReleaseCursorFocus();
@@ -685,6 +686,7 @@
}
}
+ @SuppressWarnings("deprecation")
void mouseDragged(MouseEvent mouseEvent) {
// TODO: can you drag w/ any other buttons? what about multiple buttons?
if (isEnabled() &&
@@ -810,7 +812,7 @@
break;
}
}
-
+ @SuppressWarnings("deprecation")
void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (log.isLoggable(PlatformLogger.Level.FINE)) {
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuBarPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XMenuBarPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -503,6 +503,7 @@
* This function is called from XWindow
* @see XWindow.handleF10onEDT()
*/
+ @SuppressWarnings("deprecation")
void handleF10KeyPress(KeyEvent event) {
int keyState = event.getModifiers();
if (((keyState & InputEvent.ALT_MASK) != 0) ||
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XPopupMenuPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XPopupMenuPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -131,6 +131,7 @@
/*
* From PopupMenuPeer
*/
+ @SuppressWarnings("deprecation")
public void show(Event e) {
target = (Component)e.target;
// Get menus from the target.
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XScrollPanePeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XScrollPanePeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -468,6 +468,7 @@
* MouseEvent.MOUSE_EXITED
* MouseEvent.MOUSE_DRAGGED
*/
+ @SuppressWarnings("deprecation")
public void handleJavaMouseEvent( MouseEvent mouseEvent ) {
super.handleJavaMouseEvent(mouseEvent);
int modifiers = mouseEvent.getModifiers();
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XScrollbar.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XScrollbar.java Wed Jul 05 22:52:22 2017 +0200
@@ -457,6 +457,7 @@
* MouseEvent.MOUSE_EXITED
* MouseEvent.MOUSE_DRAGGED
*/
+ @SuppressWarnings("deprecation")
public void handleMouseEvent(int id, int modifiers, int x, int y) {
if ((modifiers & InputEvent.BUTTON1_MASK) == 0) {
return;
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XScrollbarPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XScrollbarPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -126,6 +126,7 @@
* MouseEvent.MOUSE_EXITED
* MouseEvent.MOUSE_DRAGGED
*/
+ @SuppressWarnings("deprecation")
public void handleJavaMouseEvent( MouseEvent mouseEvent ) {
super.handleJavaMouseEvent(mouseEvent);
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTextAreaPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTextAreaPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -1344,6 +1344,7 @@
}
}
+ @SuppressWarnings("deprecation")
private static MouseEvent newMouseEvent(
Component source, Point point, MouseEvent template )
{
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -477,6 +477,7 @@
e.setSource(xtiPeer.target);
XToolkit.postEvent(XToolkit.targetToAppContext(e.getSource()), e);
}
+ @SuppressWarnings("deprecation")
public void mouseClicked(MouseEvent e) {
if ((e.getClickCount() == 1 || xtiPeer.balloon.isVisible()) &&
e.getButton() == MouseEvent.BUTTON1)
--- a/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java Wed Jul 05 22:52:22 2017 +0200
@@ -621,7 +621,7 @@
// 4 and 5 buttons are usually considered assigned to a first wheel
return button == XConstants.buttons[3] || button == XConstants.buttons[4];
}
-
+ @SuppressWarnings("deprecation")
static int getXModifiers(AWTKeyStroke stroke) {
int mods = stroke.getModifiers();
int res = 0;
--- a/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/unix/classes/sun/print/IPPPrintService.java Wed Jul 05 22:52:22 2017 +0200
@@ -59,6 +59,7 @@
import java.util.Iterator;
import java.util.HashSet;
+import java.util.Map;
public class IPPPrintService implements PrintService, SunPrinterJobService {
@@ -1758,6 +1759,19 @@
if (responseMap != null && responseMap.length > 0) {
getAttMap = responseMap[0];
+ // If there is extra hashmap created due to duplicate
+ // key/attribute present in IPPresponse, then use that
+ // map too by appending to getAttMap after removing the
+ // duplicate key/value
+ if (responseMap.length > 1) {
+ for (int i = 1; i < responseMap.length; i++) {
+ for (Map.Entry<String, AttributeClass> entry : responseMap[i].entrySet()) {
+ if (!getAttMap.containsKey(entry.getValue())) {
+ getAttMap.put(entry.getKey(), entry.getValue());
+ }
+ }
+ }
+ }
}
} else {
debug_println(debugPrefix+"opGetAttributes - null input stream");
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WButtonPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WButtonPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -95,6 +95,7 @@
private static native void initIDs();
@Override
+ @SuppressWarnings("deprecation")
public boolean handleJavaKeyEvent(KeyEvent e) {
switch (e.getID()) {
case KeyEvent.KEY_RELEASED:
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -263,6 +263,7 @@
void disable() {}
@Override
public void reshape(int x, int y, int width, int height) {}
+ @SuppressWarnings("deprecation")
public boolean handleEvent(Event e) { return false; }
@Override
public void setForeground(Color c) {}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -70,6 +70,7 @@
private native void createMenu(WComponentPeer parent);
+ @SuppressWarnings("deprecation")
public void show(Event e) {
Component origin = (Component)e.target;
WComponentPeer peer = (WComponentPeer) WToolkit.targetToPeer(origin);
@@ -97,6 +98,7 @@
*/
void show(Component origin, Point p) {
WComponentPeer peer = (WComponentPeer) WToolkit.targetToPeer(origin);
+ @SuppressWarnings("deprecation")
Event e = new Event(origin, 0, Event.MOUSE_DOWN, p.x, p.y, 0, 0);
if (peer == null) {
Component nativeOrigin = WToolkit.getNativeContainer(origin);
@@ -107,5 +109,6 @@
_show(e);
}
+ @SuppressWarnings("deprecation")
private native void _show(Event e);
}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPrintDialogPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -135,6 +135,7 @@
void disable() {}
@Override
public void reshape(int x, int y, int width, int height) {}
+ @SuppressWarnings("deprecation")
public boolean handleEvent(Event e) { return false; }
@Override
public void setForeground(Color c) {}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WTextFieldPeer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WTextFieldPeer.java Wed Jul 05 22:52:22 2017 +0200
@@ -43,6 +43,7 @@
}
@Override
+ @SuppressWarnings("deprecation")
public boolean handleJavaKeyEvent(KeyEvent e) {
switch (e.getID()) {
case KeyEvent.KEY_TYPED:
--- a/jdk/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java Wed Jul 05 22:52:22 2017 +0200
@@ -229,6 +229,7 @@
* or {@code null} if no transform is performed
*
* @since 9
+ * @spec JPMS
*/
default byte[]
transform( Module module,
--- a/jdk/src/java.instrument/share/classes/java/lang/instrument/Instrumentation.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.instrument/share/classes/java/lang/instrument/Instrumentation.java Wed Jul 05 22:52:22 2017 +0200
@@ -714,6 +714,7 @@
* @throws NullPointerException if any of the arguments are {@code null} or
* any of the Sets or Maps contains a {@code null} key or value
* @since 9
+ * @spec JPMS
*/
void redefineModule(Module module,
Set<Module> extraReads,
--- a/jdk/src/java.instrument/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.instrument/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,6 +26,8 @@
/**
* Defines services that allow agents to
* instrument programs running on the JVM.
+ *
+ * @since 9
*/
module java.instrument {
exports java.lang.instrument;
--- a/jdk/src/java.logging/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.logging/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the Java Logging API.
+ *
+ * @since 9
*/
module java.logging {
exports java.util.logging;
--- a/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java Wed Jul 05 22:52:22 2017 +0200
@@ -38,6 +38,7 @@
import java.io.ObjectInputStream;
import java.io.ObjectStreamClass;
import java.io.Serializable;
+import java.lang.module.ModuleDescriptor;
import java.lang.ref.WeakReference;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
@@ -107,6 +108,8 @@
import sun.rmi.transport.LiveRef;
import java.io.NotSerializableException;
+import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
+
/**
* <p>A connection to a remote RMI connector. Usually, such
* connections are made using {@link
@@ -2020,8 +2023,14 @@
Module rmiModule = RemoteRef.class.getModule();
String pkg = packageOf(pRefClassName);
- assert pkg != null && pkg.length() > 0 && !pkg.equals(packageOf(proxyRefCName));
- Module m = Modules.defineModule(cl, "jdk.remoteref", Collections.singleton(pkg));
+ assert pkg != null && pkg.length() > 0 &&
+ !pkg.equals(packageOf(proxyRefCName));
+
+ ModuleDescriptor descriptor =
+ ModuleDescriptor.newModule("jdk.remoteref", Set.of(SYNTHETIC))
+ .packages(Set.of(pkg))
+ .build();
+ Module m = Modules.defineModule(cl, descriptor, null);
// jdk.remoteref needs to read to java.base and jmxModule
Modules.addReads(m, Object.class.getModule());
--- a/jdk/src/java.management.rmi/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.management.rmi/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -46,6 +46,7 @@
* and load the appropriate {@code JMXConnectorServerProvider} service
* implementation for the given protocol.
*
+ * @since 9
*/
module java.management.rmi {
--- a/jdk/src/java.management/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.management/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -28,6 +28,8 @@
* <P>
* The JMX API consists of interfaces for monitoring and management of the
* JVM and other components in the Java runtime.
+ *
+ * @since 9
*/
module java.management {
--- a/jdk/src/java.naming/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.naming/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the Java Naming and Directory Interface (JNDI) API.
+ *
+ * @since 9
*/
module java.naming {
requires java.security.sasl;
--- a/jdk/src/java.prefs/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.prefs/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the Preferences API.
+ *
+ * @since 9
*/
module java.prefs {
requires java.xml;
--- a/jdk/src/java.rmi/share/classes/java/rmi/activation/ActivationInstantiator.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.rmi/share/classes/java/rmi/activation/ActivationInstantiator.java Wed Jul 05 22:52:22 2017 +0200
@@ -60,7 +60,20 @@
* initialization data, and
*
* <li> returning a MarshalledObject containing the stub for the
- * remote object it created </ul>
+ * remote object it created.</ul>
+ *
+ * <p>In order for activation to be successful, one of the following requirements
+ * must be met, otherwise {@link ActivationException} is thrown:
+ *
+ * <ul><li>The class to be activated and the special activation constructor are both public,
+ * and the class resides in a package that is
+ * {@linkplain java.lang.reflect.Module#isExported(String,java.lang.reflect.Module) exported}
+ * to at least the {@code java.rmi} module; or
+ *
+ * <li>The class to be activated resides in a package that is
+ * {@linkplain java.lang.reflect.Module#isOpen(String,java.lang.reflect.Module) open}
+ * to at least the {@code java.rmi} module.
+ * </ul>
*
* @param id the object's activation identifier
* @param desc the object's descriptor
--- a/jdk/src/java.rmi/share/classes/java/rmi/activation/Activator.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.rmi/share/classes/java/rmi/activation/Activator.java Wed Jul 05 22:52:22 2017 +0200
@@ -48,7 +48,7 @@
* The <code>Activator</code> works closely with
* <code>ActivationSystem</code>, which provides a means for registering
* groups and objects within those groups, and <code>ActivationMonitor</code>,
- * which recives information about active and inactive objects and inactive
+ * which receives information about active and inactive objects and inactive
* groups. <p>
*
* The activator is responsible for monitoring and detecting when
--- a/jdk/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.rmi/share/classes/java/rmi/server/UnicastRemoteObject.java Wed Jul 05 22:52:22 2017 +0200
@@ -107,8 +107,9 @@
* the binary name of the root class with the suffix {@code _Stub}.
*
* <li>The stub class is loaded by name using the class loader of the root
- * class. The stub class must extend {@link RemoteStub} and must have a
- * public constructor that has one parameter of type {@link RemoteRef}.
+ * class. The stub class must be public, it must extend {@link RemoteStub}, it must
+ * reside in a package that is exported to at least the {@code java.rmi} module, and it
+ * must have a public constructor that has one parameter of type {@link RemoteRef}.
*
* <li>Finally, an instance of the stub class is constructed with a
* {@link RemoteRef}.
@@ -124,12 +125,21 @@
*
* <ul>
*
- * <li>The proxy's class is defined by the class loader of the remote
- * object's class.
+ * <li>The proxy's class is defined according to the specifications for the
+ * <a href="{@docRoot}/java/lang/reflect/Proxy.html#membership">
+ * {@code Proxy}
+ * </a>
+ * class, using the class loader of the remote object's class.
*
* <li>The proxy implements all the remote interfaces implemented by the
* remote object's class.
*
+ * <li>Each remote interface must either be public and reside in a package that is
+ * {@linkplain java.lang.reflect.Module#isExported(String,java.lang.reflect.Module) exported}
+ * to at least the {@code java.rmi} module, or it must reside in a package that is
+ * {@linkplain java.lang.reflect.Module#isOpen(String,java.lang.reflect.Module) open}
+ * to at least the {@code java.rmi} module.
+ *
* <li>The proxy's invocation handler is a {@link
* RemoteObjectInvocationHandler} instance constructed with a
* {@link RemoteRef}.
--- a/jdk/src/java.rmi/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.rmi/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the Remote Method Invocation (RMI) API.
+ *
+ * @since 9
*/
module java.rmi {
requires java.logging;
--- a/jdk/src/java.scripting/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.scripting/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the Scripting API.
+ *
+ * @since 9
*/
module java.scripting {
exports javax.script;
--- a/jdk/src/java.se.ee/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.se.ee/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -28,6 +28,8 @@
* <P>
* This module requires {@code java.se} and supplements it with modules
* that define CORBA and Java EE APIs. These modules are upgradeable.
+ *
+ * @since 9
*/
@SuppressWarnings("deprecation")
module java.se.ee {
--- a/jdk/src/java.se/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.se/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -28,6 +28,8 @@
* <P>
* The modules defining CORBA and Java EE APIs are not required by
* this module, but they are required by {@code java.se.ee}.
+ *
+ * @since 9
*/
module java.se {
requires transitive java.compiler;
--- a/jdk/src/java.security.jgss/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.security.jgss/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -27,6 +27,8 @@
* Defines the Java binding of the IETF Generic Security Services API (GSS-API).
* <P>
* This module also contains GSS-API mechanisms including Kerberos v5 and SPNEGO.
+ *
+ * @since 9
*/
module java.security.jgss {
requires java.naming;
--- a/jdk/src/java.security.sasl/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.security.sasl/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -29,6 +29,8 @@
* <P>
* This module also contains SASL mechanisms including DIGEST-MD5,
* CRAM-MD5, and NTLM.
+ *
+ * @since 9
*/
module java.security.sasl {
requires java.logging;
--- a/jdk/src/java.smartcardio/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.smartcardio/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the Java Smart Card I/O API.
+ *
+ * @since 9
*/
module java.smartcardio {
exports javax.smartcardio;
--- a/jdk/src/java.sql.rowset/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.sql.rowset/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the JDBC RowSet API.
+ *
+ * @since 9
*/
module java.sql.rowset {
requires transitive java.logging;
--- a/jdk/src/java.sql/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.sql/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the JDBC API.
+ *
+ * @since 9
*/
module java.sql {
requires transitive java.logging;
--- a/jdk/src/java.transaction/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.transaction/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -28,6 +28,8 @@
* <P>
* The subset consists of RMI exception types which are mapped to CORBA system
* exceptions by the 'Java Language to IDL Mapping Specification'.
+ *
+ * @since 9
*/
module java.transaction {
requires transitive java.rmi;
--- a/jdk/src/java.xml.crypto/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/java.xml.crypto/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines an API for XML cryptography.
+ *
+ * @since 9
*/
module java.xml.crypto {
requires transitive java.xml;
--- a/jdk/src/jdk.attach/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.attach/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the attach API.
+ *
+ * @since 9
*/
module jdk.attach {
requires jdk.internal.jvmstat;
--- a/jdk/src/jdk.crypto.ucrypto/solaris/conf/security/ucrypto-solaris.cfg Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/conf/security/ucrypto-solaris.cfg Wed Jul 05 22:52:22 2017 +0200
@@ -2,8 +2,5 @@
# Configuration file for the OracleUcrypto provider
#
disabledServices = {
- # disabled due to Solaris bug 7121679
- Cipher.AES/CFB128/PKCS5Padding
- Cipher.AES/CFB128/NoPadding
}
--- a/jdk/src/jdk.desktop/share/classes/jdk/awt/AWTUtils.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +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.awt;
-
-import java.awt.Component;
-import java.awt.Shape;
-
-import com.sun.awt.AWTUtilities;
-
-/**
- * A class to allow access to JDK-specific utility methods.
- * Methods in this class are always deprecated since a caller
- * should be aware they may be removed and replaced in the future.
- * Access using reflection is highly recommended.
- * @since 9
- */
-public final class AWTUtils {
-
- /**
- * No-one should be creating instances of this class.
- */
- private AWTUtils() {
- }
-
- /**
- * Sets a 'mixing-cutout' shape for the given component.
- *
- * By default a lightweight component is treated as an opaque rectangle for
- * the purposes of the Heavyweight/Lightweight Components Mixing feature.
- * This method enables developers to set an arbitrary shape to be cut out
- * from heavyweight components positioned underneath the lightweight
- * component in the z-order.
- * <p>
- * The {@code shape} argument may have the following values:
- * <ul>
- * <li>{@code null} - reverts the default cutout shape (the rectangle equal
- * to the component's {@code getBounds()})
- * <li><i>empty-shape</i> - does not cut out anything from heavyweight
- * components. This makes the given lightweight component effectively
- * transparent. Note that descendants of the lightweight component still
- * affect the shapes of heavyweight components. An example of an
- * <i>empty-shape</i> is {@code new Rectangle()}.
- * <li><i>non-empty-shape</i> - the given shape will be cut out from
- * heavyweight components.
- * </ul>
- * <p>
- * The most common example when the 'mixing-cutout' shape is needed is a
- * glass pane component. The {@link JRootPane#setGlassPane()} method
- * automatically sets the <i>empty-shape</i> as the 'mixing-cutout' shape
- * for the given glass pane component. If a developer needs some other
- * 'mixing-cutout' shape for the glass pane (which is rare), this must be
- * changed manually after installing the glass pane to the root pane.
- * <p>
- * Note that the 'mixing-cutout' shape neither affects painting, nor the
- * mouse events handling for the given component. It is used exclusively
- * for the purposes of the Heavyweight/Lightweight Components Mixing
- * feature.
- *
- * @param component the component that needs non-default
- * 'mixing-cutout' shape
- * @param shape the new 'mixing-cutout' shape
- * @throws NullPointerException if the component argument is {@code null}
- * @deprecated This API may be removed or replaced.
- */
- @Deprecated
- @SuppressWarnings("deprecation")
- public static void setComponentMixingCutoutShape(Component component,
- Shape shape) {
-
- AWTUtilities.setComponentMixingCutoutShape(component, shape);
- }
-}
--- a/jdk/src/jdk.desktop/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +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.
- */
-
-/*
- * Provides non-SE desktop APIs.
- */
-
-module jdk.desktop {
- requires transitive java.desktop;
-
- exports jdk.awt;
-}
--- a/jdk/src/jdk.editpad/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.editpad/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Implementation of the edit pad service.
+ *
+ * @since 9
*/
module jdk.editpad {
requires jdk.internal.ed;
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLDelegate.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/AsyncSSLDelegate.java Wed Jul 05 22:52:22 2017 +0200
@@ -609,11 +609,13 @@
}
// SSLParameters.getApplicationProtocols() can't return null
+ // JDK 8 EXCL START
for (String approto : p.getApplicationProtocols()) {
sb.append("\n application protocol: {")
.append(params.size()).append("}");
params.add(approto);
}
+ // JDK 8 EXCL END
if (p.getProtocols() != null) {
for (String protocol : p.getProtocols()) {
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/DefaultPublisher.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/DefaultPublisher.java Wed Jul 05 22:52:22 2017 +0200
@@ -91,11 +91,13 @@
for (long i = 0; i < nbItemsDemanded && !done.get(); i++) {
try {
Optional<T> item = Objects.requireNonNull(supplier.get());
- item.ifPresentOrElse(subscriber::onNext, () -> {
+ if (item.isPresent()) {
+ subscriber.onNext(item.get());
+ } else {
if (done.compareAndSet(false, true)) {
subscriber.onComplete();
}
- });
+ }
} catch (RuntimeException e) {
if (done.compareAndSet(false, true)) {
subscriber.onError(e);
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpResponse.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/HttpResponse.java Wed Jul 05 22:52:22 2017 +0200
@@ -30,6 +30,8 @@
import java.net.URI;
import jdk.incubator.http.ResponseProcessors.MultiFile;
import jdk.incubator.http.ResponseProcessors.MultiProcessorImpl;
+import static jdk.incubator.http.internal.common.Utils.unchecked;
+import static jdk.incubator.http.internal.common.Utils.charsetFrom;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
@@ -269,19 +271,6 @@
};
}
- /**
- * Get the Charset from the Content-encoding header. Defaults to
- * UTF_8
- */
- private static Charset charsetFrom(HttpHeaders headers) {
- String encoding = headers.firstValue("Content-encoding")
- .orElse("UTF_8");
- try {
- return Charset.forName(encoding);
- } catch (IllegalArgumentException e) {
- return StandardCharsets.UTF_8;
- }
- }
/**
* Returns a {@code BodyHandler<Path>} that returns a
@@ -342,10 +331,6 @@
};
}
- private static UncheckedIOException unchecked(IOException e) {
- return new UncheckedIOException(e);
- }
-
/**
* Returns a {@code BodyHandler<Path>} that returns a
* {@link BodyProcessor BodyProcessor}{@code <Path>} obtained from
@@ -743,48 +728,5 @@
return asMap(pushHandler, true);
}
- /**
- * Returns a {@code MultiProcessor} which writes the response bodies to
- * files under a given root directory and which returns an aggregate
- * response map that is a {@code Map<HttpRequest, HttpResponse<Path>>}.
- * The keyset of the {@code Map} represents the original request and any
- * additional requests generated by the server. The values are the
- * responses containing the paths of the destination files. Each file
- * uses the URI path of the request relative to the destination parent
- * directorycprovided.
- *
- * <p>
- * All incoming additional requests (push promises) are accepted by this
- * multi response processor. Errors are effectively ignored and any
- * failed responses are simply omitted from the result {@code Map}.
- * Other implementations of {@code MultiProcessor} may handle these
- * situations.
- *
- * <p>
- * <b>Example usage</b>
- * <pre>
- * {@code
- * HttpClient client = ..
- * HttpRequest request = HttpRequest
- * .create(new URI("https://www.foo.com/"))
- * .version(Version.HTTP2)
- * .GET();
- *
- * Map<HttpRequest, HttpResponse<Path>>> map = client
- * .sendAsync(HttpResponse.MultiProcessor.multiFile("/usr/destination"))
- * .join();
- *
- * }
- * </pre>
- * TEMPORARILY REMOVING THIS FROM API. MIGHT NOT BE NEEDED.
- *
- * @param destination the destination parent directory of all response
- * bodies
- * @return a MultiProcessor
- */
- private static MultiProcessor<MultiMapResult<Path>,Path> multiFile(Path destination) {
- MultiFile mf = new MultiFile(destination);
- return new MultiProcessorImpl<Path>(mf::handlePush, true);
- }
}
}
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ResponseProcessors.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/ResponseProcessors.java Wed Jul 05 22:52:22 2017 +0200
@@ -252,7 +252,7 @@
@Override
public void onError(HttpRequest request, Throwable t) {
- results.put(request, CompletableFuture.failedFuture(t));
+ results.put(request, MinimalFuture.failedFuture(t));
}
@Override
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLDelegate.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/SSLDelegate.java Wed Jul 05 22:52:22 2017 +0200
@@ -449,9 +449,11 @@
for (String cipher : p.getCipherSuites()) {
System.out.printf("cipher: %s\n", cipher);
}
+ // JDK 8 EXCL START
for (String approto : p.getApplicationProtocols()) {
System.out.printf("application protocol: %s\n", approto);
}
+ // JDK 8 EXCL END
for (String protocol : p.getProtocols()) {
System.out.printf("protocol: %s\n", protocol);
}
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/MinimalFuture.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/MinimalFuture.java Wed Jul 05 22:52:22 2017 +0200
@@ -110,7 +110,6 @@
}
}
- @Override
public <U> MinimalFuture<U> newIncompleteFuture() {
return new MinimalFuture<>();
}
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/Queue.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/Queue.java Wed Jul 05 22:52:22 2017 +0200
@@ -118,11 +118,13 @@
public synchronized void closeExceptionally(Throwable t) {
if (exception == null) exception = t;
else if (t != null && t != exception) {
- Stream.of(exception.getSuppressed())
+ if (!Stream.of(exception.getSuppressed())
.filter(x -> x == t)
.findFirst()
- .ifPresentOrElse((x) -> {},
- () -> exception.addSuppressed(t));
+ .isPresent())
+ {
+ exception.addSuppressed(t);
+ }
}
close();
}
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/Utils.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/common/Utils.java Wed Jul 05 22:52:22 2017 +0200
@@ -32,12 +32,14 @@
import java.io.ByteArrayOutputStream;
import java.io.Closeable;
import java.io.IOException;
+import java.io.UncheckedIOException;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.net.NetPermission;
import java.net.URI;
import java.net.URLPermission;
import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -54,6 +56,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.Predicate;
+import jdk.incubator.http.HttpHeaders;
/**
* Miscellaneous utilities
@@ -259,9 +262,11 @@
SSLParameters p1 = new SSLParameters();
p1.setAlgorithmConstraints(p.getAlgorithmConstraints());
p1.setCipherSuites(p.getCipherSuites());
+ // JDK 8 EXCL START
p1.setEnableRetransmissions(p.getEnableRetransmissions());
+ p1.setMaximumPacketSize(p.getMaximumPacketSize());
+ // JDK 8 EXCL END
p1.setEndpointIdentificationAlgorithm(p.getEndpointIdentificationAlgorithm());
- p1.setMaximumPacketSize(p.getMaximumPacketSize());
p1.setNeedClientAuth(p.getNeedClientAuth());
String[] protocols = p.getProtocols();
if (protocols != null) {
@@ -475,4 +480,21 @@
return newb;
}
+ /**
+ * Get the Charset from the Content-encoding header. Defaults to
+ * UTF_8
+ */
+ public static Charset charsetFrom(HttpHeaders headers) {
+ String encoding = headers.firstValue("Content-encoding")
+ .orElse("UTF_8");
+ try {
+ return Charset.forName(encoding);
+ } catch (IllegalArgumentException e) {
+ return StandardCharsets.UTF_8;
+ }
+ }
+
+ public static UncheckedIOException unchecked(IOException e) {
+ return new UncheckedIOException(e);
+ }
}
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/FrameConsumer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/FrameConsumer.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,6 +26,7 @@
package jdk.incubator.http.internal.websocket;
import jdk.incubator.http.WebSocket.MessagePart;
+import jdk.incubator.http.internal.common.Log;
import jdk.incubator.http.internal.websocket.Frame.Opcode;
import java.nio.ByteBuffer;
@@ -33,13 +34,11 @@
import java.nio.charset.CharacterCodingException;
import static java.lang.String.format;
-import static java.lang.System.Logger.Level.TRACE;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.util.Objects.requireNonNull;
import static jdk.incubator.http.internal.common.Utils.dump;
import static jdk.incubator.http.internal.websocket.StatusCodes.NO_STATUS_CODE;
import static jdk.incubator.http.internal.websocket.StatusCodes.checkIncomingCode;
-import static jdk.incubator.http.internal.websocket.WebSocketImpl.logger;
/*
* Consumes frame parts and notifies a message consumer, when there is
@@ -71,17 +70,13 @@
@Override
public void fin(boolean value) {
- if (logger.isLoggable(TRACE)) {
- logger.log(TRACE, "Reading fin: {0}", value);
- }
+ Log.logTrace("Reading fin: {0}", value);
fin = value;
}
@Override
public void rsv1(boolean value) {
- if (logger.isLoggable(TRACE)) {
- logger.log(TRACE, "Reading rsv1: {0}", value);
- }
+ Log.logTrace("Reading rsv1: {0}", value);
if (value) {
throw new FailWebSocketException("Unexpected rsv1 bit");
}
@@ -89,9 +84,7 @@
@Override
public void rsv2(boolean value) {
- if (logger.isLoggable(TRACE)) {
- logger.log(TRACE, "Reading rsv2: {0}", value);
- }
+ Log.logTrace("Reading rsv2: {0}", value);
if (value) {
throw new FailWebSocketException("Unexpected rsv2 bit");
}
@@ -99,9 +92,7 @@
@Override
public void rsv3(boolean value) {
- if (logger.isLoggable(TRACE)) {
- logger.log(TRACE, "Reading rsv3: {0}", value);
- }
+ Log.logTrace("Reading rsv3: {0}", value);
if (value) {
throw new FailWebSocketException("Unexpected rsv3 bit");
}
@@ -109,7 +100,7 @@
@Override
public void opcode(Opcode v) {
- logger.log(TRACE, "Reading opcode: {0}", v);
+ Log.logTrace("Reading opcode: {0}", v);
if (v == Opcode.PING || v == Opcode.PONG || v == Opcode.CLOSE) {
if (!fin) {
throw new FailWebSocketException("Fragmented control frame " + v);
@@ -137,9 +128,7 @@
@Override
public void mask(boolean value) {
- if (logger.isLoggable(TRACE)) {
- logger.log(TRACE, "Reading mask: {0}", value);
- }
+ Log.logTrace("Reading mask: {0}", value);
if (value) {
throw new FailWebSocketException("Masked frame received");
}
@@ -147,10 +136,7 @@
@Override
public void payloadLen(long value) {
- if (logger.isLoggable(TRACE)) {
- // Checked for being loggable because of autoboxing of 'value'
- logger.log(TRACE, "Reading payloadLen: {0}", value);
- }
+ Log.logTrace("Reading payloadLen: {0}", value);
if (opcode.isControl()) {
if (value > 125) {
throw new FailWebSocketException(
@@ -178,9 +164,7 @@
@Override
public void payloadData(ByteBuffer data) {
- if (logger.isLoggable(TRACE)) {
- logger.log(TRACE, "Reading payloadData: data={0}", data);
- }
+ Log.logTrace("Reading payloadData: data={0}", data);
unconsumedPayloadLen -= data.remaining();
boolean isLast = unconsumedPayloadLen == 0;
if (opcode.isControl()) {
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/UTF8AccumulatingDecoder.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/UTF8AccumulatingDecoder.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
package jdk.incubator.http.internal.websocket;
+import jdk.incubator.http.internal.common.Log;
+
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.CharacterCodingException;
@@ -32,10 +34,8 @@
import java.nio.charset.CoderResult;
import java.nio.charset.CodingErrorAction;
-import static java.lang.System.Logger.Level.WARNING;
import static java.nio.charset.StandardCharsets.UTF_8;
import static jdk.incubator.http.internal.common.Utils.EMPTY_BYTEBUFFER;
-import static jdk.incubator.http.internal.websocket.WebSocketImpl.logger;
final class UTF8AccumulatingDecoder {
@@ -74,9 +74,8 @@
// Since it's UTF-8, the assumption is leftovers.remaining() < 4
// (i.e. small). Otherwise a shared buffer should be used
if (!(leftovers.remaining() < 4)) {
- logger.log(WARNING,
- "The size of decoding leftovers is greater than expected: {0}",
- leftovers.remaining());
+ Log.logError("The size of decoding leftovers is greater than expected: {0}",
+ leftovers.remaining());
}
b.position(b.limit()); // As if we always read to the end
// Decoder promises that in the case of endOfInput == true:
--- a/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/WebSocketImpl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/jdk/incubator/http/internal/websocket/WebSocketImpl.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,6 +26,7 @@
package jdk.incubator.http.internal.websocket;
import jdk.incubator.http.WebSocket;
+import jdk.incubator.http.internal.common.Log;
import jdk.incubator.http.internal.common.Pair;
import jdk.incubator.http.internal.websocket.OpeningHandshake.Result;
import jdk.incubator.http.internal.websocket.OutgoingMessage.Binary;
@@ -47,8 +48,6 @@
import java.util.function.Consumer;
import java.util.function.Function;
-import static java.lang.System.Logger.Level.ERROR;
-import static java.lang.System.Logger.Level.TRACE;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.CompletableFuture.failedFuture;
import static jdk.incubator.http.internal.common.Pair.pair;
@@ -61,8 +60,6 @@
*/
final class WebSocketImpl implements WebSocket {
- static final System.Logger logger = System.getLogger("jdk.httpclient.WebSocket");
-
private final URI uri;
private final String subprotocol;
private final RawChannel channel;
@@ -142,7 +139,7 @@
try {
channel.close();
} catch (IOException e) {
- logger.log(ERROR, e);
+ Log.logError(e);
} finally {
closed.set(true);
}
@@ -168,14 +165,14 @@
private void signalError(Throwable error) {
synchronized (lock) {
if (lastMethodInvoked) {
- logger.log(ERROR, error);
+ Log.logError(error);
} else {
lastMethodInvoked = true;
receiver.close();
try {
listener.onError(this, error);
} catch (Exception e) {
- logger.log(ERROR, e);
+ Log.logError(e);
}
}
}
@@ -190,7 +187,7 @@
try {
channel.shutdownInput();
} catch (IOException e) {
- logger.log(ERROR, e);
+ Log.logError(e);
}
boolean wasComplete = !closeReceived.complete(null);
if (wasComplete) {
@@ -210,7 +207,7 @@
enqueueClose(new Close(code, ""))
.whenComplete((r1, error1) -> {
if (error1 != null) {
- logger.log(ERROR, error1);
+ Log.logError(error1);
}
});
});
@@ -223,14 +220,14 @@
private CompletionStage<?> signalClose(int statusCode, String reason) {
synchronized (lock) {
if (lastMethodInvoked) {
- logger.log(TRACE, "Close: {0}, ''{1}''", statusCode, reason);
+ Log.logTrace("Close: {0}, ''{1}''", statusCode, reason);
} else {
lastMethodInvoked = true;
receiver.close();
try {
return listener.onClose(this, statusCode, reason);
} catch (Exception e) {
- logger.log(ERROR, e);
+ Log.logError(e);
}
}
}
@@ -289,7 +286,7 @@
try {
channel.shutdownOutput();
} catch (IOException e) {
- logger.log(ERROR, e);
+ Log.logError(e);
}
boolean wasComplete = !closeSent.complete(null);
if (wasComplete) {
--- a/jdk/src/jdk.incubator.httpclient/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.incubator.httpclient/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,6 +26,8 @@
/**
* Defines the high-level HTTP and WebSocket API.
* {@Incubating}
+ *
+ * @since 9
*/
module jdk.incubator.httpclient {
requires java.base;
--- a/jdk/src/jdk.internal.ed/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.internal.ed/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,6 +26,8 @@
/**
* Internal editor support for JDK tools. Includes the Service Provider
* Interface to built-in editors.
+ *
+ * @since 9
*/
module jdk.internal.ed {
--- a/jdk/src/jdk.internal.le/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.internal.le/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Internal API for line editing
+ *
+ * @since 9
*/
module jdk.internal.le {
exports jdk.internal.jline to
--- a/jdk/src/jdk.internal.opt/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.internal.opt/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Internal option processing API
+ *
+ * @since 9
*/
module jdk.internal.opt {
exports jdk.internal.joptsimple to jdk.jlink, jdk.jshell;
--- a/jdk/src/jdk.jartool/share/classes/com/sun/jarsigner/ContentSigner.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jartool/share/classes/com/sun/jarsigner/ContentSigner.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 @@
* @deprecated This class has been deprecated.
*/
-@Deprecated
+@Deprecated(since="9")
public abstract class ContentSigner {
/**
--- a/jdk/src/jdk.jartool/share/classes/com/sun/jarsigner/ContentSignerParameters.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jartool/share/classes/com/sun/jarsigner/ContentSignerParameters.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@
* @author Vincent Ryan
* @deprecated This class has been deprecated.
*/
-@Deprecated
+@Deprecated(since="9")
public interface ContentSignerParameters {
/**
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/GNUStyleOptions.java Wed Jul 05 22:52:22 2017 +0200
@@ -157,8 +157,7 @@
for (String dir : dirs) {
paths[i++] = Paths.get(dir);
}
- jartool.moduleFinder =
- new ModulePath(Runtime.version(), true, paths);
+ jartool.moduleFinder = ModulePath.of(Runtime.version(), true, paths);
}
},
new Option(false, OptionType.CREATE_UPDATE, "--do-not-resolve-by-default") {
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Main.java Wed Jul 05 22:52:22 2017 +0200
@@ -158,7 +158,7 @@
static final String MANIFEST_DIR = "META-INF/";
static final String VERSIONS_DIR = MANIFEST_DIR + "versions/";
static final String VERSION = "1.0";
-
+ static final int VERSIONS_DIR_LENGTH = VERSIONS_DIR.length();
private static ResourceBundle rsrc;
/**
@@ -681,7 +681,7 @@
void addPackageIfNamed(Set<String> packages, String name) {
if (name.startsWith(VERSIONS_DIR)) {
// trim the version dir prefix
- int i0 = VERSIONS_DIR.length();
+ int i0 = VERSIONS_DIR_LENGTH;
int i = name.indexOf('/', i0);
if (i <= 0) {
warn(formatMsg("warn.release.unexpected.versioned.entry", name));
@@ -699,7 +699,7 @@
}
String pn = toPackageName(name);
// add if this is a class or resource in a package
- if (Checks.isJavaIdentifier(pn)) {
+ if (Checks.isPackageName(pn)) {
packages.add(pn);
}
}
@@ -1727,12 +1727,16 @@
private boolean printModuleDescriptor(ZipFile zipFile)
throws IOException
{
- ZipEntry entry = zipFile.getEntry(MODULE_INFO);
- if (entry == null)
+ ZipEntry[] zes = zipFile.stream()
+ .filter(e -> isModuleInfoEntry(e.getName()))
+ .sorted(Validator.ENTRY_COMPARATOR)
+ .toArray(ZipEntry[]::new);
+ if (zes.length == 0)
return false;
-
- try (InputStream is = zipFile.getInputStream(entry)) {
- printModuleDescriptor(is);
+ for (ZipEntry ze : zes) {
+ try (InputStream is = zipFile.getInputStream(ze)) {
+ printModuleDescriptor(is, ze.getName());
+ }
}
return true;
}
@@ -1742,16 +1746,23 @@
{
try (BufferedInputStream bis = new BufferedInputStream(fis);
ZipInputStream zis = new ZipInputStream(bis)) {
-
ZipEntry e;
while ((e = zis.getNextEntry()) != null) {
- if (e.getName().equals(MODULE_INFO)) {
- printModuleDescriptor(zis);
- return true;
+ String ename = e.getName();
+ if (isModuleInfoEntry(ename)){
+ moduleInfos.put(ename, zis.readAllBytes());
}
}
}
- return false;
+ if (moduleInfos.size() == 0)
+ return false;
+ String[] names = moduleInfos.keySet().stream()
+ .sorted(Validator.ENTRYNAME_COMPARATOR)
+ .toArray(String[]::new);
+ for (String name : names) {
+ printModuleDescriptor(new ByteArrayInputStream(moduleInfos.get(name)), name);
+ }
+ return true;
}
static <T> String toString(Collection<T> set) {
@@ -1760,7 +1771,7 @@
.collect(joining(" "));
}
- private void printModuleDescriptor(InputStream entryInputStream)
+ private void printModuleDescriptor(InputStream entryInputStream, String ename)
throws IOException
{
ModuleInfo.Attributes attrs = ModuleInfo.read(entryInputStream, null);
@@ -1768,10 +1779,12 @@
ModuleHashes hashes = attrs.recordedHashes();
StringBuilder sb = new StringBuilder();
- sb.append("\n");
+ sb.append("\nmodule ")
+ .append(md.toNameAndVersion())
+ .append(" (").append(ename).append(")");
+
if (md.isOpen())
- sb.append("open ");
- sb.append(md.toNameAndVersion());
+ sb.append("\n open ");
md.requires().stream()
.sorted(Comparator.comparing(Requires::name))
@@ -1879,7 +1892,7 @@
if (end == 0)
return true;
if (name.startsWith(VERSIONS_DIR)) {
- int off = VERSIONS_DIR.length();
+ int off = VERSIONS_DIR_LENGTH;
if (off == end) // meta-inf/versions/module-info.class
return false;
while (off < end - 1) {
@@ -1995,7 +2008,7 @@
}
// get a resolved module graph
Configuration config =
- Configuration.empty().resolveRequires(system, finder, roots);
+ Configuration.empty().resolve(system, finder, roots);
// filter modules resolved from the system module finder
this.modules = config.modules().stream()
--- a/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jartool/share/classes/sun/tools/jar/Validator.java Wed Jul 05 22:52:22 2017 +0200
@@ -49,6 +49,7 @@
import static java.util.jar.JarFile.MANIFEST_NAME;
import static sun.tools.jar.Main.VERSIONS_DIR;
+import static sun.tools.jar.Main.VERSIONS_DIR_LENGTH;
import static sun.tools.jar.Main.MODULE_INFO;
import static sun.tools.jar.Main.getMsg;
import static sun.tools.jar.Main.formatMsg;
@@ -59,19 +60,19 @@
final class Validator {
private final static boolean DEBUG = Boolean.getBoolean("jar.debug");
private final Map<String,FingerPrint> fps = new HashMap<>();
- private static final int vdlen = VERSIONS_DIR.length();
private final Main main;
private final JarFile jf;
private int oldVersion = -1;
private String currentTopLevelName;
private boolean isValid = true;
- private Set<String> concealedPkgs;
+ private Set<String> concealedPkgs = Collections.emptySet();
private ModuleDescriptor md;
+ private String mdName;
private Validator(Main main, JarFile jf) {
this.main = main;
this.jf = jf;
- loadModuleDescriptor();
+ checkModuleDescriptor(MODULE_INFO);
}
static boolean validate(Main main, JarFile jf) throws IOException {
@@ -83,7 +84,7 @@
jf.stream()
.filter(e -> !e.isDirectory() &&
!e.getName().equals(MANIFEST_NAME))
- .sorted(entryComparator)
+ .sorted(ENTRY_COMPARATOR)
.forEachOrdered(e -> validate(e));
return isValid;
} catch (InvalidJarException e) {
@@ -102,9 +103,8 @@
// sort base entries before versioned entries, and sort entry classes with
// nested classes so that the top level class appears before the associated
// nested class
- private static Comparator<JarEntry> entryComparator = (je1, je2) -> {
- String s1 = je1.getName();
- String s2 = je2.getName();
+ static Comparator<String> ENTRYNAME_COMPARATOR = (s1, s2) -> {
+
if (s1.equals(s2)) return 0;
boolean b1 = s1.startsWith(VERSIONS_DIR);
boolean b2 = s2.startsWith(VERSIONS_DIR);
@@ -140,6 +140,9 @@
return l1 - l2;
};
+ static Comparator<ZipEntry> ENTRY_COMPARATOR =
+ Comparator.comparing(ZipEntry::getName, ENTRYNAME_COMPARATOR);
+
/*
* Validator has state and assumes entries provided to accept are ordered
* from base entries first and then through the versioned entries in
@@ -158,24 +161,25 @@
// validate the versioned module-info
if (isModuleInfoEntry(entryName)) {
- if (entryName.length() != MODULE_INFO.length())
- checkModuleDescriptor(je);
+ if (!entryName.equals(mdName))
+ checkModuleDescriptor(entryName);
return;
}
// figure out the version and basename from the JarEntry
int version;
String basename;
+ String versionStr = null;;
if (entryName.startsWith(VERSIONS_DIR)) {
- int n = entryName.indexOf("/", vdlen);
+ int n = entryName.indexOf("/", VERSIONS_DIR_LENGTH);
if (n == -1) {
error(formatMsg("error.validator.version.notnumber", entryName));
isValid = false;
return;
}
- String v = entryName.substring(vdlen, n);
+ versionStr = entryName.substring(VERSIONS_DIR_LENGTH, n);
try {
- version = Integer.parseInt(v);
+ version = Integer.parseInt(versionStr);
} catch (NumberFormatException x) {
error(formatMsg("error.validator.version.notnumber", entryName));
isValid = false;
@@ -196,6 +200,11 @@
if (oldVersion != version) {
oldVersion = version;
currentTopLevelName = null;
+ if (md == null && versionStr != null) {
+ // don't have a base module-info.class yet, try to see if
+ // a versioned one exists
+ checkModuleDescriptor(VERSIONS_DIR + versionStr + "/" + MODULE_INFO);
+ }
}
// analyze the entry, keeping key attributes
@@ -308,61 +317,52 @@
return;
}
- private void loadModuleDescriptor() {
- ZipEntry je = jf.getEntry(MODULE_INFO);
- if (je != null) {
- try (InputStream jis = jf.getInputStream(je)) {
- md = ModuleDescriptor.read(jis);
- concealedPkgs = new HashSet<>(md.packages());
- md.exports().stream().map(Exports::source).forEach(concealedPkgs::remove);
- md.opens().stream().map(Opens::source).forEach(concealedPkgs::remove);
- return;
- } catch (Exception x) {
- error(x.getMessage() + " : " + je.getName());
- this.isValid = false;
- }
- }
- md = null;
- concealedPkgs = Collections.emptySet();
- }
-
- private static boolean isPlatformModule(String name) {
- return name.startsWith("java.") || name.startsWith("jdk.");
- }
-
/**
* Checks whether or not the given versioned module descriptor's attributes
- * are valid when compared against the root module descriptor.
+ * are valid when compared against the root/base module descriptor.
*
- * A versioned module descriptor must be identical to the root module
+ * A versioned module descriptor must be identical to the root/base module
* descriptor, with two exceptions:
* - A versioned descriptor can have different non-public `requires`
* clauses of platform ( `java.*` and `jdk.*` ) modules, and
* - A versioned descriptor can have different `uses` clauses, even of
* service types defined outside of the platform modules.
*/
- private void checkModuleDescriptor(JarEntry je) {
- try (InputStream is = jf.getInputStream(je)) {
- ModuleDescriptor root = this.md;
- ModuleDescriptor md = null;
- try {
- md = ModuleDescriptor.read(is);
- } catch (InvalidModuleDescriptorException x) {
- error(x.getMessage());
- isValid = false;
- return;
- }
- if (root == null) {
- this.md = md;
- } else {
- if (!root.name().equals(md.name())) {
+ private void checkModuleDescriptor(String miName) {
+ ZipEntry je = jf.getEntry(miName);
+ if (je != null) {
+ try (InputStream jis = jf.getInputStream(je)) {
+ ModuleDescriptor md = ModuleDescriptor.read(jis);
+ // Initialize the base md if it's not yet. A "base" md can be either the
+ // root module-info.class or the first versioned module-info.class
+ ModuleDescriptor base = this.md;
+
+ if (base == null) {
+ concealedPkgs = new HashSet<>(md.packages());
+ md.exports().stream().map(Exports::source).forEach(concealedPkgs::remove);
+ md.opens().stream().map(Opens::source).forEach(concealedPkgs::remove);
+ // must have the implementation class of the services it 'provides'.
+ if (md.provides().stream().map(Provides::providers)
+ .flatMap(List::stream)
+ .filter(p -> jf.getEntry(toBinaryName(p)) == null)
+ .peek(p -> error(formatMsg("error.missing.provider", p)))
+ .count() != 0) {
+ isValid = false;
+ return;
+ }
+ this.md = md;
+ this.mdName = miName;
+ return;
+ }
+
+ if (!base.name().equals(md.name())) {
error(getMsg("error.validator.info.name.notequal"));
isValid = false;
}
- if (!root.requires().equals(md.requires())) {
- Set<Requires> rootRequires = root.requires();
+ if (!base.requires().equals(md.requires())) {
+ Set<Requires> baseRequires = base.requires();
for (Requires r : md.requires()) {
- if (rootRequires.contains(r))
+ if (baseRequires.contains(r))
continue;
if (r.modifiers().contains(Requires.Modifier.TRANSITIVE)) {
error(getMsg("error.validator.info.requires.transitive"));
@@ -372,7 +372,7 @@
isValid = false;
}
}
- for (Requires r : rootRequires) {
+ for (Requires r : baseRequires) {
Set<Requires> mdRequires = md.requires();
if (mdRequires.contains(r))
continue;
@@ -382,33 +382,37 @@
}
}
}
- if (!root.exports().equals(md.exports())) {
+ if (!base.exports().equals(md.exports())) {
error(getMsg("error.validator.info.exports.notequal"));
isValid = false;
}
- if (!root.opens().equals(md.opens())) {
+ if (!base.opens().equals(md.opens())) {
error(getMsg("error.validator.info.opens.notequal"));
isValid = false;
}
- if (!root.provides().equals(md.provides())) {
+ if (!base.provides().equals(md.provides())) {
error(getMsg("error.validator.info.provides.notequal"));
isValid = false;
}
- if (!root.mainClass().equals(md.mainClass())) {
+ if (!base.mainClass().equals(md.mainClass())) {
error(formatMsg("error.validator.info.manclass.notequal", je.getName()));
isValid = false;
}
- if (!root.version().equals(md.version())) {
+ if (!base.version().equals(md.version())) {
error(formatMsg("error.validator.info.version.notequal", je.getName()));
isValid = false;
}
+ } catch (Exception x) {
+ error(x.getMessage() + " : " + miName);
+ this.isValid = false;
}
- } catch (IOException x) {
- error(x.getMessage());
- isValid = false;
}
}
+ private static boolean isPlatformModule(String name) {
+ return name.startsWith("java.") || name.startsWith("jdk.");
+ }
+
private boolean checkInternalName(String entryName, String basename, String internalName) {
String className = className(basename);
if (internalName.equals(className)) {
--- a/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/JConsole.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/JConsole.java Wed Jul 05 22:52:22 2017 +0200
@@ -128,7 +128,7 @@
hotspotMI.setMnemonic(Resources.getMnemonicInt(Messages.HOTSPOT_MBEANS_ELLIPSIS));
hotspotMI.setAccelerator(KeyStroke.
getKeyStroke(KeyEvent.VK_H,
- InputEvent.CTRL_MASK));
+ InputEvent.CTRL_DOWN_MASK));
hotspotMI.addActionListener(this);
connectionMenu.add(hotspotMI);
@@ -138,7 +138,7 @@
connectMI = new JMenuItem(Messages.NEW_CONNECTION_ELLIPSIS);
connectMI.setMnemonic(Resources.getMnemonicInt(Messages.NEW_CONNECTION_ELLIPSIS));
connectMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
- InputEvent.CTRL_MASK));
+ InputEvent.CTRL_DOWN_MASK));
connectMI.addActionListener(this);
connectionMenu.add(connectMI);
@@ -147,7 +147,7 @@
exitMI = new JMenuItem(Messages.EXIT);
exitMI.setMnemonic(Resources.getMnemonicInt(Messages.EXIT));
exitMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,
- InputEvent.ALT_MASK));
+ InputEvent.ALT_DOWN_MASK));
exitMI.addActionListener(this);
connectionMenu.add(exitMI);
@@ -223,7 +223,7 @@
tileMI = new JMenuItem(Messages.TILE);
tileMI.setMnemonic(Resources.getMnemonicInt(Messages.TILE));
tileMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T,
- InputEvent.CTRL_MASK));
+ InputEvent.CTRL_DOWN_MASK));
tileMI.addActionListener(JConsole.this);
add(tileMI);
--- a/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/VMPanel.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/VMPanel.java Wed Jul 05 22:52:22 2017 +0200
@@ -124,7 +124,9 @@
addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
- if (connectedIconBounds != null && (e.getModifiers() & MouseEvent.BUTTON1_MASK) != 0 && connectedIconBounds.contains(e.getPoint())) {
+ if (connectedIconBounds != null
+ && (e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0
+ && connectedIconBounds.contains(e.getPoint())) {
if (isConnected()) {
userDisconnected = true;
--- a/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/inspector/Utils.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jconsole/share/classes/sun/tools/jconsole/inspector/Utils.java Wed Jul 05 22:52:22 2017 +0200
@@ -438,7 +438,7 @@
public void keyPressed(KeyEvent e) {
// Accept "copy" key strokes
KeyStroke ks = KeyStroke.getKeyStroke(
- e.getKeyCode(), e.getModifiers());
+ e.getKeyCode(), e.getModifiersEx());
JComponent comp = (JComponent) e.getSource();
for (int i = 0; i < 3; i++) {
InputMap im = comp.getInputMap(i);
--- a/jdk/src/jdk.jdi/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jdi/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Defines the Java Debugger Interface.
+ *
+ * @since 9
*/
module jdk.jdi {
requires jdk.attach;
--- a/jdk/src/jdk.jdwp.agent/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jdwp.agent/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Java Debug Wire Protocol.
+ *
+ * @since 9
*/
module jdk.jdwp.agent {
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jimage/resources/jimage.properties Wed Jul 05 22:52:22 2017 +0200
@@ -98,3 +98,4 @@
err.no.jimage=no jimage provided
err.option.unsupported={0} not supported: {1}
err.unknown.option=unknown option: {0}
+err.cannot.create.dir=cannot create directory {0}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Wed Jul 05 22:52:22 2017 +0200
@@ -362,7 +362,7 @@
String module = "/" + entry.moduleName() + "/";
String filename = entry.path().substring(module.length());
- // Remove radical native|config|...
+ // Remove radical lib|config|...
return filename.substring(filename.indexOf('/') + 1);
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/AbstractResourcePoolEntry.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/AbstractResourcePoolEntry.java Wed Jul 05 22:52:22 2017 +0200
@@ -38,7 +38,7 @@
* <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>
+ * {@literal bin|conf|lib}/{dir1}>/.../{dirN}/{file name}</li>
* </ul>
*/
abstract class AbstractResourcePoolEntry implements ResourcePoolEntry {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Wed Jul 05 22:52:22 2017 +0200
@@ -29,6 +29,7 @@
import java.io.PrintWriter;
import java.io.UncheckedIOException;
import java.lang.module.Configuration;
+import java.lang.module.FindException;
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
@@ -232,7 +233,7 @@
return EXIT_OK;
} catch (PluginException | IllegalArgumentException |
- UncheckedIOException |IOException | ResolutionException e) {
+ UncheckedIOException |IOException | FindException | ResolutionException e) {
log.println(taskHelper.getMessage("error.prefix") + " " + e.getMessage());
if (DEBUG) {
e.printStackTrace(log);
@@ -370,7 +371,7 @@
*/
private ModuleFinder modulePathFinder() {
Path[] entries = options.modulePath.toArray(new Path[0]);
- ModuleFinder finder = new ModulePath(Runtime.version(), true, entries);
+ ModuleFinder finder = ModulePath.of(Runtime.version(), true, entries);
if (!options.limitMods.isEmpty()) {
finder = limitFinder(finder, options.limitMods, Collections.emptySet());
}
@@ -388,7 +389,7 @@
Set<String> roots)
{
Path[] entries = paths.toArray(new Path[0]);
- ModuleFinder finder = new ModulePath(Runtime.version(), true, entries);
+ ModuleFinder finder = ModulePath.of(Runtime.version(), true, entries);
// if limitmods is specified then limit the universe
if (!limitMods.isEmpty()) {
@@ -418,9 +419,9 @@
}
Configuration cf = Configuration.empty()
- .resolveRequires(finder,
- ModuleFinder.of(),
- roots);
+ .resolve(finder,
+ ModuleFinder.of(),
+ roots);
// emit warning for modules that end with a digit
cf.modules().stream()
@@ -458,9 +459,9 @@
// resolve all root modules
Configuration cf = Configuration.empty()
- .resolveRequires(finder,
- ModuleFinder.of(),
- roots);
+ .resolve(finder,
+ ModuleFinder.of(),
+ roots);
// module name -> reference
Map<String, ModuleReference> map = new HashMap<>();
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ResourcePoolConfiguration.java Wed Jul 05 22:52:22 2017 +0200
@@ -51,7 +51,7 @@
ModuleDescriptor md = mod.descriptor();
// drop hashes
- ModuleDescriptor.Builder builder = ModuleDescriptor.module(md.name());
+ ModuleDescriptor.Builder builder = ModuleDescriptor.newModule(md.name());
md.requires().stream()
.forEach(builder::requires);
md.exports().stream()
@@ -62,12 +62,7 @@
.forEach(builder::uses);
md.provides().stream()
.forEach(builder::provides);
-
- // build the proper concealed packages
- Set<String> concealed = new HashSet<>(mod.packages());
- md.exports().stream().map(ModuleDescriptor.Exports::source).forEach(concealed::remove);
- md.opens().stream().map(ModuleDescriptor.Opens::source).forEach(concealed::remove);
- concealed.stream().forEach(builder::contains);
+ builder.packages(md.packages());
md.version().ifPresent(builder::version);
md.mainClass().ifPresent(builder::mainClass);
@@ -124,7 +119,7 @@
}
};
- return Configuration.empty().resolveRequires(
+ return Configuration.empty().resolve(
finder, ModuleFinder.of(), nameToModRef.keySet());
}
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Wed Jul 05 22:52:22 2017 +0200
@@ -718,13 +718,13 @@
static Layer createPluginsLayer(List<Path> paths) {
Path[] dirs = paths.toArray(new Path[0]);
- ModuleFinder finder = new ModulePath(Runtime.version(), true, dirs);
+ ModuleFinder finder = ModulePath.of(Runtime.version(), true, dirs);
Configuration bootConfiguration = Layer.boot().configuration();
try {
Configuration cf = bootConfiguration
- .resolveRequiresAndUses(ModuleFinder.of(),
- finder,
- Collections.emptySet());
+ .resolveAndBind(ModuleFinder.of(),
+ finder,
+ Collections.emptySet());
ClassLoader scl = ClassLoader.getSystemClassLoader();
return Layer.boot().defineModulesWithOneLoader(cf, scl);
} catch (Exception ex) {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeVMPlugin.java Wed Jul 05 22:52:22 2017 +0200
@@ -95,9 +95,9 @@
/**
* VM paths:
- * /java.base/native/{architecture}/{server|client|minimal}/{shared lib}
- * e.g.: /java.base/native/amd64/server/libjvm.so
- * /java.base/native/server/libjvm.dylib
+ * /java.base/lib/{architecture}/{server|client|minimal}/{shared lib}
+ * e.g.: /java.base/lib/server/libjvm.so
+ * /java.base/lib/server/libjvm.dylib
*/
private List<ResourcePoolEntry> getVMs(ResourcePoolModule javaBase, String[] jvmlibs) {
List<ResourcePoolEntry> ret = javaBase.entries().filter((t) -> {
@@ -198,17 +198,17 @@
}
case CLIENT: {
target = Jvm.CLIENT;
- exclude = "/java.base/native**server/**,/java.base/native**minimal/**";
+ exclude = "/java.base/lib**server/**,/java.base/lib**minimal/**";
break;
}
case SERVER: {
target = Jvm.SERVER;
- exclude = "/java.base/native**client/**,/java.base/native**minimal/**";
+ exclude = "/java.base/lib**client/**,/java.base/lib**minimal/**";
break;
}
case MINIMAL: {
target = Jvm.MINIMAL;
- exclude = "/java.base/native**server/**,/java.base/native**client/**";
+ exclude = "/java.base/lib**server/**,/java.base/lib**client/**";
break;
}
default: {
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/SystemModulesPlugin.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -46,11 +46,16 @@
import java.util.function.IntSupplier;
import jdk.internal.module.Checks;
+import jdk.internal.module.ClassFileAttributes;
+import jdk.internal.module.ClassFileConstants;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleInfo.Attributes;
import jdk.internal.module.ModuleInfoExtender;
import jdk.internal.module.ModuleResolution;
import jdk.internal.module.SystemModules;
+import jdk.internal.org.objectweb.asm.Attribute;
+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.MethodVisitor;
import jdk.internal.org.objectweb.asm.Opcodes;
@@ -109,6 +114,11 @@
}
@Override
+ public String getArgumentsDescription() {
+ return PluginsResourceBundle.getArgument(NAME);
+ }
+
+ @Override
public void configure(Map<String, String> config) {
String arg = config.get(NAME);
if (arg != null) {
@@ -171,10 +181,11 @@
}
static class ModuleInfo {
+ private final ByteArrayInputStream bain;
private final Attributes attrs;
private final Set<String> packages;
- private final ByteArrayInputStream bain;
private final boolean dropModuleTarget;
+ private final boolean addModulePackages;
private ModuleDescriptor descriptor; // may be different that the original one
ModuleInfo(byte[] bytes, Set<String> packages, boolean dropModuleTarget)
@@ -182,15 +193,21 @@
{
this.bain = new ByteArrayInputStream(bytes);
this.packages = packages;
-
this.attrs = jdk.internal.module.ModuleInfo.read(bain, null);
+ // If ModulePackages attribute is present, the packages from this
+ // module descriptor returns the packages in that attribute.
+ // If it's not present, ModuleDescriptor::packages only contains
+ // the exported and open packages from module-info.class
this.descriptor = attrs.descriptor();
if (descriptor.isAutomatic()) {
throw new InternalError("linking automatic module is not supported");
}
+ // add ModulePackages attribute if this module contains some packages
+ // and ModulePackages is not present
+ this.addModulePackages = packages.size() > 0 && !hasModulePackages();
+ // drop target attribute only if any OS property is present
if (dropModuleTarget) {
- // drop target attribute only if any OS property is present
this.dropModuleTarget =
descriptor.osName().isPresent() ||
descriptor.osArch().isPresent() ||
@@ -276,53 +293,71 @@
}
}
+ boolean hasModulePackages() throws IOException {
+ Set<String> attrTypes = new HashSet<>();
+ ClassVisitor cv = new ClassVisitor(Opcodes.ASM5) {
+ @Override
+ public void visitAttribute(Attribute attr) {
+ attrTypes.add(attr.type);
+ }
+ };
+
+ // prototype of attributes that should be parsed
+ Attribute[] attrs = new Attribute[] {
+ new ClassFileAttributes.ModulePackagesAttribute()
+ };
+
+ try (InputStream in = getInputStream()) {
+ // parse module-info.class
+ ClassReader cr = new ClassReader(in);
+ cr.accept(cv, attrs, 0);
+ return attrTypes.contains(ClassFileConstants.MODULE_PACKAGES);
+ }
+ }
+
/**
* Returns true if module-info.class should be written
* 1. add ModulePackages attribute if not present; or
* 2. drop ModuleTarget attribute except java.base
*/
boolean shouldRewrite() {
- return shouldAddModulePackages() || shouldDropModuleTarget();
- }
-
- boolean shouldAddModulePackages() {
- return (descriptor.packages().isEmpty() && packages.size() > 0);
- }
-
- boolean shouldDropModuleTarget() {
- return dropModuleTarget &&
- (descriptor.osName().isPresent() ||
- descriptor.osArch().isPresent() ||
- descriptor.osVersion().isPresent());
+ return addModulePackages || dropModuleTarget;
}
/**
* Returns the bytes for the module-info.class with ModulePackages
- * if it contains at least one package
+ * attribute added and/or with ModuleTarget attribute dropped.
*/
byte[] getBytes() throws IOException {
- bain.reset();
-
- // add ModulePackages attribute if not exist
- if (shouldRewrite()) {
- ModuleInfoRewriter rewriter = new ModuleInfoRewriter(bain);
- if (shouldAddModulePackages()) {
- rewriter.addModulePackages(packages);
+ try (InputStream in = getInputStream()) {
+ if (shouldRewrite()) {
+ ModuleInfoRewriter rewriter = new ModuleInfoRewriter(in);
+ if (addModulePackages) {
+ rewriter.addModulePackages(packages);
+ }
+ if (dropModuleTarget) {
+ rewriter.dropModuleTarget();
+ }
+ // rewritten module descriptor
+ byte[] bytes = rewriter.getBytes();
+ try (ByteArrayInputStream bain = new ByteArrayInputStream(bytes)) {
+ this.descriptor = ModuleDescriptor.read(bain);
+ }
+ return bytes;
+ } else {
+ return in.readAllBytes();
}
- if (shouldDropModuleTarget()) {
- rewriter.dropModuleTarget();
- }
- // rewritten module descriptor
- byte[] bytes = rewriter.getBytes();
- try (ByteArrayInputStream bain = new ByteArrayInputStream(bytes)) {
- this.descriptor = ModuleDescriptor.read(bain);
- }
- return bytes;
- } else {
- return bain.readAllBytes();
}
}
+ /*
+ * Returns the input stream of the module-info.class
+ */
+ InputStream getInputStream() {
+ bain.reset();
+ return bain;
+ }
+
class ModuleInfoRewriter extends ByteArrayOutputStream {
final ModuleInfoExtender extender;
ModuleInfoRewriter(InputStream in) {
@@ -771,9 +806,12 @@
if (md.isOpen()) {
setModuleBit("open", true);
}
- if (md.isSynthetic()) {
+ if (md.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC)) {
setModuleBit("synthetic", true);
}
+ if (md.modifiers().contains(ModuleDescriptor.Modifier.MANDATED)) {
+ setModuleBit("mandated", true);
+ }
}
/*
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Wed Jul 05 22:52:22 2017 +0200
@@ -62,7 +62,7 @@
exclude-files.argument=<pattern-list> of files to exclude
exclude-files.description=\
-Specify files to exclude. e.g.: **.java,glob:/java.base/native/client/**
+Specify files to exclude. e.g.: **.java,glob:/java.base/lib/client/**
exclude-resources.argument=<pattern-list> resources to exclude
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Wed Jul 05 22:52:22 2017 +0200
@@ -34,6 +34,7 @@
import java.io.PrintWriter;
import java.io.UncheckedIOException;
import java.lang.module.Configuration;
+import java.lang.module.FindException;
import java.lang.module.ModuleReader;
import java.lang.module.ModuleReference;
import java.lang.module.ModuleFinder;
@@ -851,8 +852,8 @@
// get a resolved module graph
Configuration config = null;
try {
- config = Configuration.empty().resolveRequires(system, finder, roots);
- } catch (ResolutionException e) {
+ config = Configuration.empty().resolve(system, finder, roots);
+ } catch (FindException | ResolutionException e) {
throw new CommandException("err.module.resolution.fail", e.getMessage());
}
@@ -1392,7 +1393,7 @@
options.legalNotices = getLastElement(opts.valuesOf(legalNotices));
if (opts.has(modulePath)) {
Path[] dirs = getLastElement(opts.valuesOf(modulePath)).toArray(new Path[0]);
- options.moduleFinder = new ModulePath(Runtime.version(), true, dirs);
+ options.moduleFinder = ModulePath.of(Runtime.version(), true, dirs);
}
if (opts.has(moduleVersion))
options.moduleVersion = getLastElement(opts.valuesOf(moduleVersion));
--- a/jdk/src/jdk.security.auth/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.security.auth/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,6 +26,8 @@
/**
* Contains the implementation of the javax.security.auth.* interfaces and
* various authentication modules.
+ *
+ * @since 9
*/
module jdk.security.auth {
requires transitive java.naming;
--- a/jdk/src/jdk.security.jgss/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/src/jdk.security.jgss/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,6 +26,8 @@
/**
* Defines Java extensions to the GSS-API and an implementation of the SASL
* GSSAPI mechanism.
+ *
+ * @since 9
*/
module jdk.security.jgss {
requires transitive java.security.jgss;
--- a/jdk/test/ProblemList.txt Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/ProblemList.txt Wed Jul 05 22:52:22 2017 +0200
@@ -251,12 +251,11 @@
tools/pack200/CommandLineTests.java 8059906 generic-all
-tools/launcher/ArgsEnvVar.java 8173712 generic-all
tools/launcher/FXLauncherTest.java 8068049 linux-all,macosx-all
-tools/jimage/JImageExtractTest.java 8169713 generic-all
-tools/jimage/JImageListTest.java 8169713 generic-all
-tools/jimage/JImageVerifyTest.java 8169713 generic-all
+tools/jimage/JImageExtractTest.java 8170120 generic-all
+tools/jimage/JImageListTest.java 8170120 generic-all
+tools/jimage/JImageVerifyTest.java 8170120 generic-all
tools/jlink/multireleasejar/JLinkMultiReleaseJarTest.java 8169971 windows-x64
@@ -267,7 +266,7 @@
com/sun/jdi/RedefineImplementor.sh 8004127 generic-all
-com/sun/jdi/JdbMethodExitTest.sh 6902121 generic-all
+com/sun/jdi/JdbMethodExitTest.sh 8171483 generic-all
com/sun/jdi/RepStep.java 8043571 generic-all
@@ -296,6 +295,8 @@
sun/tools/jcmd/TestJcmdSanity.java 8031482 windows-all
+sun/tools/jstat/jstatClassloadOutput1.sh 8173942 generic-all
+
sun/jvmstat/monitor/MonitoredVm/MonitorVmStartTerminate.java 8057732 generic-all
demo/jvmti/compiledMethodLoad/CompiledMethodLoadTest.java 8151899 generic-all
@@ -308,6 +309,6 @@
javax/rmi/PortableRemoteObject/8146975/RmiIiopReturnValueTest.java 8169737 linux-all
-javax/xml/ws/clientjar/TestWsImport.java 8170370 generic-all
+javax/xml/ws/clientjar/TestWsImport.java 8173317 generic-all
############################################################################
--- a/jdk/test/TEST.groups Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/TEST.groups Wed Jul 05 22:52:22 2017 +0200
@@ -273,6 +273,7 @@
jdk/internal/jline \
com/sun/jndi \
com/sun/corba \
+ org/omg/CORBA \
lib/testlibrary \
sample
--- a/jdk/test/com/oracle/security/ucrypto/TestAES.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/com/oracle/security/ucrypto/TestAES.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 8014374 8167512
+ * @bug 7088989 8014374 8167512 8173708
* @summary Ensure the AES ciphers of OracleUcrypto provider works correctly
* @key randomness
* @run main TestAES
@@ -177,6 +177,12 @@
k += c.doFinal(eout, firstPartLen+1, eout.length - firstPartLen - 1, dout, k);
if (!checkArrays(in, in.length, dout, k)) testPassed = false;
} catch(Exception ex) {
+ if (ex instanceof BadPaddingException &&
+ algos[i].indexOf("CFB128") != -1 &&
+ p.getName().equals("OracleUcrypto")) {
+ System.out.println("Ignore due to a pre-S11.3 bug: " + ex);
+ continue;
+ }
System.out.println("Unexpected Exception: " + algos[i]);
ex.printStackTrace();
testPassed = false;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/com/sun/java/swing/plaf/windows/Test8173145.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8173145
+ @summary Menu is activated after using mnemonic Alt/Key combination
+ @modules java.desktop/com.sun.java.swing.plaf.windows
+ @run main Test8173145
+*/
+
+import java.awt.*;
+import java.awt.event.KeyEvent;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.*;
+
+public class Test8173145 {
+
+ private volatile static JButton btn;
+ private volatile static boolean uiCreated;
+
+ public static void main(String[] args) throws InvocationTargetException, InterruptedException, AWTException {
+ SwingUtilities.invokeAndWait(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ uiCreated = createGUI();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ if (uiCreated) {
+ test();
+ } else {
+ //no windows l&f, skip the test
+ }
+ }
+
+ private static void test() {
+ final Robot robot;
+ try {
+ robot = new Robot();
+ } catch (AWTException e) {
+ throw new RuntimeException(e);
+ }
+ robot.setAutoDelay(100);
+ robot.waitForIdle();
+
+ robot.keyPress(KeyEvent.VK_ALT);
+ robot.keyPress(KeyEvent.VK_M);
+ robot.keyRelease(KeyEvent.VK_M);
+ robot.keyRelease(KeyEvent.VK_ALT);
+
+ Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
+
+ if (focusOwner != btn) {
+ throw new RuntimeException("Wrong focus owner");
+ }
+ }
+
+ private static boolean createGUI() {
+ try {
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+ } catch (Exception e) {
+ return false;
+ }
+ JFrame f = new JFrame();
+
+ JPanel panel = new JPanel();
+ btn = new JButton("Mmmmm");
+ btn.setMnemonic(KeyEvent.VK_M);
+ btn.setDisplayedMnemonicIndex(0);
+ panel.add(btn);
+
+ JTextField tf = new JTextField();
+ tf.setColumns(10);
+ panel.add(tf);
+
+ f.setJMenuBar(getMenuBar());
+ f.add(panel);
+ f.pack();
+ f.setVisible(true);
+ tf.requestFocus();
+ return true;
+ }
+
+ static JMenuBar getMenuBar() {
+ JMenuBar menuBar;
+ JMenu menu;
+
+ menuBar = new JMenuBar();
+
+ menu = new JMenu("Menu");
+ menuBar.add(menu);
+
+ JMenuItem mi = new JMenuItem("test");
+ menu.add(mi);
+
+ return menuBar;
+ }
+}
--- a/jdk/test/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/awt/Mixing/AWT_Mixing/OpaqueOverlapping.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,6 @@
*/
-import com.sun.awt.AWTUtilities;
import java.awt.Frame;
import java.awt.Panel;
import java.awt.Point;
@@ -44,11 +43,10 @@
/*
* @test
* @key headful
- * @bug 6776743
+ * @bug 6776743 8173409
* @summary Opaque overlapping test for each AWT component
* @library /java/awt/patchlib ../../regtesthelpers
- * @modules java.desktop/com.sun.awt
- * java.desktop/java.awt.peer
+ * @modules java.desktop/java.awt.peer
* java.desktop/sun.awt
* @build java.desktop/java.awt.Helper
* @build Util
@@ -134,12 +132,10 @@
// flag value.
for (int i = 0; i < 9; ++i) {
if (i == 3) {
- AWTUtilities.setComponentMixingCutoutShape(light,
- new Rectangle());
+ light.setMixingCutoutShape(new Rectangle());
}
if (i == 6) {
- AWTUtilities.setComponentMixingCutoutShape(light,
- null);
+ light.setMixingCutoutShape(null);
}
robot.mousePress(InputEvent.BUTTON1_MASK);
--- a/jdk/test/java/awt/Mixing/OpaqueTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/awt/Mixing/OpaqueTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -24,11 +24,10 @@
/*
@test
@key headful
- @bug 4811096
+ @bug 4811096 8173409
@summary Tests whether opaque and non-opaque components mix correctly
@author anthony.petrov@...: area=awt.mixing
@library ../regtesthelpers
- @modules java.desktop/com.sun.awt
@build Util
@run main OpaqueTest
*/
@@ -44,7 +43,6 @@
import java.awt.event.*;
import javax.swing.*;
import test.java.awt.regtesthelpers.Util;
-import com.sun.awt.AWTUtilities;
@@ -125,12 +123,10 @@
// flag value.
for (int i = 0; i < 9; ++i) {
if (i == 3) {
- AWTUtilities.setComponentMixingCutoutShape(light,
- new Rectangle());
+ light.setMixingCutoutShape(new Rectangle());
}
if (i == 6) {
- AWTUtilities.setComponentMixingCutoutShape(light,
- null);
+ light.setMixingCutoutShape(null);
}
robot.mousePress(InputEvent.BUTTON1_MASK);
--- a/jdk/test/java/awt/jdk/TestJDKAWTUtils.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +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.
- */
-
-/*
- * @test
- * @bug 8167126
- */
-import java.awt.BorderLayout;
-import java.awt.Font;
-import java.awt.Rectangle;
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JPanel;
-import javax.swing.SwingUtilities;
-
-public class TestJDKAWTUtils {
-
- static JFrame f;
- public static void main(String[] args) throws Exception {
-
- SwingUtilities.invokeAndWait(() -> {
- f = new JFrame("test");
- JPanel p = new JPanel();
- JButton b = new JButton("Hello");
- b.setFont(new Font(Font.DIALOG, Font.PLAIN, 80));
- p.setLayout(new BorderLayout());
- p.add("Center", b);
- f.getContentPane().add(p);
- f.pack();
- f.setVisible(true);
- Rectangle r = new Rectangle(0, 0, 50, 50);
- jdk.awt.AWTUtils.setComponentMixingCutoutShape(b, r);
- });
- Thread.sleep(2000);
- SwingUtilities.invokeAndWait(() -> f.dispose());
- }
-}
--- a/jdk/test/java/awt/print/PrinterJob/PrintAttributeUpdateTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/awt/print/PrinterJob/PrintAttributeUpdateTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 8042713
+ @bug 8042713 8170578
@summary Print Dialog does not update attribute set with page range
@run main/manual PrintAttributeUpdateTest
*/
--- a/jdk/test/java/io/FilePermission/ReadFileOnPath.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/io/FilePermission/ReadFileOnPath.java Wed Jul 05 22:52:22 2017 +0200
@@ -57,7 +57,7 @@
"module-info.class", "base", "p/App.class", "p/child");
// exploded module
- test("--module-path", "modules", "-m", "m/p.App", "SS+++++");
+ test("--module-path", "modules", "-m", "m/p.App", "SS++++0");
// module in jar
test("--module-path", "new.jar", "-m", "m/p.App", "SSSS++0");
--- a/jdk/test/java/lang/Class/forName/modules/TestLayer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/Class/forName/modules/TestLayer.java Wed Jul 05 22:52:22 2017 +0200
@@ -46,9 +46,9 @@
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
Configuration parent = Layer.boot().configuration();
- Configuration cf = parent.resolveRequiresAndUses(ModuleFinder.of(),
- finder,
- modules);
+ Configuration cf = parent.resolveAndBind(ModuleFinder.of(),
+ finder,
+ modules);
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, scl);
--- a/jdk/test/java/lang/Class/forName/modules/src/m3/p3/NoAccess.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/Class/forName/modules/src/m3/p3/NoAccess.java Wed Jul 05 22:52:22 2017 +0200
@@ -50,9 +50,9 @@
Layer bootLayer = Layer.boot();
Configuration parent = bootLayer.configuration();
- Configuration cf = parent.resolveRequiresAndUses(finder,
- ModuleFinder.of(),
- Set.of("m1", "m2"));
+ Configuration cf = parent.resolveAndBind(finder,
+ ModuleFinder.of(),
+ Set.of("m1", "m2"));
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = bootLayer.defineModulesWithManyLoaders(cf, scl);
--- a/jdk/test/java/lang/Class/getPackageName/Basic.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/Class/getPackageName/Basic.java Wed Jul 05 22:52:22 2017 +0200
@@ -154,8 +154,8 @@
return new Object[][] {
{ Basic.class, TEST_PACKAGE },
- { Basic[].class, null },
- { Basic[][].class, null },
+ { Basic[].class, TEST_PACKAGE },
+ { Basic[][].class, TEST_PACKAGE },
{ getNestedClass1(), TEST_PACKAGE },
{ getNestedClass2(), TEST_PACKAGE },
@@ -174,14 +174,14 @@
{ getAnonymousClass6(), TEST_PACKAGE },
{ Object.class, "java.lang" },
- { Object[].class, null },
- { Object[][].class, null },
+ { Object[].class, "java.lang" },
+ { Object[][].class, "java.lang" },
- { int.class, null },
- { int[].class, null },
- { int[][].class, null },
+ { int.class, "java.lang" },
+ { int[].class, "java.lang" },
+ { int[][].class, "java.lang" },
- { void.class, null },
+ { void.class, "java.lang" },
};
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/securityManager/ClassLoaderTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,297 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8168423
+ * @summary Different types of ClassLoader running with(out) SecurityManager and
+ * (in)valid security policy file.
+ * @library /lib/testlibrary
+ * @modules java.base/jdk.internal.module
+ * @build JarUtils CompilerUtils
+ * @run main/timeout=240 ClassLoaderTest
+ */
+import java.io.File;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.Map;
+import java.util.HashMap;
+import java.lang.module.ModuleDescriptor;
+import jdk.internal.module.ModuleInfoWriter;
+import jdk.testlibrary.ProcessTools;
+
+public class ClassLoaderTest {
+
+ private static final String SRC = System.getProperty("test.src");
+ private static final Path CL_SRC = Paths.get(SRC, "TestClassLoader.java");
+ private static final Path C_SRC = Paths.get(SRC, "TestClient.java");
+ private static final Path CL_BIN = Paths.get("classes", "clbin");
+ private static final Path C_BIN = Paths.get("classes", "cbin");
+ private static final Path ARTIFACT_DIR = Paths.get("jars");
+ private static final Path VALID_POLICY = Paths.get(SRC, "valid.policy");
+ private static final Path INVALID_POLICY
+ = Paths.get(SRC, "malformed.policy");
+ private static final Path NO_POLICY = null;
+ private static final String LOCALE = "-Duser.language=en -Duser.region=US";
+ /*
+ * Here is the naming convention followed for each jar.
+ * cl.jar - Regular custom class loader jar.
+ * mcl.jar - Modular custom class loader jar.
+ * c.jar - Regular client jar.
+ * mc.jar - Modular client jar.
+ * amc.jar - Modular client referring automated custom class loader jar.
+ */
+ private static final Path CL_JAR = ARTIFACT_DIR.resolve("cl.jar");
+ private static final Path MCL_JAR = ARTIFACT_DIR.resolve("mcl.jar");
+ private static final Path C_JAR = ARTIFACT_DIR.resolve("c.jar");
+ private static final Path MC_JAR = ARTIFACT_DIR.resolve("mc.jar");
+ private static final Path AMC_JAR = ARTIFACT_DIR.resolve("amc.jar");
+ private static final Map<String, String> MSG_MAP = new HashMap<>();
+
+ static {
+ // This mapping help process finding expected message based
+ // on the key passed as argument while executing java command.
+ MSG_MAP.put("MissingModule", "Module cl not found, required by mc");
+ MSG_MAP.put("ErrorPolicy", "java.security.policy: error parsing file");
+ MSG_MAP.put(
+ "SystemCL", "jdk.internal.loader.ClassLoaders$AppClassLoader");
+ MSG_MAP.put("CustomCL", "cl.TestClassLoader");
+ }
+
+ public static void main(String[] args) throws Exception {
+
+ // Generates regular and modular jars before start processing it.
+ setUp();
+ processForEachPolicyFile();
+ }
+
+ /**
+ * Test cases are based on the following logic,
+ * for (policyFile : {"NO_POLICY", "VALID", "MALFORMED"}) {
+ * for (classLoader : {"SystemClassLoader", "CustomClassLoader"}){
+ * for (clientModule : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
+ * for (classLoaderModule : {"NAMED", "AUTOMATIC", "UNNAMED"}) {
+ * Create and run java command for each possible Test case
+ * }
+ * }
+ * }
+ * }
+ */
+ private static void processForEachPolicyFile() throws Exception {
+
+ final String regCLloc = CL_JAR.toFile().getAbsolutePath();
+ final String modCLloc = MCL_JAR.toFile().getAbsolutePath();
+ final String regCloc = C_JAR.toFile().getAbsolutePath();
+ final String modCloc = MC_JAR.toFile().getAbsolutePath();
+ final String autoModCloc = AMC_JAR.toFile().getAbsolutePath();
+ final String separator = File.pathSeparator;
+
+ for (Path policy
+ : new Path[]{NO_POLICY, VALID_POLICY, INVALID_POLICY}) {
+ final String policyFile = (policy != null)
+ ? policy.toFile().getAbsolutePath() : null;
+ final boolean malformedPolicy
+ = (policy == null) ? false : policy.equals(INVALID_POLICY);
+
+ for (boolean useSCL : new boolean[]{true, false}) {
+ final String clVmArg = (useSCL) ? ""
+ : "-Djava.system.class.loader=cl.TestClassLoader";
+ final String autoAddModArg
+ = (useSCL) ? "" : "--add-modules=cl";
+ final String addmodArg = (useSCL) ? "" : "--add-modules=mcl";
+ final String sMArg = (policy != null) ? String.format(
+ "-Djava.security.manager -Djava.security.policy=%s",
+ policyFile) : "";
+ final String smMsg = (policy != null) ? "With SecurityManager"
+ : "Without SecurityManager";
+ final String expectedResult = ((!malformedPolicy)
+ ? ((useSCL) ? "PASS SystemCL" : "PASS CustomCL")
+ : "FAIL ErrorPolicy");
+
+ // NAMED-NAMED, NAMED-AUTOMATIC, NAMED-UNNAMED
+ System.out.printf("Case:- Modular Client and %s %s%n",
+ ((useSCL) ? "SystemClassLoader"
+ : "Modular CustomClassLoader"), smMsg);
+ execute(new String[]{String.format(
+ "--module-path %s%s%s %s %s %s -m mc/c.TestClient",
+ modCloc, separator, modCLloc, LOCALE, clVmArg, sMArg),
+ expectedResult});
+ System.out.printf("Case:- Modular Client and %s %s%n", ((useSCL)
+ ? "SystemClassLoader"
+ : "Automatic modular CustomClassLoader"), smMsg);
+ execute(new String[]{String.format(
+ "--module-path %s%s%s %s %s %s -m mc/c.TestClient",
+ autoModCloc, separator, regCLloc, LOCALE, clVmArg, sMArg),
+ expectedResult});
+ System.out.printf("Case:- Modular Client and %s %s%n", ((useSCL)
+ ? "SystemClassLoader"
+ : "Unknown modular CustomClassLoader"), smMsg);
+ execute(new String[]{String.format(
+ "--module-path %s -cp %s %s %s %s -m mc/c.TestClient",
+ autoModCloc, regCLloc, LOCALE, clVmArg, sMArg),
+ "FAIL MissingModule"});
+
+ // AUTOMATIC-NAMED, AUTOMATIC-AUTOMATIC, AUTOMATIC-UNNAMED
+ System.out.printf("Case:- Automated modular Client and %s %s%n",
+ ((useSCL) ? "SystemClassLoader"
+ : "Modular CustomClassLoader"), smMsg);
+ execute(new String[]{String.format(
+ "--module-path %s%s%s %s %s %s %s -m c/c.TestClient",
+ regCloc, separator, modCLloc, addmodArg, LOCALE, clVmArg,
+ sMArg), expectedResult});
+ System.out.printf("Case:- Automated modular Client and %s %s%n",
+ ((useSCL) ? "SystemClassLoader"
+ : "Automatic modular CustomClassLoader"),
+ smMsg);
+ execute(new String[]{String.format(
+ "--module-path %s%s%s %s %s %s %s -m c/c.TestClient",
+ regCloc, separator, regCLloc, autoAddModArg, LOCALE,
+ clVmArg, sMArg), expectedResult});
+ System.out.printf("Case:- Automated modular Client and %s %s%n",
+ ((useSCL) ? "SystemClassLoader"
+ : "Unknown modular CustomClassLoader"), smMsg);
+ execute(new String[]{String.format(
+ "--module-path %s -cp %s %s %s %s -m c/c.TestClient",
+ regCloc, regCLloc, LOCALE, clVmArg, sMArg),
+ expectedResult});
+
+ // UNNAMED-NAMED, UNNAMED-AUTOMATIC, UNNAMED-UNNAMED
+ System.out.printf("Case:- Unknown modular Client and %s %s%n",
+ ((useSCL) ? "SystemClassLoader"
+ : "Modular CustomClassLoader"), smMsg);
+ execute(new String[]{String.format(
+ "-cp %s --module-path %s %s %s %s %s c.TestClient",
+ regCloc, modCLloc, addmodArg, LOCALE, clVmArg, sMArg),
+ expectedResult});
+ System.out.printf("Case:- Unknown modular Client and %s %s%n",
+ ((useSCL) ? "SystemClassLoader"
+ : "Automatic modular CustomClassLoader"),
+ smMsg);
+ execute(new String[]{String.format(
+ "-cp %s --module-path %s %s %s %s %s c.TestClient",
+ regCloc, regCLloc, autoAddModArg, LOCALE, clVmArg, sMArg),
+ expectedResult});
+ System.out.printf("Case:- Unknown modular Client and %s %s%n",
+ ((useSCL) ? "SystemClassLoader"
+ : "Unknown modular CustomClassLoader"), smMsg);
+ execute(new String[]{String.format(
+ "-cp %s%s%s %s %s %s c.TestClient", regCloc, separator,
+ regCLloc, LOCALE, clVmArg, sMArg), expectedResult});
+
+ // Regular jars in module-path and Modular jars in class-path.
+ System.out.printf("Case:- Regular Client and %s "
+ + "inside --module-path %s.%n", ((useSCL)
+ ? "SystemClassLoader"
+ : "Unknown modular CustomClassLoader"), smMsg);
+ execute(new String[]{String.format(
+ "--module-path %s%s%s %s %s %s %s -m c/c.TestClient",
+ regCloc, separator, regCLloc, autoAddModArg, LOCALE,
+ clVmArg, sMArg), expectedResult});
+ System.out.printf("Case:- Modular Client and %s in -cp %s%n",
+ ((useSCL) ? "SystemClassLoader"
+ : "Modular CustomClassLoader"), smMsg);
+ execute(new String[]{String.format(
+ "-cp %s%s%s %s %s %s c.TestClient", modCloc, separator,
+ modCLloc, LOCALE, clVmArg, sMArg), expectedResult});
+ }
+ }
+ }
+
+ /**
+ * Execute with command arguments and process the result.
+ */
+ private static void execute(String[] args) throws Exception {
+
+ String status = null;
+ String msgKey = null;
+ if ((args != null && args.length > 1)) {
+ String[] secArgs = args[1].split("\\s+");
+ status = (secArgs.length > 0) ? secArgs[0] : null;
+ msgKey = (secArgs.length > 1) ? secArgs[1] : null;
+ }
+ String out = ProcessTools.executeTestJvm(args[0].split("\\s+"))
+ .getOutput();
+ // Handle response.
+ if ((status != null && "PASS".equals(status) && msgKey != null
+ && out.contains(MSG_MAP.get(msgKey)))) {
+ System.out.printf("PASS: Expected Result: %s.%n",
+ MSG_MAP.get(msgKey));
+ } else if ((status != null && "FAIL".equals(status) && msgKey != null
+ && out.contains(MSG_MAP.get(msgKey)))) {
+ System.out.printf("PASS: Expected Failure: %s.%n",
+ MSG_MAP.get(msgKey));
+ } else if (out.contains("Exception") || out.contains("Error")) {
+ System.out.printf("OUTPUT: %s", out);
+ throw new RuntimeException("FAIL: Unknown Exception.");
+ } else {
+ System.out.printf("OUTPUT: %s", out);
+ throw new RuntimeException("FAIL: Unknown Test case found");
+ }
+ }
+
+ /**
+ * Creates regular/modular jar files for TestClient and TestClassLoader.
+ */
+ private static void setUp() throws Exception {
+
+ boolean compiled = CompilerUtils.compile(CL_SRC, CL_BIN);
+ compiled &= CompilerUtils.compile(C_SRC, C_BIN);
+ if (!compiled) {
+ throw new RuntimeException("Test Setup failed.");
+ }
+ // Generate regular jar files for TestClient and TestClassLoader
+ JarUtils.createJarFile(CL_JAR, CL_BIN);
+ JarUtils.createJarFile(C_JAR, C_BIN);
+ // Generate modular jar files for TestClient and TestClassLoader with
+ // their corresponding ModuleDescriptor.
+ Files.copy(CL_JAR, MCL_JAR, StandardCopyOption.REPLACE_EXISTING);
+ updateModuleDescr(MCL_JAR, ModuleDescriptor.newModule("mcl")
+ .exports("cl").requires("java.base").build());
+ Files.copy(C_JAR, MC_JAR, StandardCopyOption.REPLACE_EXISTING);
+ updateModuleDescr(MC_JAR, ModuleDescriptor.newModule("mc")
+ .exports("c").requires("java.base").requires("mcl").build());
+ Files.copy(C_JAR, AMC_JAR, StandardCopyOption.REPLACE_EXISTING);
+ updateModuleDescr(AMC_JAR, ModuleDescriptor.newModule("mc")
+ .exports("c").requires("java.base").requires("cl").build());
+ }
+
+ /**
+ * Update regular jars and include module-info.class inside it to make
+ * modular jars.
+ */
+ private static void updateModuleDescr(Path jar, ModuleDescriptor mDescr)
+ throws Exception {
+ if (mDescr != null) {
+ Path dir = Files.createTempDirectory("tmp");
+ Path mi = dir.resolve("module-info.class");
+ try (OutputStream out = Files.newOutputStream(mi)) {
+ ModuleInfoWriter.write(mDescr, out);
+ }
+ System.out.format("Adding 'module-info.class' to jar '%s'%n", jar);
+ JarUtils.updateJarFile(jar, dir);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/securityManager/TestClassLoader.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 cl;
+
+public class TestClassLoader extends ClassLoader {
+
+ /**
+ * This constructor is used to set the parent ClassLoader
+ */
+ public TestClassLoader(ClassLoader parent) {
+ super(parent);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/securityManager/TestClient.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 c;
+
+public class TestClient {
+
+ public static void main(String[] args) {
+
+ // Initialize policy file.
+ System.getProperty("test.src");
+ System.out.printf("ContextClassLoader: %s%n",
+ Thread.currentThread().getContextClassLoader().toString());
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/securityManager/malformed.policy Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,4 @@
+grant {
+ xyz;
+ permission java.util.PropertyPermission "test.src", "read";
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/ClassLoader/securityManager/valid.policy Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,4 @@
+grant codeBase "file:./jars/*" {
+ permission java.lang.RuntimePermission "createClassLoader";
+ permission java.util.PropertyPermission "test.src", "read";
+};
\ No newline at end of file
--- a/jdk/test/java/lang/SecurityManager/CheckPackageAccess.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/SecurityManager/CheckPackageAccess.java Wed Jul 05 22:52:22 2017 +0200
@@ -33,6 +33,7 @@
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
+import java.lang.reflect.Layer;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
@@ -80,25 +81,33 @@
}
void test() {
- System.out.println("Testing module " + moduleName);
+ final boolean isModulePresent =
+ Layer.boot().findModule(moduleName).isPresent();
+ System.out.format("Testing module: %1$s. Module is%2$s present.\n",
+ moduleName, isModulePresent ? "" : " NOT");
- // access to exported pkg should pass
- testNonRestricted(exports);
+ if (isModulePresent) {
- // access to opened pkg should pass
- opens.ifPresent(Test::testNonRestricted);
+ // access to exported pkg should pass
+ testNonRestricted(exports);
+
+ // access to opened pkg should pass
+ opens.ifPresent(Test::testNonRestricted);
- // access to concealed pkg should fail
- testRestricted(conceals);
+ // access to concealed pkg should fail
+ testRestricted(conceals);
- // access to qualified export pkg should fail
- qualExports.ifPresent(Test::testRestricted);
+ // access to qualified export pkg should fail
+ qualExports.ifPresent(Test::testRestricted);
- // access to qualified open pkg should fail
- qualOpens.ifPresent(Test::testRestricted);
+ // access to qualified open pkg should fail
+ qualOpens.ifPresent(Test::testRestricted);
- // access to qualified opened pkg that is also exported should pass
- qualOpensAndExports.ifPresent(Test::testNonRestricted);
+ // access to qualified opened pkg that is also exported should pass
+ qualOpensAndExports.ifPresent(Test::testNonRestricted);
+ } else {
+ System.out.println("Skipping tests for module.");
+ }
}
private static void testRestricted(String pkg) {
--- a/jdk/test/java/lang/StackTraceElement/WithClassLoaderName.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/StackTraceElement/WithClassLoaderName.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 @@
* @bug 6479237
* @summary Basic test StackTraceElement with class loader names
* @library lib /lib/testlibrary
+ * @modules jdk.compiler
* @build m1/* WithClassLoaderName
* @run main/othervm m1/com.app.Main
* @run main/othervm WithClassLoaderName
--- a/jdk/test/java/lang/StackWalker/Basic.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/StackWalker/Basic.java Wed Jul 05 22:52:22 2017 +0200
@@ -23,18 +23,21 @@
/*
* @test
- * @bug 8140450
+ * @bug 8140450 8173898
* @summary Basic test for the StackWalker::walk method
* @run testng Basic
*/
import java.lang.StackWalker.StackFrame;
import java.util.List;
+import java.util.Objects;
import java.util.stream.Collectors;
+import java.util.stream.Stream;
import static java.lang.StackWalker.Option.*;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
+import static org.testng.Assert.*;
public class Basic {
private static boolean verbose = false;
@@ -60,6 +63,17 @@
}
}
+ @Test
+ public static void testWalkFromConstructor() throws Exception {
+ System.out.println("testWalkFromConstructor:");
+ List<String> found = ((ConstructorNewInstance)ConstructorNewInstance.class.getMethod("create")
+ .invoke(null)).collectedFrames();
+ assertEquals(List.of(ConstructorNewInstance.class.getName()+"::<init>",
+ ConstructorNewInstance.class.getName()+"::create",
+ Basic.class.getName()+"::testWalkFromConstructor"),
+ found);
+ }
+
private final int depth;
Basic(int depth) {
this.depth = depth;
@@ -77,6 +91,47 @@
assertEquals(limit, frames.size());
}
+ static class ConstructorNewInstance {
+ static final StackWalker walker =
+ StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+ List<String> testFramesOrReflectionFrames;
+ public ConstructorNewInstance() {
+ testFramesOrReflectionFrames = walker.walk(this::parse);
+ }
+ public List<String> collectedFrames() {
+ return testFramesOrReflectionFrames;
+ }
+ public boolean accept(StackFrame f) {
+ // Frames whose class names don't contain "."
+ // are our own test frames. These are the ones
+ // we expect.
+ // Frames whose class names contain ".reflect."
+ // are reflection frames. None should be present,
+ // since they are supposed to be filtered by
+ // by StackWalker. If we find any, we want to fail.
+ if (!f.getClassName().contains(".")
+ || f.getClassName().contains(".reflect.")) {
+ System.out.println(" " + f);
+ return true;
+ }
+ // Filter out all other frames (in particular
+ // those from the test framework) in order to
+ // have predictable results.
+ return false;
+ }
+ public String frame(StackFrame f) {
+ return f.getClassName() + "::" + f.getMethodName();
+ }
+ List<String> parse(Stream<StackFrame> s) {
+ return s.filter(this::accept)
+ .map(this::frame)
+ .collect(Collectors.toList());
+ }
+ public static ConstructorNewInstance create() throws Exception {
+ return ConstructorNewInstance.class.getConstructor().newInstance();
+ }
+ }
+
class StackBuilder {
private final int stackDepth;
private final int limit;
@@ -131,9 +186,4 @@
}
}
- static void assertEquals(int x, int y) {
- if (x != y) {
- throw new RuntimeException(x + " != " + y);
- }
- }
}
--- a/jdk/test/java/lang/StackWalker/CallerFromMain.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/StackWalker/CallerFromMain.java Wed Jul 05 22:52:22 2017 +0200
@@ -51,7 +51,7 @@
try {
Class<?> c = sw.getCallerClass();
throw new RuntimeException("UOE not thrown. Caller: " + c);
- } catch (IllegalStateException e) {}
+ } catch (IllegalCallerException e) {}
// StackWalker::getCallerClass
// Runnable::run
--- a/jdk/test/java/lang/StackWalker/CountLocalSlots.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +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.
- *
- * 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
- * @modules java.base/java.lang:open
- * @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 + ")");
- }
- }
- }
-}
--- a/jdk/test/java/lang/StackWalker/LocalsAndOperands.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/StackWalker/LocalsAndOperands.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,33 +23,54 @@
/*
* @test
- * @bug 8020968 8147039
+ * @bug 8020968 8147039 8156073
* @summary Tests for locals and operands
* @modules java.base/java.lang:open
- * @run testng LocalsAndOperands
+ * @run testng/othervm -Xint -DtestUnused=true LocalsAndOperands
+ * @run testng/othervm -Xcomp LocalsAndOperands
+ * @run testng/othervm -Xcomp -XX:-TieredCompilation LocalsAndOperands
*/
import org.testng.annotations.*;
+import static org.testng.Assert.*;
import java.lang.StackWalker.StackFrame;
+import static java.lang.StackWalker.Option.*;
import java.lang.reflect.*;
import java.util.*;
import java.util.stream.*;
public class LocalsAndOperands {
- static final boolean debug = true;
+ static final boolean debug = false;
+ static final boolean is32bit;
+ static final boolean testUnused;
static Class<?> liveStackFrameClass;
- static Class<?> primitiveValueClass;
+ static Class<?> primitiveSlotClass;
+ static Class<?> primitiveSlot32Class;
+ static Class<?> primitiveSlot64Class;
+
static StackWalker extendedWalker;
static Method getLocals;
static Method getOperands;
static Method getMonitors;
- static Method primitiveType;
+ static Method primitiveSize;
+ static Method primitiveLongValue;
+ static Method primitiveIntValue;
+ static Method getExtendedWalker;
+
+ private static final long LOWER_LONG_VAL = 4L; // Lower bits
+ private static final long UPPER_LONG_VAL = 0x123400000000L; // Upper bits
+ private static final long NEG_LONG_VAL = Long.MIN_VALUE;
+
+ private static final double LOWER_DOUBLE_VAL = Double.longBitsToDouble(0xABCDL);
+ private static final double UPPER_DOUBLE_VAL = Double.longBitsToDouble(0x432100000000L);
static {
try {
liveStackFrameClass = Class.forName("java.lang.LiveStackFrame");
- primitiveValueClass = Class.forName("java.lang.LiveStackFrame$PrimitiveValue");
+ primitiveSlotClass = Class.forName("java.lang.LiveStackFrame$PrimitiveSlot");
+ primitiveSlot32Class = Class.forName("java.lang.LiveStackFrameInfo$PrimitiveSlot32");
+ primitiveSlot64Class = Class.forName("java.lang.LiveStackFrameInfo$PrimitiveSlot64");
getLocals = liveStackFrameClass.getDeclaredMethod("getLocals");
getLocals.setAccessible(true);
@@ -60,12 +81,31 @@
getMonitors = liveStackFrameClass.getDeclaredMethod("getMonitors");
getMonitors.setAccessible(true);
- primitiveType = primitiveValueClass.getDeclaredMethod("type");
- primitiveType.setAccessible(true);
+ primitiveSize = primitiveSlotClass.getDeclaredMethod("size");
+ primitiveSize.setAccessible(true);
+
+ primitiveLongValue = primitiveSlotClass.getDeclaredMethod("longValue");
+ primitiveLongValue.setAccessible(true);
+
+ primitiveIntValue = primitiveSlotClass.getDeclaredMethod("intValue");
+ primitiveIntValue.setAccessible(true);
- Method method = liveStackFrameClass.getMethod("getStackWalker");
- method.setAccessible(true);
- extendedWalker = (StackWalker) method.invoke(null);
+ getExtendedWalker = liveStackFrameClass.getMethod("getStackWalker", Set.class);
+ getExtendedWalker.setAccessible(true);
+ extendedWalker = (StackWalker) getExtendedWalker.invoke(null,
+ EnumSet.noneOf(StackWalker.Option.class));
+
+ String dataModel = System.getProperty("sun.arch.data.model");
+ if ("32".equals(dataModel)) {
+ is32bit = true;
+ } else if ("64".equals(dataModel)) {
+ is32bit= false;
+ } else {
+ throw new RuntimeException("Weird data model:" + dataModel);
+ }
+ System.out.println("VM bits: " + dataModel);
+
+ testUnused = System.getProperty("testUnused") != null;
} catch (Throwable t) { throw new RuntimeException(t); }
}
@@ -80,47 +120,17 @@
* DataProviders *
*****************/
- /** 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.
- */
+ /** Calls KnownLocalsTester.testLocals* and provides LiveStackFrames */
@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()
- };
+ public static StackFrame[][] knownLocalsProvider() {
+ List<StackFrame[]> list = new ArrayList<>(3);
+ list.add(new KnownLocalsTester().testLocalsKeepAlive());
+ list.add(new KnownLocalsTester().testLocalsKeepAliveArgs(0xA, 'z',
+ "himom", 0x3FF00000000L + 0xFFFF, Math.PI));
+ if (testUnused) {
+ list.add(new KnownLocalsTester().testLocalsUnused());
+ }
+ return list.toArray(new StackFrame[1][1]);
}
/****************
@@ -128,135 +138,123 @@
****************/
/**
- * Check for expected local values and types in the LiveStackFrame
+ * Check for expected local values in the LiveStackFrame
*/
- @Test(dataProvider = "keepAliveProvider")
+ @Test(dataProvider = "knownLocalsProvider")
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++) {
- // 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);
- }
-
- // 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);
- }
- }
- }
- );
+ dumpFramesIfDebug(frames);
+ try {
+ Stream.of(frames)
+ .filter(f -> KnownLocalsTester.TEST_METHODS.contains(f.getMethodName()))
+ .forEach(LocalsAndOperands::checkFrameLocals);
+ } catch (Exception e) { dumpFramesIfNotDebug(frames); throw e; }
}
/**
- * Basic sanity check for locals and operands
+ * Check the locals in the given StackFrame against the expected values.
*/
- @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);
+ private static void checkFrameLocals(StackFrame f) {
+ Object[] expectedArray = KnownLocalsTester.LOCAL_VALUES;
+ Object[] locals = invokeGetLocals(f);
+
+ for (int i = 0; i < locals.length; i++) {
+ Object expected = expectedArray[i];
+ Object observed = locals[i];
+
+ if (expected == null) { /* skip nulls in golden values */
+ continue;
+ } else if (expected instanceof KnownLocalsTester.TwoSlotValue) {
+ // confirm integrity of expected values
+ assertEquals(expectedArray[i+1], null,
+ "Malformed array of expected values - slot after TwoSlotValue should be null");
+ assertLongIsInSlots(locals[i], locals[i+1],
+ ((KnownLocalsTester.TwoSlotValue)expected).value);
+ i++; // skip following slot
+ } else if (primitiveSlotClass.isInstance(observed)) { // single slot primitive
+ assertTrue(primitiveValueEquals(observed, expected),
+ "Local value mismatch: local " + i + " value is " +
+ observed + ", expected " + expected);
+ } else if (expected instanceof Class) {
+ assertTrue(((Class)expected).isInstance(observed),
+ "Local value mismatch: local " + i + " expected instancof " +
+ expected + " but got " + observed);
+ } else if (expected instanceof String) {
+ assertEquals(expected, observed, "Local value mismatch: local " +
+ i + " value is " + observed + ", expected " + expected);
} else {
- System.out.println(stream.count() + " frames");
+ throw new RuntimeException("Unrecognized expected local value " +
+ i + ": " + expected);
}
- } catch (Throwable t) {
- dumpStackWithLocals(frames);
- throw t;
}
}
/**
* Sanity check for locals and operands, including testng/jtreg frames
+ * using all StackWalker options.
*/
- @Test(dataProvider = "unfilteredProvider")
- public static void unfilteredSanityCheck(StackFrame... frames) {
+ @Test
+ public synchronized void fullStackSanityCheck() throws Throwable {
if (debug) {
- System.out.println("Running unfilteredSanityCheck");
+ System.out.println("Running fullStackSanityCheck");
}
- try {
- Stream<StackFrame> stream = Arrays.stream(frames);
+ StackWalker sw = (StackWalker) getExtendedWalker.invoke(null,
+ EnumSet.of(SHOW_HIDDEN_FRAMES, SHOW_REFLECT_FRAMES,
+ RETAIN_CLASS_REFERENCE));
+ sw.forEach(f -> {
if (debug) {
- stream.forEach(f -> { System.out.println(f + ": " +
- invokeGetLocals(f).length + " locals"); } );
+ printLocals(f);
} else {
- System.out.println(stream.count() + " frames");
+ try {
+ System.out.println(" " + f + ": " +
+ ((Object[]) getLocals.invoke(f)).length + " locals, " +
+ ((Object[]) getOperands.invoke(f)).length + " operands, " +
+ ((Object[]) getMonitors.invoke(f)).length + " monitors");
+ } catch (IllegalAccessException|InvocationTargetException t) {
+ throw new RuntimeException(t);
+ }
}
- } 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");
- }
- }
+ @Test
+ public static void noLocalsSanityCheck() {
+ StackWalker sw = StackWalker.getInstance();
+ sw.forEach(f -> {
+ assertFalse(liveStackFrameClass.isInstance(f),
+ "should not be LiveStackFrame");
+ });
}
- static class Tester {
+ /**
+ * Class stack-walking methods with a known set of methods and local variables.
+ */
+ static class KnownLocalsTester {
private StackWalker walker;
- private boolean filter = true; // Filter out testng/jtreg/etc frames?
- Tester() {
+ KnownLocalsTester() {
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() {
+ private synchronized StackFrame[] testLocalsUnused() {
// Unused local variables will become dead
- int x = 10;
- char c = 'z';
+ int x = 0xA;
+ char c = 'z'; // 0x7A
String hi = "himom";
- long l = 1000000L;
- double d = 3.1415926;
+ long l = 0x3FF00000000L + 0xFFFFL;
+ double d = Math.PI;
- 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]);
- }
+ return walker.walk(s ->
+ s.filter(f -> TEST_METHODS.contains(f.getMethodName()))
+ .toArray(StackFrame[]::new)
+ );
}
/**
@@ -264,64 +262,153 @@
* the collected StackFrames
*/
private synchronized StackFrame[] testLocalsKeepAlive() {
- int x = 10;
- char c = 'z';
+ int x = 0xA;
+ char c = 'z'; // 0x7A
String hi = "himom";
- long l = 1000000L;
- double d = 3.1415926;
+ long l = 0x3FF00000000L + 0xFFFFL;
+ double d = Math.PI;
- 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()));
- }
+ StackFrame[] frames = walker.walk(s ->
+ s.filter(f -> TEST_METHODS.contains(f.getMethodName()))
+ .toArray(StackFrame[]::new)
+ );
// 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
+ System.out.println("Stayin' alive: "+this+" "+x+" "+c+" "+hi+" "+l+" "+d);
+ return frames;
+ }
+
+ /**
+ * Perform stackwalk, keeping method arguments alive, and return a list of
+ * the collected StackFrames
+ */
+ private synchronized StackFrame[] testLocalsKeepAliveArgs(int x, char c,
+ String hi, long l,
+ double d) {
+ StackFrame[] frames = walker.walk(s ->
+ s.filter(f -> TEST_METHODS.contains(f.getMethodName()))
+ .toArray(StackFrame[]::new)
+ );
+
+ // Use local variables so they stay alive
+ System.out.println("Stayin' alive: "+this+" "+x+" "+c+" "+hi+" "+l+" "+d);
+ return frames;
+ }
+
+ // An expected two-slot local (i.e. long or double)
+ static class TwoSlotValue {
+ public long value;
+ public TwoSlotValue(long value) { this.value = value; }
}
- // 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",
+ // Expected values for locals in KnownLocalsTester.testLocals* methods
+ private final static Object[] LOCAL_VALUES = new Object[] {
+ LocalsAndOperands.KnownLocalsTester.class,
+ Integer.valueOf(0xA),
+ Integer.valueOf(0x7A),
"himom",
- "0",
- null, // skip, fix in 8156073
- null, // skip, fix in 8156073
- null, // skip, fix in 8156073
- "0"
+ new TwoSlotValue(0x3FF00000000L + 0xFFFFL),
+ null, // 2nd slot
+ new TwoSlotValue(Double.doubleToRawLongBits(Math.PI)),
+ null, // 2nd slot
+ Integer.valueOf(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"
- };
+ private final static List<String> TEST_METHODS =
+ List.of("testLocalsUnused",
+ "testLocalsKeepAlive",
+ "testLocalsKeepAliveArgs");
+ }
+
+ /* Simpler tests of long & double arguments */
+
+ @Test
+ public static void testUsedLongArg() throws Exception {
+ usedLong(LOWER_LONG_VAL);
+ usedLong(UPPER_LONG_VAL);
+ usedLong(NEG_LONG_VAL);
+ }
+
+ private static void usedLong(long longArg) throws Exception {
+ StackFrame[] frames = extendedWalker.walk(s ->
+ s.filter(f -> "usedLong".equals(f.getMethodName()))
+ .toArray(StackFrame[]::new)
+ );
+ try {
+ dumpFramesIfDebug(frames);
+
+ Object[] locals = (Object[]) getLocals.invoke(frames[0]);
+ assertLongIsInSlots(locals[0], locals[1], longArg);
+ System.out.println("Stayin' alive: " + longArg);
+ } catch (Exception t) {
+ dumpFramesIfNotDebug(frames);
+ throw t;
+ }
+ }
+
+ @Test
+ public static void testUnusedLongArg() throws Exception {
+ if (testUnused) {
+ unusedLong(NEG_LONG_VAL);
+ }
+ }
- final static Map NUM_LOCALS = Map.of("testLocals", 8,
- "testLocalsKeepAlive",
- LOCAL_VALUES.length);
- private final static Collection<String> TEST_METHODS = NUM_LOCALS.keySet();
+ private static void unusedLong(long longArg) throws Exception {
+ StackFrame[] frames = extendedWalker.walk(s ->
+ s.filter(f -> "unusedLong".equals(f.getMethodName()))
+ .toArray(StackFrame[]::new)
+ );
+ try {
+ dumpFramesIfDebug(frames);
+
+ final Object[] locals = (Object[]) getLocals.invoke(frames[0]);
+ assertLongIsInSlots(locals[0], locals[1], NEG_LONG_VAL);
+ } catch (Exception t) {
+ dumpFramesIfNotDebug(frames);
+ throw t;
+ }
+ }
+
+ @Test
+ public static void testUsedDoubleArg() throws Exception {
+ usedDouble(LOWER_DOUBLE_VAL);
+ usedDouble(UPPER_DOUBLE_VAL);
}
+ private static void usedDouble(double doubleArg) throws Exception {
+ StackFrame[] frames = extendedWalker.walk(s ->
+ s.filter(f -> "usedDouble".equals(f.getMethodName()))
+ .toArray(StackFrame[]::new)
+ );
+ try {
+ dumpFramesIfDebug(frames);
+
+ Object[] locals = (Object[]) getLocals.invoke(frames[0]);
+ assertDoubleIsInSlots(locals[0], locals[1], doubleArg);
+ System.out.println("Stayin' alive: " + doubleArg);
+ } catch (Exception t) {
+ dumpFramesIfNotDebug(frames);
+ throw t;
+ }
+ }
+
+ /*******************
+ * Utility Methods *
+ *******************/
+
/**
* Print stack trace with locals
*/
public static void dumpStackWithLocals(StackFrame...frames) {
- Arrays.stream(frames).forEach(LocalsAndOperands::printLocals);
+ Stream.of(frames).forEach(LocalsAndOperands::printLocals);
+ }
+
+ public static void dumpFramesIfDebug(StackFrame...frames) {
+ if (debug) { dumpStackWithLocals(frames); }
+ }
+
+ public static void dumpFramesIfNotDebug(StackFrame...frames) {
+ if (!debug) { dumpStackWithLocals(frames); }
}
/**
@@ -329,10 +416,21 @@
*/
public static void printLocals(StackWalker.StackFrame frame) {
try {
- System.out.println(frame);
+ System.out.println("Locals for: " + 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]));
+ String localStr = null;
+
+ if (primitiveSlot64Class.isInstance(locals[i])) {
+ localStr = String.format("0x%X",
+ (Long)primitiveLongValue.invoke(locals[i]));
+ } else if (primitiveSlot32Class.isInstance(locals[i])) {
+ localStr = String.format("0x%X",
+ (Integer)primitiveIntValue.invoke(locals[i]));
+ } else if (locals[i] != null) {
+ localStr = locals[i].toString();
+ }
+ System.out.format(" local %d: %s type %s\n", i, localStr, type(locals[i]));
}
Object[] operands = (Object[]) getOperands.invoke(frame);
@@ -352,12 +450,87 @@
try {
if (o == null) {
return "null";
- } else if (primitiveValueClass.isInstance(o)) {
- char c = (char)primitiveType.invoke(o);
- return String.valueOf(c);
+ } else if (primitiveSlotClass.isInstance(o)) {
+ int s = (int)primitiveSize.invoke(o);
+ return s + "-byte primitive";
} else {
return o.getClass().getName();
}
} catch(Exception e) { throw new RuntimeException(e); }
}
+
+ /*
+ * Check if the PrimitiveValue "primVal" contains the specified value,
+ * either a Long or an Integer.
+ */
+ static boolean primitiveValueEquals(Object primVal, Object expectedVal) {
+ try {
+ if (expectedVal instanceof Long) {
+ assertFalse(is32bit);
+ assertTrue(primitiveSlot64Class.isInstance(primVal));
+ assertTrue(8 == (int)primitiveSize.invoke(primVal));
+ return Objects.equals(primitiveLongValue.invoke(primVal), expectedVal);
+ } else if (expectedVal instanceof Integer) {
+ int expectedInt = (Integer)expectedVal;
+ if (is32bit) {
+ assertTrue(primitiveSlot32Class.isInstance(primVal),
+ "expected a PrimitiveSlot32 on 32-bit VM");
+ assertTrue(4 == (int)primitiveSize.invoke(primVal));
+ return expectedInt == (int)primitiveIntValue.invoke(primVal);
+ } else {
+ assertTrue(primitiveSlot64Class.isInstance(primVal),
+ "expected a PrimitiveSlot64 on 64-bit VM");
+ assertTrue(8 == (int)primitiveSize.invoke(primVal));
+ // Look for int expectedVal in high- or low-order 32 bits
+ long primValLong = (long)primitiveLongValue.invoke(primVal);
+ return (int)(primValLong & 0x00000000FFFFFFFFL) == expectedInt ||
+ (int)(primValLong >>> 32) == expectedInt;
+ }
+ } else {
+ throw new RuntimeException("Called with non-Integer/Long: " + expectedVal);
+ }
+ } catch (IllegalAccessException|InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ /*
+ * Assert that the expected 2-slot long value is stored somewhere in the
+ * pair of slots.
+ * Throw exception if long value isn't in the two slots given.
+ * Accounts for 32 vs 64 bit, but is lax on endianness (accepts either)
+ */
+ static void assertLongIsInSlots(Object primVal0, Object primVal1, long expected) {
+ try {
+ if (is32bit) {
+ int upper = (int)(expected & 0xFFFFFFFFL);
+ int lower = (int)(expected >> 32);
+
+ if (!((primitiveValueEquals(primVal0, upper) &&
+ primitiveValueEquals(primVal1, lower)) ||
+ (primitiveValueEquals(primVal0, lower) &&
+ primitiveValueEquals(primVal1, upper)))) {
+ throw new RuntimeException(String.format("0x%X and 0x%X of 0x%016X not found in 0x%X and 0x%X",
+ upper, lower, expected,
+ (int)primitiveIntValue.invoke(primVal0),
+ (int)primitiveIntValue.invoke(primVal1)));
+ }
+ } else {
+ if (!(primitiveValueEquals(primVal0, expected) ||
+ primitiveValueEquals(primVal1, expected))) {
+ throw new RuntimeException(String.format("0x%016X not found in 0x%016X or 0x%016X",
+ expected,
+ (long)primitiveLongValue.invoke(primVal0),
+ (long)primitiveLongValue.invoke(primVal1)));
+ }
+ }
+ } catch (IllegalAccessException|InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static void assertDoubleIsInSlots(Object primVal0, Object primVal1, double expected) {
+ assertLongIsInSlots(primVal0, primVal1, Double.doubleToRawLongBits(expected));
+ }
}
--- a/jdk/test/java/lang/StackWalker/LocalsCrash.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +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.
- *
- * 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
- * @modules java.base/java.lang:open
- * @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); }
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/StackWalker/ReflectionFrames.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,842 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8173898
+ * @summary Basic test for checking filtering of reflection frames
+ * @run testng ReflectionFrames
+ */
+
+import java.lang.StackWalker.StackFrame;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.function.Supplier;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+import static java.lang.StackWalker.Option.*;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+public class ReflectionFrames {
+ final static boolean verbose = false;
+
+ /**
+ * This test invokes new StackInspector() directly from
+ * the caller StackInspector.Caller.create method.
+ * It checks that the caller is StackInspector.Caller.
+ * It also checks the expected frames collected
+ * by walking the stack from the default StackInspector()
+ * constructor.
+ * This is done twice, once using a default StackWalker
+ * that hides reflection frames, once using a StackWalker
+ * configured to show reflection frames.
+ */
+ @Test
+ public static void testNewStackInspector() throws Exception {
+ // Sets the default walker which hides reflection
+ // frames.
+ StackInspector.walker.set(StackInspector.walkerHide);
+
+ // Calls the StackInspector.create method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The create method invokes new StackInspector() directly.
+ // No reflection frame should appear.
+ System.out.println("testNewStackInspector: create");
+
+ StackInspector obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("create", How.class)
+ .invoke(null, How.NEW));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ ReflectionFrames.class.getName()
+ +"::testNewStackInspector"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.reflect method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The reflect method invokes the create method through
+ // reflection.
+ // The create method invokes new StackInspector() directly.
+ // No reflection frame should appear.
+ System.out.println("testNewStackInspector: reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("reflect", How.class)
+ .invoke(null, How.NEW));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ StackInspector.Caller.class.getName()
+ +"::reflect",
+ ReflectionFrames.class.getName()
+ +"::testNewStackInspector"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.handle method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The handle method invokes the create method using
+ // a MethodHandle.
+ // The create method invokes new StackInspector() directly.
+ // No reflection frame should appear.
+ System.out.println("testNewStackInspector: handle");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("handle", How.class)
+ .invoke(null, How.NEW));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ StackInspector.Caller.class.getName()
+ +"::handle",
+ ReflectionFrames.class.getName()
+ +"::testNewStackInspector"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertEquals(obj.filtered, 0);
+
+ // Sets a non-default walker configured to show
+ // reflection frames
+ StackInspector.walker.set(StackInspector.walkerShow);
+
+ // Calls the StackInspector.create method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The create method invokes new StackInspector() directly.
+ // We should see all reflection frames, except the
+ // jdk.internal.reflect frames which we are filtering
+ // out in StackInspector::filter.
+ System.out.println("testNewStackInspector: create: show reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("create", How.class)
+ .invoke(null, How.NEW));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ Method.class.getName()
+ +"::invoke",
+ ReflectionFrames.class.getName()
+ +"::testNewStackInspector"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertNotEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.reflect method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The reflect method invokes the create method through
+ // reflection.
+ // The create method invokes new StackInspector() directly.
+ // We should see all reflection frames, except the
+ // jdk.internal.reflect frames which we are filtering
+ // out in StackInspector::filter.
+ System.out.println("testNewStackInspector: reflect: show reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("reflect", How.class)
+ .invoke(null, How.NEW));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ Method.class.getName()
+ +"::invoke",
+ StackInspector.Caller.class.getName()
+ +"::reflect",
+ Method.class.getName()
+ +"::invoke",
+ ReflectionFrames.class.getName()
+ +"::testNewStackInspector"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertNotEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.handle method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The handle method invokes the create method using
+ // MethodHandle.
+ // The create method invokes new StackInspector() directly.
+ // We should see all reflection frames, except the
+ // jdk.internal.reflect frames which we are filtering
+ // out in StackInspector::filter.
+ System.out.println("testNewStackInspector: handle: show reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("handle", How.class)
+ .invoke(null, How.NEW));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ // MethodHandle::invoke remains hidden
+ StackInspector.Caller.class.getName()
+ +"::handle",
+ Method.class.getName()
+ +"::invoke",
+ ReflectionFrames.class.getName()
+ +"::testNewStackInspector"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertNotEquals(obj.filtered, 0);
+ }
+
+ /**
+ * This test invokes Constructor.newInstance() from
+ * the caller StackInspector.Caller.create method.
+ * It checks that the caller is StackInspector.Caller.
+ * It also checks the expected frames collected
+ * by walking the stack from the default StackInspector()
+ * constructor.
+ * This is done twice, once using a default StackWalker
+ * that hides reflection frames, once using a StackWalker
+ * configured to show reflection frames.
+ */
+ @Test
+ public static void testConstructor() throws Exception {
+ // Sets the default walker which hides reflection
+ // frames.
+ StackInspector.walker.set(StackInspector.walkerHide);
+
+ // Calls the StackInspector.create method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The create method invokes Constructor.newInstance().
+ // No reflection frame should appear.
+ System.out.println("testConstructor: create");
+
+ StackInspector obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("create", How.class)
+ .invoke(null, How.CONSTRUCTOR));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ ReflectionFrames.class.getName()
+ +"::testConstructor"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.reflect method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The reflect method invokes the create method through
+ // reflection.
+ // The create method invokes Constructor.newInstance().
+ // No reflection frame should appear.
+ System.out.println("testConstructor: reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("reflect", How.class)
+ .invoke(null, How.CONSTRUCTOR));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ StackInspector.Caller.class.getName()
+ +"::reflect",
+ ReflectionFrames.class.getName()
+ +"::testConstructor"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.handle method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The handle method invokes the create method using
+ // MethodHandle.
+ // The create method invokes Constructor.newInstance().
+ // No reflection frame should appear.
+ System.out.println("testConstructor: handle");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("handle", How.class)
+ .invoke(null, How.CONSTRUCTOR));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ StackInspector.Caller.class.getName()
+ +"::handle",
+ ReflectionFrames.class.getName()
+ +"::testConstructor"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertEquals(obj.filtered, 0);
+
+ // Sets a non-default walker configured to show
+ // reflection frames
+ StackInspector.walker.set(StackInspector.walkerShow);
+
+ // Calls the StackInspector.create method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The create method invokes Constructor.newInstance().
+ // We should see all reflection frames, except the
+ // jdk.internal.reflect frames which we are filtering
+ // out in StackInspector::filter.
+ System.out.println("testConstructor: create: show reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("create", How.class)
+ .invoke(null, How.CONSTRUCTOR));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ Constructor.class.getName()
+ +"::newInstance",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ Method.class.getName()
+ +"::invoke",
+ ReflectionFrames.class.getName()
+ +"::testConstructor"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertNotEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.reflect method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The reflect method invokes the create method through
+ // reflection.
+ // The create method invokes Constructor.newInstance().
+ // We should see all reflection frames, except the
+ // jdk.internal.reflect frames which we are filtering
+ // out in StackInspector::filter.
+ System.out.println("testConstructor: reflect: show reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("reflect", How.class)
+ .invoke(null, How.CONSTRUCTOR));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ Constructor.class.getName()
+ +"::newInstance",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ Method.class.getName()
+ +"::invoke",
+ StackInspector.Caller.class.getName()
+ +"::reflect",
+ Method.class.getName()
+ +"::invoke",
+ ReflectionFrames.class.getName()
+ +"::testConstructor"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertNotEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.handle method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The handle method invokes the create method using
+ // MethodHandle.
+ // The create method invokes Constructor.newInstance().
+ // We should see all reflection frames, except the
+ // jdk.internal.reflect frames which we are filtering
+ // out in StackInspector::filter.
+ System.out.println("testConstructor: handle: show reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("handle", How.class)
+ .invoke(null, How.CONSTRUCTOR));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ Constructor.class.getName()
+ +"::newInstance",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ // MethodHandle::invoke remains hidden
+ StackInspector.Caller.class.getName()
+ +"::handle",
+ Method.class.getName()
+ +"::invoke",
+ ReflectionFrames.class.getName()
+ +"::testConstructor"));
+ assertEquals(obj.cls, StackInspector.Caller.class);
+ assertNotEquals(obj.filtered, 0);
+ }
+
+ /**
+ * This test invokes StackInspector.class.newInstance() from
+ * the caller StackInspector.Caller.create method. Because
+ * Class.newInstance() is not considered as a
+ * reflection frame, the the caller returned by
+ * getCallerClass() should appear to be java.lang.Class
+ * and not StackInspector.Caller.
+ * It also checks the expected frames collected
+ * by walking the stack from the default StackInspector()
+ * constructor.
+ * This is done twice, once using a default StackWalker
+ * that hides reflection frames, once using a StackWalker
+ * configured to show reflection frames.
+ */
+ @Test
+ public static void testNewInstance() throws Exception {
+ // Sets the default walker which hides reflection
+ // frames.
+ StackInspector.walker.set(StackInspector.walkerHide);
+
+ // Calls the StackInspector.create method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The create method invokes StackInspector.class.newInstance().
+ // No reflection frame should appear, except
+ // Class::newInstance which is not considered as
+ // a reflection frame.
+ System.out.println("testNewInstance: create");
+
+ StackInspector obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("create", How.class)
+ .invoke(null, How.CLASS));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ Class.class.getName()
+ +"::newInstance",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ ReflectionFrames.class.getName()
+ +"::testNewInstance"));
+ // Because Class.newInstance is not filtered, then the
+ // caller is Class.class
+ assertEquals(obj.cls, Class.class);
+ assertEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.reflect method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The reflect method invokes the create method through
+ // reflection.
+ // The create method invokes StackInspector.class.newInstance().
+ // No reflection frame should appear, except
+ // Class::newInstance which is not considered as
+ // a reflection frame.
+ System.out.println("testNewInstance: reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("reflect", How.class)
+ .invoke(null, How.CLASS));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ Class.class.getName()
+ +"::newInstance",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ StackInspector.Caller.class.getName()
+ +"::reflect",
+ ReflectionFrames.class.getName()
+ +"::testNewInstance"));
+
+ // Because Class.newInstance is not filtered, then the
+ // caller is Class.class
+ assertEquals(obj.cls, Class.class);
+ assertEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.handle method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The handle method invokes the create method using
+ // reflection.
+ // The create method invokes StackInspector.class.newInstance().
+ // No reflection frame should appear, except
+ // Class::newInstance which is not considered as
+ // a reflection frame.
+ System.out.println("testNewInstance: handle");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("handle", How.class)
+ .invoke(null, How.CLASS));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ Class.class.getName()
+ +"::newInstance",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ StackInspector.Caller.class.getName()
+ +"::handle",
+ ReflectionFrames.class.getName()
+ +"::testNewInstance"));
+
+ // Because Class.newInstance is not filtered, then the
+ // caller is Class.class
+ assertEquals(obj.cls, Class.class);
+ assertEquals(obj.filtered, 0);
+
+ // Sets a non-default walker configured to show
+ // reflection frames
+ StackInspector.walker.set(StackInspector.walkerShow);
+
+ // Calls the StackInspector.create method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The create method invokes StackInspector.class.newInstance().
+ // We should see all reflection frames, except the
+ // jdk.internal.reflect frames which we are filtering
+ // out in StackInspector::filter.
+ System.out.println("testNewInstance: create: show reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("create", How.class)
+ .invoke(null, How.CLASS));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ Constructor.class.getName()
+ +"::newInstance",
+ Class.class.getName()
+ +"::newInstance",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ Method.class.getName()
+ +"::invoke",
+ ReflectionFrames.class.getName()
+ +"::testNewInstance"));
+ // Because Class.newInstance is not filtered, then the
+ // caller is Class.class
+ assertEquals(obj.cls, Class.class);
+ assertNotEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.reflect method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The reflect method invokes the create method through
+ // reflection.
+ // The create method invokes StackInspector.class.newInstance().
+ // We should see all reflection frames, except the
+ // jdk.internal.reflect frames which we are filtering
+ // out in StackInspector::filter.
+ System.out.println("testNewInstance: reflect: show reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("reflect", How.class)
+ .invoke(null, How.CLASS));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ Constructor.class.getName()
+ +"::newInstance",
+ Class.class.getName()
+ +"::newInstance",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ Method.class.getName()
+ +"::invoke",
+ StackInspector.Caller.class.getName()
+ +"::reflect",
+ Method.class.getName()
+ +"::invoke",
+ ReflectionFrames.class.getName()
+ +"::testNewInstance"));
+
+ // Because Class.newInstance is not filtered, then the
+ // caller is Class.class
+ assertEquals(obj.cls, Class.class);
+ assertNotEquals(obj.filtered, 0);
+
+ // Calls the StackInspector.handle method through reflection
+ // and check the frames collected in the StackInspector
+ // default constructor.
+ // The handle method invokes the create method using
+ // MethodHandle.
+ // The create method invokes StackInspector.class.newInstance().
+ // We should see all reflection frames, except the
+ // jdk.internal.reflect frames which we are filtering
+ // out in StackInspector::filter.
+ System.out.println("testNewInstance: handle: show reflect");
+
+ obj = ((StackInspector)StackInspector.Caller.class
+ .getMethod("handle", How.class)
+ .invoke(null, How.CLASS));
+ assertEquals(obj.collectedFrames,
+ List.of(StackInspector.class.getName()
+ +"::<init>",
+ Constructor.class.getName()
+ +"::newInstance",
+ Class.class.getName()
+ +"::newInstance",
+ StackInspector.Caller.class.getName()
+ +"::create",
+ // MethodHandle::invoke remains hidden
+ StackInspector.Caller.class.getName()
+ +"::handle",
+ Method.class.getName()
+ +"::invoke",
+ ReflectionFrames.class.getName()
+ +"::testNewInstance"));
+
+ // Because Class.newInstance is not filtered, then the
+ // caller is Class.class
+ assertEquals(obj.cls, Class.class);
+ assertNotEquals(obj.filtered, 0);
+ }
+
+ @Test
+ public static void testGetCaller() throws Exception {
+ // Sets the default walker which hides reflection
+ // frames.
+ StackInspector.walker.set(StackInspector.walkerHide);
+
+ assertEquals(StackInspector.getCaller(), ReflectionFrames.class);
+ assertEquals(StackInspector.class.getMethod("getCaller").invoke(null),
+ ReflectionFrames.class);
+
+ // Sets a non-default walker configured to show
+ // reflection frames
+ StackInspector.walker.set(StackInspector.walkerShow);
+
+ assertEquals(StackInspector.getCaller(), ReflectionFrames.class);
+ assertEquals(StackInspector.class.getMethod("getCaller").invoke(null),
+ ReflectionFrames.class);
+ }
+
+ @Test
+ public static void testReflectCaller() throws Exception {
+ // Sets the default walker which hides reflection
+ // frames.
+ StackInspector.walker.set(StackInspector.walkerHide);
+
+ assertEquals(StackInspector.reflectCaller(), ReflectionFrames.class);
+ assertEquals(StackInspector.class.getMethod("reflectCaller").invoke(null),
+ ReflectionFrames.class);
+
+ // Sets a non-default walker configured to show
+ // reflection frames
+ StackInspector.walker.set(StackInspector.walkerShow);
+
+ assertEquals(StackInspector.reflectCaller(), ReflectionFrames.class);
+ assertEquals(StackInspector.class.getMethod("reflectCaller").invoke(null),
+ ReflectionFrames.class);
+ }
+
+ @Test
+ public static void testSupplyCaller() throws Exception {
+ // Sets the default walker which hides reflection
+ // frames.
+ StackInspector.walker.set(StackInspector.walkerHide);
+
+ assertEquals(StackInspector.supplyCaller(), ReflectionFrames.class);
+ assertEquals(StackInspector.class.getMethod("supplyCaller").invoke(null),
+ ReflectionFrames.class);
+
+ // Sets a non-default walker configured to show
+ // reflection frames
+ StackInspector.walker.set(StackInspector.walkerShow);
+
+ assertEquals(StackInspector.supplyCaller(), ReflectionFrames.class);
+ assertEquals(StackInspector.class.getMethod("supplyCaller").invoke(null),
+ ReflectionFrames.class);
+ }
+
+ @Test
+ public static void testHandleCaller() throws Exception {
+ // Sets the default walker which hides reflection
+ // frames.
+ StackInspector.walker.set(StackInspector.walkerHide);
+
+ assertEquals(StackInspector.handleCaller(), ReflectionFrames.class);
+ assertEquals(StackInspector.class.getMethod("handleCaller").invoke(null),
+ ReflectionFrames.class);
+
+ // Sets a non-default walker configured to show
+ // reflection frames
+ StackInspector.walker.set(StackInspector.walkerShow);
+
+ assertEquals(StackInspector.handleCaller(), ReflectionFrames.class);
+ assertEquals(StackInspector.class.getMethod("handleCaller").invoke(null),
+ ReflectionFrames.class);
+ }
+
+ static enum How { NEW, CONSTRUCTOR, CLASS};
+
+ /**
+ * An object that collect stack frames by walking the stack
+ * (and calling getCallerClass()) from within its constructor.
+ * For the purpose of this test, StackInspector objects are
+ * always created from the nested StackInspector.Caller class,
+ * which should therefore appear as the caller of the
+ * StackInspector constructor.
+ */
+ static class StackInspector {
+ static final StackWalker walkerHide =
+ StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+ static final StackWalker walkerShow =
+ StackWalker.getInstance(EnumSet.of(
+ StackWalker.Option.RETAIN_CLASS_REFERENCE,
+ StackWalker.Option.SHOW_REFLECT_FRAMES));
+ final static ThreadLocal<StackWalker> walker = new ThreadLocal<>() {
+ protected StackWalker initialValue() {
+ return walkerHide;
+ }
+ };
+
+ List<String> collectedFrames;
+ Class<?> cls = null;
+ boolean stop;
+ int filtered;
+ final boolean filterImplFrames;
+
+ public StackInspector() {
+ stop = false;
+ // if reflection frames are not hidden, we want to
+ // filter implementation frames before collecting
+ // to avoid depending on internal details.
+ filterImplFrames = walker.get() == walkerShow;
+ collectedFrames = walker.get().walk(this::parse);
+ cls = walker.get().getCallerClass();
+ }
+
+ public List<String> collectedFrames() {
+ return collectedFrames;
+ }
+
+ // The takeWhile method arrange for stopping frame collection
+ // as soon as a frame from ReflectionFrames.class is reached.
+ // The first such frame encountered is still included in the
+ // collected frames, but collection stops right after.
+ // This makes it possible to filter out anything above the
+ // the test method frame, such as frames from the test
+ // framework.
+ public boolean takeWhile(StackFrame f) {
+ if (stop) return false;
+ if (verbose) System.out.println(" " + f);
+ stop = stop || f.getDeclaringClass() == ReflectionFrames.class;
+ return true;
+ }
+
+ // filter out implementation frames to avoid depending
+ // on implementation details. If present, Class::newInstance,
+ // Method::invoke and Constructor::newInstance will
+ // still appear in the collected frames, which is
+ // sufficient for the purpose of the test.
+ // In the case where the StackWalker itself is supposed to
+ // filter the reflection frames, then this filter will always
+ // return true. This way, if such a reflection frame appears when
+ // it sjould have been filtered by StackWalker, it will make the
+ // test fail.
+ public boolean filter(StackFrame f) {
+ if (filterImplFrames &&
+ f.getClassName().startsWith("jdk.internal.reflect.")) {
+ filtered++;
+ return false;
+ }
+ if (!verbose) System.out.println(" " + f);
+ return true;
+ }
+
+ public String frame(StackFrame f) {
+ return f.getClassName() + "::" + f.getMethodName();
+ }
+
+ List<String> parse(Stream<StackFrame> s) {
+ return s.takeWhile(this::takeWhile)
+ .filter(this::filter)
+ .map(this::frame)
+ .collect(Collectors.toList());
+ }
+
+ /**
+ * The Caller class is used to create instances of
+ * StackInspector, either direcltly, or throug reflection.
+ */
+ public static class Caller {
+ public static StackInspector create(How how) throws Exception {
+ switch(how) {
+ case NEW: return new StackInspector();
+ case CONSTRUCTOR: return StackInspector.class
+ .getConstructor().newInstance();
+ case CLASS: return StackInspector.class.newInstance();
+ default: throw new AssertionError(String.valueOf(how));
+ }
+ }
+ public static StackInspector reflect(How how) throws Exception {
+ return (StackInspector) Caller.class.getMethod("create", How.class)
+ .invoke(null, how);
+ }
+ public static StackInspector handle(How how) throws Exception {
+ Lookup lookup = MethodHandles.lookup();
+ MethodHandle mh = lookup.findStatic(Caller.class, "create",
+ MethodType.methodType(StackInspector.class, How.class));
+ try {
+ return (StackInspector) mh.invoke(how);
+ } catch (Error | Exception x) {
+ throw x;
+ } catch(Throwable t) {
+ throw new AssertionError(t);
+ }
+ }
+ }
+
+ public static Class<?> getCaller() throws Exception {
+ return walker.get().getCallerClass();
+ }
+
+ public static Class<?> reflectCaller() throws Exception {
+ return (Class<?>)StackWalker.class.getMethod("getCallerClass")
+ .invoke(walker.get());
+ }
+
+ public static Class<?> supplyCaller() throws Exception {
+ return ((Supplier<Class<?>>)StackInspector.walker.get()::getCallerClass).get();
+ }
+
+ public static Class<?> handleCaller() throws Exception {
+ Lookup lookup = MethodHandles.lookup();
+ MethodHandle mh = lookup.findVirtual(StackWalker.class, "getCallerClass",
+ MethodType.methodType(Class.class));
+ try {
+ return (Class<?>) mh.invoke(walker.get());
+ } catch (Error | Exception x) {
+ throw x;
+ } catch(Throwable t) {
+ throw new AssertionError(t);
+ }
+ }
+ }
+}
--- a/jdk/test/java/lang/invoke/AccessControlTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/invoke/AccessControlTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -118,6 +118,8 @@
suffix = "/noaccess";
else if (lookupModes == PUBLIC)
suffix = "/public";
+ else if (lookupModes == (PUBLIC|UNCONDITIONAL))
+ suffix = "/publicLookup";
else if (lookupModes == (PUBLIC|MODULE))
suffix = "/module";
else if (lookupModes == (PUBLIC|MODULE|PACKAGE))
@@ -140,23 +142,24 @@
* [A2] However, the resulting {@code Lookup} object is guaranteed
* to have no more access capabilities than the original.
* In particular, access capabilities can be lost as follows:<ul>
- * <li>[A3] If the new lookup class differs from the old one,
- * protected members will not be accessible by virtue of inheritance.
+ * <li> [A3] If the old lookup class is in a named module, and the new
+ * lookup class is in a different module {@code M}, then no members, not
+ * even public members in {@code M}'s exported packages, will be accessible.
+ * The exception to this is when this lookup is publicLookup, in which case
+ * public access is not lost.
+ * <li> [A4] If the old lookup class is in an unnamed module, and the new
+ * lookup class is a different module then module access is lost.
+ * <li> [A5] If the new lookup class differs from the old one then UNCONDITIONAL
+ * is lost. If the new lookup class is not within the same package member as the
+ * old one, protected members will not be accessible by virtue of inheritance.
* (Protected members may continue to be accessible because of package sharing.)
- * <li>[A4] If the new lookup class is in a different package
- * than the old one, protected and default (package) members will not be accessible.
- * <li>[A5] If the new lookup class is not within the same package member
+ * <li> [A6] If the new lookup class is in a different package than the old one,
+ * protected and default (package) members will not be accessible.
+ * <li> [A7] If the new lookup class is not within the same package member
* as the old one, private members will not be accessible.
- * <li>[A6] If the new lookup class is not accessible to the old lookup class,
- * using the original access modes,
+ * <li> [A8] If the new lookup class is not accessible to the old lookup class,
* then no members, not even public members, will be accessible.
- * <li>[A7] If the new lookup class for this {@code Lookup} is in the unnamed module,
- * and the new lookup class is in a named module {@code M}, then no members in
- * {@code M}'s non-exported packages will be accessible.
- * <li>[A8] If the lookup for this {@code Lookup} is in a named module, and the
- * new lookup class is in a different module, then no members, not even
- * public members in {@code M}'s exported packages, will be accessible.
- * [A8] (In all other cases, public members will continue to be accessible.)
+ * <li> [A9] (In all other cases, public members will continue to be accessible.)
* </ul>
* Other than the above cases, the new lookup will have the same
* access capabilities as the original. [A10]
@@ -171,36 +174,35 @@
boolean sameModule = (c1.getModule() == c2.getModule()) ||
(!c1.getModule().isNamed() && !c2.getModule().isNamed());
boolean samePackage = (c1.getClassLoader() == c2.getClassLoader() &&
- packagePrefix(c1).equals(packagePrefix(c2)));
+ c1.getPackageName().equals(c2.getPackageName()));
boolean sameTopLevel = (topLevelClass(c1) == topLevelClass(c2));
boolean sameClass = (c1 == c2);
assert(samePackage || !sameTopLevel);
assert(sameTopLevel || !sameClass);
- boolean accessible = sameClass; // [A6]
+ boolean accessible = sameClass;
if ((m1 & PACKAGE) != 0) accessible |= samePackage;
if ((m1 & PUBLIC ) != 0) accessible |= (c2.getModifiers() & PUBLIC) != 0;
if (!sameModule) {
- if (c1.getModule().isNamed()) {
- accessible = false; // [A8]
+ if (c1.getModule().isNamed() && (m1 & UNCONDITIONAL) == 0) {
+ accessible = false; // [A3]
} else {
- // Different module; loose MODULE and lower access.
- changed |= (MODULE|PACKAGE|PRIVATE|PROTECTED); // [A7]
+ changed |= (MODULE|PACKAGE|PRIVATE|PROTECTED); // [A3] [A4]
}
}
if (!accessible) {
// Different package and no access to c2; lose all access.
- changed |= (PUBLIC|MODULE|PACKAGE|PRIVATE|PROTECTED); // [A6]
+ changed |= (PUBLIC|MODULE|PACKAGE|PRIVATE|PROTECTED); // [A8]
}
if (!samePackage) {
// Different package; loose PACKAGE and lower access.
- changed |= (PACKAGE|PRIVATE|PROTECTED); // [A4]
+ changed |= (PACKAGE|PRIVATE|PROTECTED); // [A6]
}
if (!sameTopLevel) {
- // Different top-level class. Lose PRIVATE and lower access.
- changed |= (PRIVATE|PROTECTED); // [A5]
+ // Different top-level class. Lose PRIVATE and PROTECTED access.
+ changed |= (PRIVATE|PROTECTED); // [A5] [A7]
}
if (!sameClass) {
- changed |= (PROTECTED); // [A3]
+ changed |= (UNCONDITIONAL); // [A5]
} else {
assert(changed == 0); // [A10] (no deprivation if same class)
}
@@ -228,11 +230,10 @@
Class<?> c1 = lookupClass();
Class<?> c2 = m.getDeclaringClass();
- // if the lookup class is in a loose module with PUBLIC access then
- // public members of public types in all unnamed modules can be accessed
- if (isLooseModule(c1.getModule())
+ // publicLookup has access to all public types/members of types in unnamed modules
+ if ((lookupModes & UNCONDITIONAL) != 0
&& (lookupModes & PUBLIC) != 0
- && (!c2.getModule().isNamed())
+ && !c2.getModule().isNamed()
&& Modifier.isPublic(c2.getModifiers())
&& Modifier.isPublic(m.getModifiers()))
return true;
@@ -261,17 +262,12 @@
if (load && c2.getClassLoader() != null) {
if (c1.getClassLoader() == null) {
// not visible
- return false;
- }
- if (c1 == publicLookup().lookupClass()) {
- // not visible as lookup class is defined by child of the boot loader
return false;
}
}
- // if the lookup class is in a loose module with PUBLIC access then
- // public types in all unnamed modules can be accessed
- if (isLooseModule(c1.getModule())
+ // publicLookup has access to all public types/members of types in unnamed modules
+ if ((lookupModes & UNCONDITIONAL) != 0
&& (lookupModes & PUBLIC) != 0
&& (!c2.getModule().isNamed())
&& Modifier.isPublic(c2.getModifiers()))
@@ -295,11 +291,6 @@
}
return r;
}
-
- private boolean isLooseModule(Module m) {
- ClassLoader cl = new ClassLoader() { };
- return m.canRead(cl.getUnnamedModule());
- }
}
private static Class<?> topLevelClass(Class<?> cls) {
@@ -311,14 +302,6 @@
return c;
}
- private static String packagePrefix(Class<?> c) {
- while (c.isArray()) c = c.getComponentType();
- String s = c.getName();
- assert(s.indexOf('/') < 0);
- return s.substring(0, s.lastIndexOf('.')+1);
- }
-
-
private final TreeSet<LookupCase> CASES = new TreeSet<>();
private final TreeMap<LookupCase,TreeSet<LookupCase>> CASE_EDGES = new TreeMap<>();
private final ArrayList<ClassLoader> LOADERS = new ArrayList<>();
--- a/jdk/test/java/lang/invoke/DropLookupModeTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/invoke/DropLookupModeTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -65,6 +65,10 @@
lookup = fullPowerLookup.dropLookupMode(PUBLIC);
assertTrue(lookup.lookupClass() == lc);
assertTrue(lookup.lookupModes() == 0);
+
+ lookup = fullPowerLookup.dropLookupMode(UNCONDITIONAL);
+ assertTrue(lookup.lookupClass() == lc);
+ assertTrue(lookup.lookupModes() == (PUBLIC|MODULE|PACKAGE|PRIVATE));
}
/**
@@ -108,7 +112,7 @@
public void testPublicLookup() {
final Lookup publicLookup = MethodHandles.publicLookup();
final Class<?> lc = publicLookup.lookupClass();
- assertTrue(publicLookup.lookupModes() == PUBLIC);
+ assertTrue(publicLookup.lookupModes() == (PUBLIC|UNCONDITIONAL));
Lookup lookup = publicLookup.dropLookupMode(PRIVATE);
assertTrue(lookup.lookupClass() == lc);
@@ -129,6 +133,10 @@
lookup = publicLookup.dropLookupMode(PUBLIC);
assertTrue(lookup.lookupClass() == lc);
assertTrue(lookup.lookupModes() == 0);
+
+ lookup = publicLookup.dropLookupMode(UNCONDITIONAL);
+ assertTrue(lookup.lookupClass() == lc);
+ assertTrue(lookup.lookupModes() == PUBLIC);
}
@DataProvider(name = "badInput")
--- a/jdk/test/java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/invoke/LFCaching/LFMultiThreadCachingTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,7 +30,7 @@
* @library /lib/testlibrary/jsr292 /lib/testlibrary
* @modules java.base/java.lang.invoke:open
* java.base/java.lang.ref:open
- * jdk.management
+ * java.management
* @build TestMethods
* @build LambdaFormTestCase
* @build LFCachingTestCase
--- a/jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/invoke/LFCaching/LFSingleThreadCachingTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,7 @@
* @library /lib/testlibrary/jsr292 /lib/testlibrary
* @modules java.base/java.lang.ref:open
* java.base/java.lang.invoke:open
+ * java.management
* @build TestMethods
* @build LambdaFormTestCase
* @build LFCachingTestCase
--- a/jdk/test/java/lang/invoke/MethodHandles/privateLookupIn/Driver.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/invoke/MethodHandles/privateLookupIn/Driver.java Wed Jul 05 22:52:22 2017 +0200
@@ -23,7 +23,7 @@
/**
* @test
- * @build test/* m1/* m2/* m3/*
+ * @build test/* m1/* m2/* m3/* Unnamed
* @run testng/othervm test/p.PrivateLookupInTests
* @summary Unit tests for MethodHandles.privateLookupIn
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/MethodHandles/privateLookupIn/Unnamed.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+public class Unnamed { }
--- a/jdk/test/java/lang/invoke/MethodHandles/privateLookupIn/test/p/PrivateLookupInTests.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/invoke/MethodHandles/privateLookupIn/test/p/PrivateLookupInTests.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -126,6 +126,26 @@
Object obj = mh.invokeExact();
}
+ // test target class in unnamed module
+ public void testTargetClassInUnnamedModule() throws Throwable {
+ Class<?> clazz = Class.forName("Unnamed");
+ assertFalse(clazz.getModule().isNamed());
+
+ // thisModule does not read the unnamed module
+ Module thisModule = getClass().getModule();
+ assertFalse(thisModule.canRead(clazz.getModule()));
+ try {
+ MethodHandles.privateLookupIn(clazz, MethodHandles.lookup());
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ // thisModule reads the unnamed module
+ thisModule.addReads(clazz.getModule());
+ Lookup lookup = MethodHandles.privateLookupIn(clazz, MethodHandles.lookup());
+ assertTrue(lookup.lookupClass() == clazz);
+ assertTrue(lookup.hasPrivateAccess());
+ }
+
// test does not read m2, m2 opens p2 to test
@Test(expectedExceptions = {IllegalAccessException.class})
public void testCallerDoesNotRead() throws Throwable {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/lambda/MetafactoryDescriptorTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,269 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8035776 8173587
+ * @summary metafactory should fail if instantiatedMethodType does not match sam/bridge descriptors
+ */
+import java.lang.invoke.*;
+import java.util.*;
+
+public class MetafactoryDescriptorTest {
+
+ static final MethodHandles.Lookup lookup = MethodHandles.lookup();
+
+ static MethodType mt(Class<?> ret, Class<?>... params) {
+ return MethodType.methodType(ret, params);
+ }
+
+ public interface I {}
+
+ public static class C {
+ public static void m_void(String arg) {}
+ public static boolean m_boolean(String arg) { return true; }
+ public static char m_char(String arg) { return 'x'; }
+ public static byte m_byte(String arg) { return 12; }
+ public static short m_short(String arg) { return 12; }
+ public static int m_int(String arg) { return 12; }
+ public static long m_long(String arg) { return 12; }
+ public static float m_float(String arg) { return 12; }
+ public static double m_double(String arg) { return 12; }
+ public static String m_String(String arg) { return ""; }
+ public static Integer m_Integer(String arg) { return 23; }
+ public static Object m_Object(String arg) { return new Object(); }
+
+ public static String n_boolean(boolean arg) { return ""; }
+ public static String n_char(char arg) { return ""; }
+ public static String n_byte(byte arg) { return ""; }
+ public static String n_short(short arg) { return ""; }
+ public static String n_int(int arg) { return ""; }
+ public static String n_long(long arg) { return ""; }
+ public static String n_float(float arg) { return ""; }
+ public static String n_double(double arg) { return ""; }
+ public static String n_String(String arg) { return ""; }
+ public static String n_Integer(Integer arg) { return ""; }
+ public static String n_Object(Object arg) { return ""; }
+
+ public static MethodHandle getM(Class<?> c) {
+ try {
+ return lookup.findStatic(C.class, "m_" + c.getSimpleName(), mt(c, String.class));
+ }
+ catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static MethodHandle getN(Class<?> c) {
+ if (c == void.class) return null;
+ try {
+ return lookup.findStatic(C.class, "n_" + c.getSimpleName(), mt(String.class, c));
+ }
+ catch (NoSuchMethodException | IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ }
+
+ public static void main(String... args) {
+ Class<?>[] t = { void.class, boolean.class, char.class,
+ byte.class, short.class, int.class, long.class, float.class, double.class,
+ String.class, Integer.class, Object.class };
+
+ for (int i = 0; i < t.length; i++) {
+ MethodHandle m = C.getM(t[i]);
+ MethodHandle n = C.getN(t[i]); // null for void.class
+ for (int j = 0; j < t.length; j++) {
+ boolean correctRet = t[j].isAssignableFrom(t[i]) || conversions.contains(t[i], t[j]);
+ test(correctRet, m, mt(t[i], String.class), mt(t[j], String.class));
+ testBridge(correctRet, m, mt(t[i], String.class), mt(t[i], String.class),
+ mt(t[j], Object.class));
+ testBridge(correctRet, m, mt(t[i], String.class), mt(t[i], String.class),
+ mt(t[i], CharSequence.class), mt(t[j], Object.class));
+
+ if (t[i] != void.class && t[j] != void.class) {
+ boolean correctParam = t[j].isAssignableFrom(t[i]);
+ test(correctParam, n, mt(String.class, t[i]), mt(String.class, t[j]));
+ testBridge(correctParam, n, mt(String.class, t[i]), mt(String.class, t[i]),
+ mt(Object.class, t[j]));
+ testBridge(correctParam, n, mt(String.class, t[i]), mt(String.class, t[i]),
+ mt(CharSequence.class, t[i]), mt(Object.class, t[j]));
+ }
+
+ }
+ }
+ }
+
+ static void test(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT) {
+ tryMetafactory(correct, mh, instMT, samMT);
+ tryAltMetafactory(correct, mh, instMT, samMT);
+ }
+
+ static void testBridge(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
+ tryAltMetafactory(correct, mh, instMT, samMT, bridgeMTs);
+ }
+
+ static void tryMetafactory(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT) {
+ try {
+ LambdaMetafactory.metafactory(lookup, "run", mt(I.class),
+ samMT, mh, instMT);
+ if (!correct) {
+ throw new AssertionError("Unexpected linkage without error:" +
+ " impl=" + mh +
+ ", inst=" + instMT +
+ ", sam=" + samMT);
+ }
+ }
+ catch (LambdaConversionException e) {
+ if (correct) {
+ throw new AssertionError("Unexpected linkage error:" +
+ " e=" + e +
+ ", impl=" + mh +
+ ", inst=" + instMT +
+ ", sam=" + samMT);
+ }
+ }
+ }
+
+ static void tryAltMetafactory(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT,
+ MethodType... bridgeMTs) {
+ boolean bridge = bridgeMTs.length > 0;
+ Object[] args = new Object[bridge ? 5+bridgeMTs.length : 4];
+ args[0] = samMT;
+ args[1] = mh;
+ args[2] = instMT;
+ args[3] = bridge ? LambdaMetafactory.FLAG_BRIDGES : 0;
+ if (bridge) {
+ args[4] = bridgeMTs.length;
+ for (int i = 0; i < bridgeMTs.length; i++) args[5+i] = bridgeMTs[i];
+ }
+ try {
+ LambdaMetafactory.altMetafactory(lookup, "run", mt(I.class), args);
+ if (!correct) {
+ throw new AssertionError("Unexpected linkage without error:" +
+ " impl=" + mh +
+ ", inst=" + instMT +
+ ", sam=" + samMT +
+ ", bridges=" + Arrays.toString(bridgeMTs));
+ }
+ }
+ catch (LambdaConversionException e) {
+ if (correct) {
+ throw new AssertionError("Unexpected linkage error:" +
+ " e=" + e +
+ ", impl=" + mh +
+ ", inst=" + instMT +
+ ", sam=" + samMT +
+ ", bridges=" + Arrays.toString(bridgeMTs));
+ }
+ }
+ }
+
+ private static class ConversionTable {
+ private final Map<Class<?>, Set<Class<?>>> pairs = new HashMap<>();
+
+ public void put(Class<?> from, Class<?> to) {
+ Set<Class<?>> set = pairs.computeIfAbsent(from, f -> new HashSet<>());
+ set.add(to);
+ }
+
+ public boolean contains(Class<?> from, Class<?> to) {
+ return pairs.containsKey(from) && pairs.get(from).contains(to);
+ }
+ }
+
+ private static ConversionTable conversions = new ConversionTable();
+ static {
+ conversions.put(char.class, int.class);
+ conversions.put(char.class, long.class);
+ conversions.put(char.class, float.class);
+ conversions.put(char.class, double.class);
+ conversions.put(char.class, Character.class);
+ conversions.put(char.class, Object.class);
+ conversions.put(Character.class, char.class);
+ conversions.put(Character.class, int.class);
+ conversions.put(Character.class, long.class);
+ conversions.put(Character.class, float.class);
+ conversions.put(Character.class, double.class);
+
+ conversions.put(byte.class, short.class);
+ conversions.put(byte.class, int.class);
+ conversions.put(byte.class, long.class);
+ conversions.put(byte.class, float.class);
+ conversions.put(byte.class, double.class);
+ conversions.put(byte.class, Byte.class);
+ conversions.put(byte.class, Object.class);
+ conversions.put(Byte.class, byte.class);
+ conversions.put(Byte.class, short.class);
+ conversions.put(Byte.class, int.class);
+ conversions.put(Byte.class, long.class);
+ conversions.put(Byte.class, float.class);
+ conversions.put(Byte.class, double.class);
+
+ conversions.put(short.class, int.class);
+ conversions.put(short.class, long.class);
+ conversions.put(short.class, float.class);
+ conversions.put(short.class, double.class);
+ conversions.put(short.class, Short.class);
+ conversions.put(short.class, Object.class);
+ conversions.put(Short.class, short.class);
+ conversions.put(Short.class, int.class);
+ conversions.put(Short.class, long.class);
+ conversions.put(Short.class, float.class);
+ conversions.put(Short.class, double.class);
+
+ conversions.put(int.class, long.class);
+ conversions.put(int.class, float.class);
+ conversions.put(int.class, double.class);
+ conversions.put(int.class, Integer.class);
+ conversions.put(int.class, Object.class);
+ conversions.put(Integer.class, int.class);
+ conversions.put(Integer.class, long.class);
+ conversions.put(Integer.class, float.class);
+ conversions.put(Integer.class, double.class);
+
+ conversions.put(long.class, float.class);
+ conversions.put(long.class, double.class);
+ conversions.put(long.class, Long.class);
+ conversions.put(long.class, Object.class);
+ conversions.put(Long.class, long.class);
+ conversions.put(Long.class, float.class);
+ conversions.put(Long.class, double.class);
+
+ conversions.put(float.class, double.class);
+ conversions.put(float.class, Float.class);
+ conversions.put(float.class, Object.class);
+ conversions.put(Float.class, float.class);
+ conversions.put(Float.class, double.class);
+
+ conversions.put(double.class, Double.class);
+ conversions.put(double.class, Object.class);
+ conversions.put(Double.class, double.class);
+
+ conversions.put(boolean.class, Boolean.class);
+ conversions.put(boolean.class, Object.class);
+ conversions.put(Boolean.class, boolean.class);
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/lambda/MetafactoryMethodNameTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8173587
+ * @summary metafactory should fail if the method name is not legal
+ */
+import java.lang.invoke.*;
+import java.util.*;
+
+public class MetafactoryMethodNameTest {
+
+ public static void main(String... args) {
+ goodName("x");
+ goodName("xy");
+
+ goodName("]");
+ goodName("x]");
+ goodName("]y");
+ goodName("x]y");
+
+ goodName("&");
+ goodName("x&");
+ goodName("&y");
+ goodName("x&y");
+
+ badName(".");
+ badName("x.");
+ badName(".y");
+ badName("x.y");
+
+ badName(";");
+ badName("x;");
+ badName(";y");
+ badName("x;y");
+
+ badName("[");
+ badName("x[");
+ badName("[y");
+ badName("x[y");
+
+ badName("/");
+ badName("x/");
+ badName("/y");
+ badName("x/y");
+
+ badName("<");
+ badName("x<");
+ badName("<y");
+ badName("x<y");
+
+ badName(">");
+ badName("x>");
+ badName(">y");
+ badName("x>y");
+
+ badName("");
+ badName("<init>");
+ badName("<clinit>");
+ }
+
+ static MethodType mt(Class<?> ret, Class<?>... params) {
+ return MethodType.methodType(ret, params);
+ }
+
+ static MethodHandle smh(Class<?> c, String name, MethodType desc) {
+ try {
+ return MethodHandles.lookup().findStatic(c, name, desc);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ static Object[] arr(Object... args) {
+ return args;
+ }
+
+ public static class C {
+ public static void m() {}
+ }
+
+ public interface I {}
+
+ private static MethodHandles.Lookup lookup = MethodHandles.lookup();
+ private static MethodType toI = mt(I.class);
+ private static MethodType toVoid = mt(void.class);
+ private static MethodHandle mh = smh(C.class, "m", toVoid);
+ private static Class<?> lce = LambdaConversionException.class;
+
+ static void goodName(String name) {
+ succeedMFLinkage(lookup, name, toI, toVoid, mh, toVoid);
+ succeedAltMFLinkage(lookup, name, toI, arr(toVoid, mh, toVoid, LambdaMetafactory.FLAG_SERIALIZABLE));
+ }
+
+ static void badName(String name) {
+ failMFLinkage(lookup, name, toI, toVoid, mh, toVoid, lce);
+ failAltMFLinkage(lookup, name, toI, arr(toVoid, mh, toVoid, LambdaMetafactory.FLAG_SERIALIZABLE), lce);
+ }
+
+ static CallSite succeedMFLinkage(MethodHandles.Lookup lookup,
+ String name,
+ MethodType capType,
+ MethodType desc,
+ MethodHandle impl,
+ MethodType checked) {
+ try {
+ return LambdaMetafactory.metafactory(lookup, name, capType, desc, impl, checked);
+ } catch (Throwable t) {
+ String msg = String.format("Unexpected exception during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
+ lookup, name, capType, desc, impl, checked);
+ throw new AssertionError(msg, t);
+ }
+ }
+
+ static void failMFLinkage(MethodHandles.Lookup lookup,
+ String name,
+ MethodType capType,
+ MethodType desc,
+ MethodHandle impl,
+ MethodType checked,
+ Class<?> expectedExceptionType) {
+ try {
+ LambdaMetafactory.metafactory(lookup, name, capType, desc, impl, checked);
+ } catch (Throwable t) {
+ if (expectedExceptionType.isInstance(t)) {
+ return;
+ } else {
+ String msg = String.format("Unexpected exception: expected %s during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
+ expectedExceptionType.getName(),
+ lookup, name, capType, desc, impl, checked);
+ throw new AssertionError(msg, t);
+ }
+ }
+ String msg = String.format("Unexpected success: expected %s during linkage for metafactory(%s, %s, %s, %s, %s, %s)",
+ expectedExceptionType.getName(),
+ lookup, name, capType, desc, impl, checked);
+ throw new AssertionError(msg);
+ }
+
+ static CallSite succeedAltMFLinkage(MethodHandles.Lookup lookup,
+ String name,
+ MethodType capType,
+ Object[] args) {
+ try {
+ return LambdaMetafactory.altMetafactory(lookup, name, capType, args);
+ } catch (Throwable t) {
+ String msg = String.format("Unexpected exception during linkage for metafactory(%s, %s, %s, %s)",
+ lookup, name, capType, Arrays.asList(args));
+ throw new AssertionError(msg, t);
+ }
+ }
+
+ static void failAltMFLinkage(MethodHandles.Lookup lookup,
+ String name,
+ MethodType capType,
+ Object[] args,
+ Class<?> expectedExceptionType) {
+ try {
+ LambdaMetafactory.altMetafactory(lookup, name, capType, args);
+ } catch (Throwable t) {
+ if (expectedExceptionType.isInstance(t)) {
+ return;
+ } else {
+ String msg = String.format("Unexpected exception: expected %s during linkage for metafactory(%s, %s, %s, %s)",
+ expectedExceptionType.getName(),
+ lookup, name, capType, Arrays.asList(args));
+ throw new AssertionError(msg, t);
+ }
+ }
+ String msg = String.format("Unexpected success: expected %s during linkage for metafactory(%s, %s, %s, %s)",
+ expectedExceptionType.getName(),
+ lookup, name, capType, Arrays.asList(args));
+ throw new AssertionError(msg);
+ }
+
+}
--- a/jdk/test/java/lang/invoke/lambda/MetafactorySamReturnTest.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,167 +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.
- *
- * 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 8035776
- * @summary metafactory should fail if impl return does not match sam/bridge returns
- */
-import java.lang.invoke.*;
-import java.util.Arrays;
-import static java.lang.invoke.MethodType.methodType;
-
-public class MetafactorySamReturnTest {
-
- static final MethodHandles.Lookup lookup = MethodHandles.lookup();
-
- public interface I {}
-
- public static class C {
- public static void m_void(String arg) {}
- public static boolean m_boolean(String arg) { return true; }
- public static char m_char(String arg) { return 'x'; }
- public static byte m_byte(String arg) { return 12; }
- public static short m_short(String arg) { return 12; }
- public static int m_int(String arg) { return 12; }
- public static long m_long(String arg) { return 12; }
- public static float m_float(String arg) { return 12; }
- public static double m_double(String arg) { return 12; }
- public static String m_String(String arg) { return ""; }
- public static Integer m_Integer(String arg) { return 23; }
- public static Object m_Object(String arg) { return new Object(); }
-
- public static MethodHandle getMH(Class<?> c) {
- try {
- return lookup.findStatic(C.class, "m_" + c.getSimpleName(), methodType(c, String.class));
- }
- catch (NoSuchMethodException | IllegalAccessException e) {
- throw new RuntimeException(e);
- }
- }
- }
-
- public static void main(String... args) {
- Class<?>[] t = { void.class, boolean.class, char.class,
- byte.class, short.class, int.class, long.class, float.class, double.class,
- String.class, Integer.class, Object.class };
-
- for (int i = 0; i < t.length; i++) {
- MethodHandle mh = C.getMH(t[i]);
- for (int j = 0; j < t.length; j++) {
- // TEMPORARY EXCEPTIONS
- if (t[j] == void.class) continue;
- if (t[i].isPrimitive() && t[j] == Object.class) continue;
- if (t[i] == char.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
- if (t[i] == byte.class && (t[j] == short.class || t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
- if (t[i] == short.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
- if (t[i] == int.class && (t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
- if (t[i] == long.class && (t[j] == float.class || t[j] == double.class)) continue;
- if (t[i] == float.class && t[j] == double.class) continue;
- if (t[i] == int.class && t[j] == Integer.class) continue;
- if (t[i] == Integer.class && (t[j] == int.class || t[j] == long.class || t[j] == float.class || t[j] == double.class)) continue;
- // END TEMPORARY EXCEPTIONS
- boolean correct = (t[i].isPrimitive() || t[j].isPrimitive())
- ? t[i] == t[j]
- : t[j].isAssignableFrom(t[i]);
- MethodType mti = methodType(t[i], String.class);
- MethodType mtiCS = methodType(t[i], CharSequence.class);
- MethodType mtj = methodType(t[j], String.class);
- MethodType mtjObj = methodType(t[j], Object.class);
- test(correct, mh, mti, mtj);
- testBridge(correct, mh, mti, mti, mtjObj);
- testBridge(correct, mh, mti, mti, mtiCS, mtjObj);
- }
- }
- }
-
- static void test(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT) {
- tryMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT);
- tryAltMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT);
- }
-
- static void testBridge(boolean correct, MethodHandle mh, MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
- tryAltMetafactory(correct, mh, new Class<?>[]{}, instMT, samMT, bridgeMTs);
- }
-
- static void tryMetafactory(boolean correct, MethodHandle mh, Class<?>[] captured,
- MethodType instMT, MethodType samMT) {
- try {
- LambdaMetafactory.metafactory(lookup, "run", methodType(I.class, captured),
- samMT, mh, instMT);
- if (!correct) {
- throw new AssertionError("Uncaught linkage error:" +
- " impl=" + mh +
- ", captured=" + Arrays.toString(captured) +
- ", inst=" + instMT +
- ", sam=" + samMT);
- }
- }
- catch (LambdaConversionException e) {
- if (correct) {
- throw new AssertionError("Unexpected linkage error:" +
- " e=" + e +
- ", impl=" + mh +
- ", captured=" + Arrays.toString(captured) +
- ", inst=" + instMT +
- ", sam=" + samMT);
- }
- }
- }
-
- static void tryAltMetafactory(boolean correct, MethodHandle mh, Class<?>[] captured,
- MethodType instMT, MethodType samMT, MethodType... bridgeMTs) {
- boolean bridge = bridgeMTs.length > 0;
- Object[] args = new Object[bridge ? 5+bridgeMTs.length : 4];
- args[0] = samMT;
- args[1] = mh;
- args[2] = instMT;
- args[3] = bridge ? LambdaMetafactory.FLAG_BRIDGES : 0;
- if (bridge) {
- args[4] = bridgeMTs.length;
- for (int i = 0; i < bridgeMTs.length; i++) args[5+i] = bridgeMTs[i];
- }
- try {
- LambdaMetafactory.altMetafactory(lookup, "run", methodType(I.class, captured), args);
- if (!correct) {
- throw new AssertionError("Uncaught linkage error:" +
- " impl=" + mh +
- ", captured=" + Arrays.toString(captured) +
- ", inst=" + instMT +
- ", sam=" + samMT +
- ", bridges=" + Arrays.toString(bridgeMTs));
- }
- }
- catch (LambdaConversionException e) {
- if (correct) {
- throw new AssertionError("Unexpected linkage error:" +
- " e=" + e +
- ", impl=" + mh +
- ", captured=" + Arrays.toString(captured) +
- ", inst=" + instMT +
- ", sam=" + samMT +
- ", bridges=" + Arrays.toString(bridgeMTs));
- }
- }
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/Driver.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
+ * @build m1/* m2/* Unnamed
+ * @run testng/othervm m1/p1.Main
+ * @summary Basic test case for module access checks and Lookup.in.
+ */
--- a/jdk/test/java/lang/invoke/modules/ModuleAccessControlTest.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * 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
- * 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.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.Arrays;
-import java.util.List;
-
-import static jdk.testlibrary.ProcessTools.executeTestJava;
-
-import org.testng.annotations.BeforeTest;
-import org.testng.annotations.Test;
-import static org.testng.Assert.*;
-
-/**
- * @test
- * @library /lib/testlibrary
- * @modules jdk.compiler
- * @build CompilerUtils jdk.testlibrary.*
- * @run testng ModuleAccessControlTest
- * @summary Driver for testing module access checking by MethodHandles.Lookup
- */
-
-public class ModuleAccessControlTest {
-
- private static final String TEST_SRC = System.getProperty("test.src");
-
- private static final Path SRC_DIR = Paths.get(TEST_SRC, "src");
- private static final Path MODS_DIR = Paths.get("mods");
-
- // the names of the modules in this test
- private static List<String> modules = Arrays.asList("m1", "m2");
-
-
- /**
- * Compiles all modules used by the test
- */
- @BeforeTest
- public void compileAll() throws Exception {
- for (String mn : modules) {
- Path msrc = SRC_DIR.resolve(mn);
- assertTrue(CompilerUtils
- .compile(msrc, MODS_DIR, "--module-source-path", SRC_DIR.toString()));
- }
- }
-
- /**
- * Launch the test
- */
- @Test
- public void runTest() throws Exception {
- int exitValue = executeTestJava("--module-path", MODS_DIR.toString(),
- "-m", "m1/p1.Main")
- .outputTo(System.out)
- .errorTo(System.out)
- .getExitValue();
-
- assertTrue(exitValue == 0);
- }
-
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/Unnamed.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+public class Unnamed { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m1/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+module m1 {
+ requires m2;
+ requires testng;
+ exports p1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m1/p1/Main.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,367 @@
+/*
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p1;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Layer;
+import java.lang.reflect.Module;
+
+import static java.lang.invoke.MethodHandles.Lookup.*;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/**
+ * Basic test case for module access checks and Lookup.in.
+ */
+
+@Test
+public class Main {
+
+ private Class<?> p1_Type1; // m1, exported
+ private Class<?> p2_Type2; // m1, not exported
+ private Class<?> q1_Type1; // m2, exported
+ private Class<?> q2_Type2; // m2, not exported
+ private Class<?> x500NameClass; // java.base, not exported
+ private Class<?> unnamedClass; // class in unnamed module
+
+ @BeforeTest
+ public void setup() throws Exception {
+ try {
+ p1_Type1 = Class.forName("p1.Type1");
+ p2_Type2 = Class.forName("p2.Type2");
+ q1_Type1 = Class.forName("q1.Type1");
+ q2_Type2 = Class.forName("q2.Type2");
+ x500NameClass = Class.forName("sun.security.x509.X500Name");
+ unnamedClass = Class.forName("Unnamed");
+ } catch (ClassNotFoundException e) {
+ throw new AssertionError(e);
+ }
+
+ // check setup
+ Module m1 = Layer.boot().findModule("m1").orElse(null);
+ assertNotNull(m1);
+ assertTrue(p1_Type1.getModule() == m1);
+ assertTrue(p2_Type2.getModule() == m1);
+ assertTrue(m1.isExported("p1"));
+ assertFalse(m1.isExported("p2"));
+
+ Module m2 = Layer.boot().findModule("m2").orElse(null);
+ assertNotNull(m2);
+ assertTrue(q1_Type1.getModule() == m2);
+ assertTrue(q2_Type2.getModule() == m2);
+ assertTrue(m2.isExported("q1"));
+ assertFalse(m2.isExported("q2"));
+
+ Module unnamedModule = unnamedClass.getModule();
+ assertFalse(unnamedModule.isNamed());
+
+ // m1 needs to read unnamed module
+ Main.class.getModule().addReads(unnamedModule);
+ }
+
+ /**
+ * MethodHandles.lookup()
+ *
+ * [A0] has module access
+ * [A1] can access all public types in m1
+ * [A2] can access public types in packages exported by modules that m1 reads
+ * [A3] cannot access public types in non-exported modules of modules that m1 reads
+ */
+ public void testLookup() throws Exception {
+ Lookup lookup = MethodHandles.lookup();
+ assertTrue((lookup.lookupModes() & MODULE) == MODULE); // [A0]
+
+ // m1
+ findConstructor(lookup, p1_Type1, void.class); // [A1]
+ findConstructor(lookup, p2_Type2, void.class); // [A1]
+
+ // m2
+ findConstructor(lookup, q1_Type1, void.class); // [A2]
+ findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A3]
+
+ // java.base
+ findConstructor(lookup, Object.class, void.class); // [A2]
+ findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class); // [A3]
+
+ // unnamed
+ findConstructor(lookup, unnamedClass, void.class); // [A3]
+ }
+
+ /**
+ * Hop to lookup class in the same module
+ *
+ * [A0] module and public access is not lost
+ */
+ public void testToSameModule() throws Exception {
+ Lookup lookup = MethodHandles.lookup().in(p2_Type2);
+ assertTrue(lookup.lookupModes() == (MODULE|PUBLIC)); // [A0]
+
+ // m1
+ findConstructor(lookup, p1_Type1, void.class);
+ findConstructor(lookup, p2_Type2, void.class);
+
+ // m2
+ findConstructor(lookup, q1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+ // java.base
+ findConstructor(lookup, Object.class, void.class);
+ findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+ // unnamed
+ findConstructor(lookup, unnamedClass, void.class);
+ }
+
+ /**
+ * Hop to lookup class in another named module
+ *
+ * [A0] has no access
+ */
+ public void testFromNamedToNamedModule() throws Exception {
+ Lookup lookup = MethodHandles.lookup().in(q1_Type1);
+ assertTrue(lookup.lookupModes() == 0); // [A0]
+
+ // m1
+ findConstructorExpectingIAE(lookup, p1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+ // m2
+ findConstructorExpectingIAE(lookup, q1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+ // java.base
+ findConstructorExpectingIAE(lookup, Object.class, void.class);
+ findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+ // unnamed
+ findConstructorExpectingIAE(lookup, unnamedClass, void.class);
+ }
+
+ /**
+ * Hop to lookup class in an unnamed module
+ *
+ * [A0] has no access
+ */
+ public void testFromNamedToUnnamedModule() throws Exception {
+ Lookup lookup = MethodHandles.lookup().in(unnamedClass);
+ assertTrue(lookup.lookupModes() == 0); // [A0]
+
+ // m1
+ findConstructorExpectingIAE(lookup, p1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+ // m2
+ findConstructorExpectingIAE(lookup, q1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+ // java.base
+ findConstructorExpectingIAE(lookup, Object.class, void.class);
+ findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+ // unnamed
+ findConstructorExpectingIAE(lookup, unnamedClass, void.class);
+ }
+
+ /**
+ * Hop from unnamed to named module.
+ *
+ * [A0] retains PUBLIC access
+ */
+ public void testFromUnnamedToNamedModule() throws Exception {
+ Lookup lookup = MethodHandles.lookup();
+ lookup = MethodHandles.privateLookupIn(unnamedClass, lookup).in(p1_Type1);
+ assertTrue(lookup.lookupModes() == PUBLIC); // A0
+
+ // m1
+ findConstructor(lookup, p1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+ // m2
+ findConstructor(lookup, q1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+ // java.base
+ findConstructor(lookup, Object.class, void.class);
+ findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+ // unnamed
+ findConstructor(lookup, unnamedClass, void.class);
+ }
+
+ /**
+ * MethodHandles.publicLookup()
+ *
+ * [A0] has PUBLIC|UNCONDITIONAL access
+ */
+ public void testPublicLookup() throws Exception {
+ Lookup lookup = MethodHandles.publicLookup();
+ assertTrue(lookup.lookupModes() == (PUBLIC|UNCONDITIONAL)); // A0
+
+ // m1
+ findConstructor(lookup, p1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+ // m2
+ findConstructor(lookup, q1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+ // java.base
+ findConstructor(lookup, Object.class, void.class);
+ findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+ // unnamed
+ findConstructor(lookup, unnamedClass, void.class);
+ }
+
+ /**
+ * Hop from publicLookup to accessible type in java.base
+ */
+ public void testPublicLookupToBaseModule() throws Exception {
+ Lookup lookup = MethodHandles.publicLookup().in(String.class);
+ assertTrue(lookup.lookupModes() == PUBLIC); // A0
+
+ // m1
+ findConstructorExpectingIAE(lookup, p1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+ // m2
+ findConstructorExpectingIAE(lookup, q1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+ // java.base
+ findConstructor(lookup, Object.class, void.class);
+ findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+ // unnamed
+ findConstructorExpectingIAE(lookup, unnamedClass, void.class);
+ }
+
+
+ /**
+ * Hop from publicLookup to accessible type in named module.
+ *
+ * [A0] has PUBLIC access
+ */
+ public void testPublicLookupToAccessibleTypeInNamedModule() throws Exception {
+ Lookup lookup = MethodHandles.publicLookup().in(p1_Type1);
+ assertTrue(lookup.lookupModes() == PUBLIC); // A0
+
+ // m1
+ findConstructor(lookup, p1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+ // m2
+ findConstructor(lookup, q1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+ // java.base
+ findConstructor(lookup, Object.class, void.class);
+ findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+ // unnamed
+ findConstructor(lookup, unnamedClass, void.class);
+ }
+
+ /**
+ * Teleport from publicLookup to inaccessible type in named module.
+ *
+ * [A0] has no access
+ */
+ public void testPublicLookupToInaccessibleTypeInNamedModule() throws Exception {
+ Lookup lookup = MethodHandles.publicLookup().in(p2_Type2);
+ assertTrue(lookup.lookupModes() == 0); // A0
+
+ // m1
+ findConstructorExpectingIAE(lookup, p1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+ // m2
+ findConstructorExpectingIAE(lookup, q1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+ // java.base
+ findConstructorExpectingIAE(lookup, Object.class, void.class);
+ findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+ // unnamed
+ findConstructorExpectingIAE(lookup, unnamedClass, void.class);
+ }
+
+ /**
+ * Teleport from publicLookup to public type in unnamed module
+ *
+ * [A0] has PUBLIC access
+ */
+ public void testPublicLookupToUnnamedModule() throws Exception {
+ Lookup lookup = MethodHandles.publicLookup().in(unnamedClass);
+ assertTrue(lookup.lookupModes() == PUBLIC); // A0
+
+ // m1
+ findConstructor(lookup, p1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, p2_Type2, void.class);
+
+ // m2
+ findConstructor(lookup, q1_Type1, void.class);
+ findConstructorExpectingIAE(lookup, q2_Type2, void.class);
+
+ // java.base
+ findConstructor(lookup, Object.class, void.class);
+ findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class);
+
+ // unnamed
+ findConstructor(lookup, unnamedClass, void.class);
+ }
+
+ /**
+ * Invokes Lookup findConstructor with a method type constructored from the
+ * given return and parameter types, expecting IllegalAccessException to be
+ * thrown.
+ */
+ static void findConstructorExpectingIAE(Lookup lookup,
+ Class<?> clazz,
+ Class<?> rtype,
+ Class<?>... ptypes) throws Exception {
+ try {
+ findConstructor(lookup, clazz, rtype, ptypes);
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+ }
+
+ /**
+ * Invokes Lookup findConstructor with a method type constructored from the
+ * given return and parameter types.
+ */
+ static MethodHandle findConstructor(Lookup lookup,
+ Class<?> clazz,
+ Class<?> rtype,
+ Class<?>... ptypes) throws Exception {
+ MethodType mt = MethodType.methodType(rtype, ptypes);
+ return lookup.findConstructor(clazz, mt);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m1/p1/Type1.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ * 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 p1;
+
+public class Type1 {
+ public Type1() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m1/p2/Type2.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ * 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 p2;
+
+public class Type2 {
+ public Type2() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m2/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,25 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+module m2 {
+ exports q1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m2/q1/Type1.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ * 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 q1;
+
+public class Type1 {
+ public Type1() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/modules/m2/q2/Type2.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,27 @@
+/*
+ * 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.
+ *
+ * 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 q2;
+
+public class Type2 {
+ public Type2() { }
+}
--- a/jdk/test/java/lang/invoke/modules/src/m1/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-module m1 {
- requires m2;
- exports p1;
-}
--- a/jdk/test/java/lang/invoke/modules/src/m1/p1/Main.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,225 +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.
- *
- * 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 p1;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodHandles.Lookup;
-import java.lang.invoke.MethodType;
-
-/**
- * Basic test case for module access check, supplements AccessControlTest.
- *
- * The tests consists of two modules:
- *
- * module m1 { requires m2; exports p1; }
- * module m2 { exports q1; }
- *
- * Both modules read java.base (as every module reads java.base)
- *
- * module m1 has public types in packages p1 and p2, p2 is not exported.
- * module m2 has public types in packages q1 and q2, q2 is not exported.
- */
-
-public class Main {
-
- static final int MODULE = Lookup.MODULE;
-
- // Use Class.forName to get classes for test because some
- // are not accessible at compile-time
-
- static final Class<?> p1_Type1; // m1, exported
- static final Class<?> p2_Type2; // m1, not exported
- static final Class<?> q1_Type1; // m2, exported, m1 reads m2
- static final Class<?> q2_Type2; // m2, not exported, m1 reads m2
- static final Class<?> x500NameClass; // java.base, not exported
-
- static {
- try {
- p1_Type1 = Class.forName("p1.Type1");
- p2_Type2 = Class.forName("p2.Type2");
- q1_Type1 = Class.forName("q1.Type1");
- q2_Type2 = Class.forName("q2.Type2");
- x500NameClass = Class.forName("sun.security.x509.X500Name");
- } catch (ClassNotFoundException e) {
- throw new AssertionError(e);
- }
- }
-
- public static void main(String[] args) throws Exception {
- Lookup lookup, lookup2;
-
- /**
- * MethodHandles.lookup()
- * has module access [A0]
- * can access all public types in m1 [A1]
- * can access public types in packages exported by modules that m1 reads [A2]
- * cannot access public types in non-exported modules of modules that m1 reads [A3]
- */
- lookup = MethodHandles.lookup();
- assertTrue((lookup.lookupModes() & MODULE) == MODULE); // [A0]
- findConstructor(lookup, p1_Type1, void.class); // [A1]
- findConstructor(lookup, p2_Type2, void.class); // [A1]
- findConstructor(lookup, q1_Type1, void.class); // [A2]
- findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A3]
- findConstructor(lookup, Object.class, void.class); // [A2]
- findConstructorExpectingIAE(lookup, x500NameClass, void.class, String.class); // [A3]
-
- /**
- * Teleport from MethodHandles.lookup() to lookup class in the same module
- * module access is retained [A0]
- * can access all public types in m1 [A1]
- * can access public types in packages exported by modules that m1 reads [A2]
- * cannot access public types in non-exported modules of modules that m1 reads [A3]
- */
- lookup2 = lookup.in(p2_Type2);
- assertTrue((lookup2.lookupModes() & MODULE) == MODULE); // [A0]
- findConstructor(lookup2, p1_Type1, void.class); // [A1]
- findConstructor(lookup2, p2_Type2, void.class); // [A1]
- findConstructor(lookup2, q1_Type1, void.class); // [A2]
- findConstructorExpectingIAE(lookup2, q2_Type2, void.class); // [A3]
- findConstructor(lookup2, Object.class, void.class); // [A2]
- findConstructorExpectingIAE(lookup2, x500NameClass, void.class, String.class); // [A3]
-
- /**
- * Teleport from MethodHandles.lookup() to lookup class in another named module
- * has no access [A0]
- */
- lookup2 = lookup.in(Object.class);
- assertTrue(lookup2.lookupModes() == 0); // [A0]
- findConstructorExpectingIAE(lookup2, Object.class, void.class); // [A0]
-
- /**
- * Teleport from MethodHandles.lookup() to lookup class in an unnamed module
- * has no access [A0]
- */
- Class<?> c = MethodHandles.publicLookup().lookupClass();
- assertTrue(!c.getModule().isNamed());
- lookup2 = lookup.in(c);
- assertTrue(lookup2.lookupModes() == 0); // [A0]
- findConstructorExpectingIAE(lookup2, Object.class, void.class);
-
- /**
- * MethodHandles.publicLookup()
- * has no module access [A0]
- * can access public types in exported packages [A1]
- * cannot access public types in non-exported packages [A2]
- */
- lookup = MethodHandles.publicLookup();
- assertTrue((lookup.lookupModes() & MODULE) == 0); // [A0]
- findConstructor(lookup, p1_Type1, void.class); // [A1]
- findConstructorExpectingIAE(lookup, p2_Type2, void.class); // [A1]
- findConstructor(lookup, q1_Type1, void.class); // [A1]
- findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A2]
- findConstructor(lookup, Object.class, void.class); // [A1]
- findConstructorExpectingIAE(lookup, x500NameClass, void.class); // [A2]
-
- /**
- * Teleport from MethodHandles.publicLookup() to lookup class in java.base
- * has no module access [A0]
- * can access public types in packages exported by java.base [A1]
- * cannot access public types in non-exported packages [A2]
- * no access to types in other named modules [A3]
- */
- lookup2 = lookup.in(Object.class);
- assertTrue((lookup2.lookupModes() & MODULE) == 0); // [A0]
- findConstructor(lookup2, String.class, void.class); // [A1]
- findConstructorExpectingIAE(lookup2, x500NameClass, void.class, String.class); // [A2]
- findConstructorExpectingIAE(lookup2, p1_Type1, void.class); // [A3]
- findConstructorExpectingIAE(lookup2, q1_Type1, void.class); // [A3]
-
- /**
- * Teleport from MethodHandles.publicLookup() to lookup class in m1
- * has no module access [A0]
- * can access public types in packages exported by m1, m2 and java.base [A1]
- * cannot access public types is non-exported packages [A2]
- */
- lookup2 = lookup.in(p1_Type1);
- assertTrue((lookup2.lookupModes() & MODULE) == 0); // [A0]
- findConstructor(lookup2, p1_Type1, void.class); // [A1]
- findConstructor(lookup2, q1_Type1, void.class); // [A1]
- findConstructor(lookup2, Object.class, void.class); // [A1]
- findConstructorExpectingIAE(lookup, p2_Type2, void.class); // [A2]
- findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A2]
- findConstructorExpectingIAE(lookup2, x500NameClass, void.class, String.class); // [A2]
-
- /**
- * Teleport from MethodHandles.publicLookup() to lookup class in m2
- * has no module access [A0]
- * can access public types in packages exported by m2 and java.base [A1]
- * cannot access public types is non-exported packages or modules that m2 does
- * not read [A2]
- */
- lookup2 = lookup.in(q1_Type1);
- assertTrue((lookup2.lookupModes() & MODULE) == 0); // [A0]
- findConstructor(lookup2, q1_Type1, void.class); // [A1]
- findConstructor(lookup2, Object.class, void.class); // [A1]
- findConstructorExpectingIAE(lookup2, p1_Type1, void.class); // [A2]
- findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A2]
- findConstructorExpectingIAE(lookup2, x500NameClass, void.class, String.class); // [A2]
-
- /**
- * Teleport from MethodHandles.publicLookup() to lookup class that is not
- * in an exported package, should get no access [A0]
- */
- lookup2 = lookup.in(p2_Type2);
- assertTrue(lookup2.lookupModes() == 0); // [A0]
- findConstructorExpectingIAE(lookup, q2_Type2, void.class); // [A0]
- }
-
- /**
- * Invokes Lookup findConstructor with a method type constructored from the
- * given return and parameter types, expecting IllegalAccessException to be
- * thrown.
- */
- static MethodHandle findConstructorExpectingIAE(Lookup lookup,
- Class<?> clazz,
- Class<?> rtype,
- Class<?>... ptypes) throws Exception {
- try {
- findConstructor(lookup, clazz, rtype, ptypes);
- throw new RuntimeException("IllegalAccessError expected");
- } catch (IllegalAccessException expected) {
- return null;
- }
- }
-
- /**
- * Invokes Lookup findConstructor with a method type constructored from the
- * given return and parameter types.
- */
- static MethodHandle findConstructor(Lookup lookup,
- Class<?> clazz,
- Class<?> rtype,
- Class<?>... ptypes) throws Exception {
- MethodType mt = MethodType.methodType(rtype, ptypes);
- return lookup.findConstructor(clazz, mt);
- }
-
- static void assertTrue(boolean condition) {
- if (!condition)
- throw new RuntimeException();
- }
-
-}
--- a/jdk/test/java/lang/invoke/modules/src/m1/p1/Type1.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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.
- *
- * 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 p1;
-
-public class Type1 {
- public Type1() { }
-}
--- a/jdk/test/java/lang/invoke/modules/src/m1/p2/Type2.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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.
- *
- * 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 p2;
-
-public class Type2 {
- public Type2() { }
-}
--- a/jdk/test/java/lang/invoke/modules/src/m2/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-module m2 {
- exports q1;
-}
--- a/jdk/test/java/lang/invoke/modules/src/m2/q1/Type1.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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.
- *
- * 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 q1;
-
-public class Type1 {
- public Type1() { }
-}
--- a/jdk/test/java/lang/invoke/modules/src/m2/q2/Type2.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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.
- *
- * 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 q2;
-
-public class Type2 {
- public Type2() { }
-}
--- a/jdk/test/java/lang/management/ManagementFactory/DefaultManagementProviderTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/management/ManagementFactory/DefaultManagementProviderTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 @@
* @bug 8151099
* @summary Verify platform MXBeans initialized properly with java.management
* module only. No other management provider
+ * @modules java.management
* @run main/othervm --limit-modules=java.management DefaultManagementProviderTest
*/
import java.lang.management.ManagementFactory;
--- a/jdk/test/java/lang/module/AutomaticModulesTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/module/AutomaticModulesTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,10 +33,10 @@
import java.lang.module.Configuration;
import java.lang.module.FindException;
import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleDescriptor.Exports;
import java.lang.module.ModuleDescriptor.Requires.Modifier;
import java.lang.module.ModuleFinder;
import java.lang.module.ModuleReference;
+import java.lang.module.ResolutionException;
import java.lang.module.ResolvedModule;
import java.lang.reflect.Layer;
import java.lang.reflect.Module;
@@ -137,6 +137,7 @@
assertTrue(mref.isPresent(), mn + " not found");
ModuleDescriptor descriptor = mref.get().descriptor();
+ assertTrue(descriptor.isAutomatic());
assertEquals(descriptor.name(), mn);
if (vs == null) {
assertFalse(descriptor.version().isPresent());
@@ -175,17 +176,14 @@
assertTrue(mref.isPresent(), "m not found");
ModuleDescriptor descriptor = mref.get().descriptor();
+ assertTrue(descriptor.isAutomatic());
assertTrue(descriptor.packages().size() == 2);
assertTrue(descriptor.packages().contains("p"));
assertTrue(descriptor.packages().contains("q"));
- Set<String> exports = descriptor.exports().stream()
- .map(Exports::source)
- .collect(Collectors.toSet());
- assertTrue(exports.size() == 2);
- assertTrue(exports.contains("p"));
- assertTrue(exports.contains("q"));
+ assertTrue(descriptor.exports().isEmpty());
+ assertTrue(descriptor.opens().isEmpty());
}
/**
@@ -201,15 +199,13 @@
assertTrue(mref.isPresent(), "m not found");
ModuleDescriptor descriptor = mref.get().descriptor();
+ assertTrue(descriptor.isAutomatic());
assertTrue(descriptor.packages().size() == 1);
assertTrue(descriptor.packages().contains("p"));
- Set<String> exports = descriptor.exports().stream()
- .map(Exports::source)
- .collect(Collectors.toSet());
- assertTrue(exports.size() == 1);
- assertTrue(exports.contains("p"));
+ assertTrue(descriptor.exports().isEmpty());
+ assertTrue(descriptor.opens().isEmpty());
}
/**
@@ -229,10 +225,10 @@
assertTrue(mref.isPresent(), "m not found");
ModuleDescriptor descriptor = mref.get().descriptor();
+ assertTrue(descriptor.isAutomatic());
- assertTrue(descriptor.packages().size() == 2);
+ assertTrue(descriptor.packages().size() == 1);
assertTrue(descriptor.packages().contains("p"));
- assertTrue(descriptor.packages().contains("p.resources"));
}
/**
@@ -254,9 +250,17 @@
String provider = "p.S1";
Path tmpdir = Files.createTempDirectory(USER_DIR, "tmp");
+
+ // provider class
+ Path providerClass = tmpdir.resolve(provider.replace('.', '/') + ".class");
+ Files.createDirectories(providerClass.getParent());
+ Files.createFile(providerClass);
+
+ // services configuration file
Path services = tmpdir.resolve("META-INF").resolve("services");
Files.createDirectories(services);
Files.write(services.resolve(service), Set.of(provider));
+
Path dir = Files.createTempDirectory(USER_DIR, "mods");
JarUtils.createJarFile(dir.resolve("m.jar"), tmpdir);
@@ -314,7 +318,7 @@
// service type provider type
{ "p.S", "-" },
- { "p.S", ".S1" },
+ { "p.S", "p..S1" },
{ "p.S", "S1." },
};
}
@@ -324,13 +328,41 @@
* values or names.
*/
@Test(dataProvider = "badproviders", expectedExceptions = FindException.class)
- public void testBadProvideNames(String service, String provider)
+ public void testBadProviderNames(String service, String provider)
throws IOException
{
Path tmpdir = Files.createTempDirectory(USER_DIR, "tmp");
+
+ // provider class
+ Path providerClass = tmpdir.resolve(provider.replace('.', '/') + ".class");
+ Files.createDirectories(providerClass.getParent());
+ Files.createFile(providerClass);
+
+ // services configuration file
Path services = tmpdir.resolve("META-INF").resolve("services");
Files.createDirectories(services);
Files.write(services.resolve(service), Set.of(provider));
+
+ Path dir = Files.createTempDirectory(USER_DIR, "mods");
+ JarUtils.createJarFile(dir.resolve("m.jar"), tmpdir);
+
+ // should throw FindException
+ ModuleFinder.of(dir).findAll();
+ }
+
+ /**
+ * Test JAR file with META-INF/services configuration file listing a
+ * provider that is not in the module.
+ */
+ @Test(expectedExceptions = FindException.class)
+ public void testMissingProviderPackage() throws IOException {
+ Path tmpdir = Files.createTempDirectory(USER_DIR, "tmp");
+
+ // services configuration file
+ Path services = tmpdir.resolve("META-INF").resolve("services");
+ Files.createDirectories(services);
+ Files.write(services.resolve("p.S"), Set.of("q.P"));
+
Path dir = Files.createTempDirectory(USER_DIR, "mods");
JarUtils.createJarFile(dir.resolve("m.jar"), tmpdir);
@@ -352,7 +384,8 @@
attrs.put(Attributes.Name.MAIN_CLASS, mainClass);
Path dir = Files.createTempDirectory(USER_DIR, "mods");
- createDummyJarFile(dir.resolve("m.jar"), man);
+ String entry = mainClass.replace('.', '/') + ".class";
+ createDummyJarFile(dir.resolve("m.jar"), man, entry);
ModuleFinder finder = ModuleFinder.of(dir);
@@ -366,20 +399,21 @@
}
- // Main-Class files that do not map to a legal Java identifier
+ // Main-Class files that do not map to a legal qualified type name
@DataProvider(name = "badmainclass")
public Object[][] createBadMainClass() {
return new Object[][]{
+ { "Main", null },
+ { "p..Main", null },
{ "p-.Main", null },
- { ".Main", null }
};
}
/**
- * Test that a JAR file with a Main-Class attribute that is not a valid
- * Java identifier
+ * Test that a JAR file with a Main-Class attribute that is not a qualified
+ * type name.
*/
@Test(dataProvider = "badmainclass", expectedExceptions = FindException.class)
public void testBadMainClass(String mainClass, String ignore) throws IOException {
@@ -389,6 +423,24 @@
attrs.put(Attributes.Name.MAIN_CLASS, mainClass);
Path dir = Files.createTempDirectory(USER_DIR, "mods");
+ String entry = mainClass.replace('.', '/') + ".class";
+ createDummyJarFile(dir.resolve("m.jar"), man, entry);
+
+ // should throw FindException
+ ModuleFinder.of(dir).findAll();
+ }
+
+ /**
+ * Test that a JAR file with a Main-Class attribute that is not in the module
+ */
+ @Test(expectedExceptions = FindException.class)
+ public void testMissingMainClassPackage() throws IOException {
+ Manifest man = new Manifest();
+ Attributes attrs = man.getMainAttributes();
+ attrs.put(Attributes.Name.MANIFEST_VERSION, "1.0.0");
+ attrs.put(Attributes.Name.MAIN_CLASS, "p.Main");
+
+ Path dir = Files.createTempDirectory(USER_DIR, "mods");
createDummyJarFile(dir.resolve("m.jar"), man);
// should throw FindException
@@ -405,7 +457,7 @@
*/
public void testConfiguration1() throws Exception {
ModuleDescriptor descriptor1
- = ModuleDescriptor.module("a")
+ = ModuleDescriptor.newModule("a")
.requires("b")
.requires("c")
.requires("java.base")
@@ -465,13 +517,13 @@
*/
public void testInConfiguration2() throws IOException {
ModuleDescriptor descriptor1
- = ModuleDescriptor.module("a")
+ = ModuleDescriptor.newModule("a")
.requires("b")
.requires("java.base")
.build();
ModuleDescriptor descriptor2
- = ModuleDescriptor.module("b")
+ = ModuleDescriptor.newModule("b")
.requires("c")
.requires("java.base")
.build();
@@ -538,13 +590,13 @@
*/
public void testInConfiguration3() throws IOException {
ModuleDescriptor descriptor1
- = ModuleDescriptor.module("a")
+ = ModuleDescriptor.newModule("a")
.requires("b")
.requires("java.base")
.build();
ModuleDescriptor descriptor2
- = ModuleDescriptor.module("b")
+ = ModuleDescriptor.newModule("b")
.requires(Set.of(Modifier.TRANSITIVE), "c")
.requires("java.base")
.build();
@@ -609,11 +661,67 @@
/**
+ * Basic test of a configuration created with automatic modules
+ * a requires b* and c*
+ * b* contains p
+ * c* contains p
+ */
+ @Test(expectedExceptions = { ResolutionException.class })
+ public void testDuplicateSuppliers1() throws IOException {
+ ModuleDescriptor descriptor
+ = ModuleDescriptor.newModule("a")
+ .requires("b")
+ .requires("c")
+ .build();
+
+ // c and d are automatic modules with the same package
+ Path dir = Files.createTempDirectory(USER_DIR, "mods");
+ createDummyJarFile(dir.resolve("b.jar"), "p/T.class");
+ createDummyJarFile(dir.resolve("c.jar"), "p/T.class");
+
+ // module finder locates 'a' and the modules in the directory
+ ModuleFinder finder
+ = ModuleFinder.compose(ModuleUtils.finderOf(descriptor),
+ ModuleFinder.of(dir));
+
+ Configuration parent = Layer.boot().configuration();
+ resolve(parent, finder, "a");
+ }
+
+
+ /**
+ * Basic test of a configuration created with automatic modules
+ * a contains p, requires b*
+ * b* contains p
+ */
+ @Test(expectedExceptions = { ResolutionException.class })
+ public void testDuplicateSuppliers2() throws IOException {
+ ModuleDescriptor descriptor
+ = ModuleDescriptor.newModule("a")
+ .packages(Set.of("p"))
+ .requires("b")
+ .build();
+
+ // c and d are automatic modules with the same package
+ Path dir = Files.createTempDirectory(USER_DIR, "mods");
+ createDummyJarFile(dir.resolve("b.jar"), "p/T.class");
+
+ // module finder locates 'a' and the modules in the directory
+ ModuleFinder finder
+ = ModuleFinder.compose(ModuleUtils.finderOf(descriptor),
+ ModuleFinder.of(dir));
+
+ Configuration parent = Layer.boot().configuration();
+ resolve(parent, finder, "a");
+ }
+
+
+ /**
* Basic test of Layer containing automatic modules
*/
public void testInLayer() throws IOException {
ModuleDescriptor descriptor
- = ModuleDescriptor.module("a")
+ = ModuleDescriptor.newModule("a")
.requires("b")
.requires("c")
.build();
@@ -664,7 +772,7 @@
// test miscellaneous methods
assertTrue(m.isAutomatic());
- assertFalse(m.isSynthetic());
+ assertFalse(m.modifiers().contains(ModuleDescriptor.Modifier.SYNTHETIC));
assertFalse(m.osName().isPresent());
assertFalse(m.osArch().isPresent());
assertFalse(m.osVersion().isPresent());
@@ -672,12 +780,12 @@
/**
- * Invokes parent.resolveRequires to resolve the given root modules.
+ * Invokes parent.resolve to resolve the given root modules.
*/
static Configuration resolve(Configuration parent,
ModuleFinder finder,
String... roots) {
- return parent.resolveRequires(finder, ModuleFinder.of(), Set.of(roots));
+ return parent.resolve(finder, ModuleFinder.of(), Set.of(roots));
}
/**
--- a/jdk/test/java/lang/module/ConfigurationTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/module/ConfigurationTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,23 +24,26 @@
/**
* @test
* @library /lib/testlibrary
+ * @modules java.base/jdk.internal.misc
* @build ConfigurationTest ModuleUtils
* @run testng ConfigurationTest
* @summary Basic tests for java.lang.module.Configuration
*/
import java.lang.module.Configuration;
+import java.lang.module.FindException;
import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Builder;
import java.lang.module.ModuleDescriptor.Requires;
import java.lang.module.ModuleFinder;
import java.lang.module.ResolutionException;
import java.lang.module.ResolvedModule;
import java.lang.reflect.Layer;
-import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
+import jdk.internal.misc.SharedSecrets;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@@ -48,30 +51,35 @@
@Test
public class ConfigurationTest {
+ /**
+ * Creates a "non-strict" builder for building a module. This allows the
+ * test the create ModuleDescriptor objects that do not require java.base.
+ */
+ private static ModuleDescriptor.Builder newBuilder(String mn) {
+ return SharedSecrets.getJavaLangModuleAccess()
+ .newModuleBuilder(mn, false, Set.of());
+ }
/**
* Basic test of resolver
* m1 requires m2, m2 requires m3
*/
public void testBasic() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m3")
.build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.build();
ModuleFinder finder
= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
- Configuration cf = resolveRequires(finder, "m1");
+ Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 3);
@@ -110,24 +118,21 @@
*/
public void testRequiresTransitive1() {
// m1 requires m2, m2 requires transitive m3
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m3")
.build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.build();
ModuleFinder finder
= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
- Configuration cf = resolveRequires(finder, "m1");
+ Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 3);
@@ -167,18 +172,16 @@
// cf1: m1 and m2, m2 requires transitive m1
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf1 = resolveRequires(finder1, "m2");
+ Configuration cf1 = resolve(finder1, "m2");
assertTrue(cf1.modules().size() == 2);
assertTrue(cf1.findModule("m1").isPresent());
@@ -196,14 +199,13 @@
// cf2: m3, m3 requires m2
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
- Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+ Configuration cf2 = resolve(cf1, finder2, "m3");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m1").isPresent()); // in parent
@@ -231,13 +233,11 @@
// cf1: m1
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .build();
+ ModuleDescriptor descriptor1 = newBuilder("m1").build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
- Configuration cf1 = resolveRequires(finder1, "m1");
+ Configuration cf1 = resolve(finder1, "m1");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m1").isPresent());
@@ -250,19 +250,17 @@
// cf2: m2, m3: m2 requires transitive m1, m3 requires m2
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3);
- Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+ Configuration cf2 = resolve(cf1, finder2, "m3");
assertTrue(cf2.modules().size() == 2);
assertTrue(cf2.findModule("m1").isPresent()); // in parent
@@ -297,13 +295,11 @@
// cf1: m1
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .build();
+ ModuleDescriptor descriptor1 = newBuilder("m1").build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
- Configuration cf1 = resolveRequires(finder1, "m1");
+ Configuration cf1 = resolve(finder1, "m1");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m1").isPresent());
@@ -316,14 +312,13 @@
// cf2: m2 requires transitive m1
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
- Configuration cf2 = resolveRequires(cf1, finder2, "m2");
+ Configuration cf2 = resolve(cf1, finder2, "m2");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m1").isPresent()); // in parent
@@ -340,14 +335,13 @@
// cf3: m3 requires m2
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3);
- Configuration cf3 = resolveRequires(cf2, finder3, "m3");
+ Configuration cf3 = resolve(cf2, finder3, "m3");
assertTrue(cf3.modules().size() == 1);
assertTrue(cf3.findModule("m1").isPresent()); // in parent
@@ -376,18 +370,16 @@
// cf1: m1, m2 requires transitive m1
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf1 = resolveRequires(finder1, "m2");
+ Configuration cf1 = resolve(finder1, "m2");
assertTrue(cf1.modules().size() == 2);
assertTrue(cf1.findModule("m1").isPresent());
@@ -408,20 +400,18 @@
// cf2: m3 requires transitive m2, m4 requires m3
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m2")
.build();
- ModuleDescriptor descriptor4
- = ModuleDescriptor.module("m4")
+ ModuleDescriptor descriptor4 = newBuilder("m4")
.requires("m3")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
- Configuration cf2 = resolveRequires(cf1, finder2, "m3", "m4");
+ Configuration cf2 = resolve(cf1, finder2, "m3", "m4");
assertTrue(cf2.modules().size() == 2);
assertTrue(cf2.findModule("m1").isPresent()); // in parent
@@ -456,28 +446,24 @@
* - Configuration cf3(cf1,cf2): m4 requires m2, m3
*/
public void testRequiresTransitive6() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
- ModuleDescriptor descriptor4
- = ModuleDescriptor.module("m4")
+ ModuleDescriptor descriptor4 = newBuilder("m4")
.requires("m2")
.requires("m3")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf1 = resolveRequires(finder1, "m2");
+ Configuration cf1 = resolve(finder1, "m2");
assertTrue(cf1.modules().size() == 2);
assertTrue(cf1.findModule("m1").isPresent());
assertTrue(cf1.findModule("m2").isPresent());
@@ -485,7 +471,7 @@
assertTrue(cf1.parents().get(0) == Configuration.empty());
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);
- Configuration cf2 = resolveRequires(finder2, "m3");
+ Configuration cf2 = resolve(finder2, "m3");
assertTrue(cf2.modules().size() == 2);
assertTrue(cf2.findModule("m3").isPresent());
assertTrue(cf2.findModule("m1").isPresent());
@@ -493,7 +479,7 @@
assertTrue(cf2.parents().get(0) == Configuration.empty());
ModuleFinder finder3 = ModuleUtils.finderOf(descriptor4);
- Configuration cf3 = Configuration.resolveRequires(finder3,
+ Configuration cf3 = Configuration.resolve(finder3,
List.of(cf1, cf2),
ModuleFinder.of(),
Set.of("m4"));
@@ -522,14 +508,13 @@
* resolve m1
*/
public void testRequiresStatic1() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires(Set.of(Requires.Modifier.STATIC), "m2")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
- Configuration cf = resolveRequires(finder, "m1");
+ Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 1);
@@ -545,18 +530,16 @@
* resolve m1
*/
public void testRequiresStatic2() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires(Set.of(Requires.Modifier.STATIC), "m2")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf = resolveRequires(finder, "m1");
+ Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 1);
@@ -572,18 +555,16 @@
* resolve m1, m2
*/
public void testRequiresStatic3() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires(Set.of(Requires.Modifier.STATIC), "m2")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf = resolveRequires(finder, "m1", "m2");
+ Configuration cf = resolve(finder, "m1", "m2");
assertTrue(cf.modules().size() == 2);
@@ -604,25 +585,22 @@
* m3
*/
public void testRequiresStatic4() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
.requires("m3")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.STATIC), "m3")
.build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.build();
ModuleFinder finder
- = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
-
- Configuration cf = resolveRequires(finder, "m1");
+ = ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
+
+ Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 3);
@@ -648,31 +626,28 @@
* - Configuration cf2: m3 requires m1, requires static m2
*/
public void testRequiresStatic5() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf1 = resolveRequires(finder1, "m1", "m2");
+ Configuration cf1 = resolve(finder1, "m1", "m2");
assertTrue(cf1.modules().size() == 2);
assertTrue(cf1.findModule("m1").isPresent());
assertTrue(cf1.findModule("m2").isPresent());
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m1")
.requires(Set.of(Requires.Modifier.STATIC), "m2")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
- Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+ Configuration cf2 = resolve(cf1, finder2, "m3");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m3").isPresent());
@@ -694,26 +669,24 @@
* - Configuration cf2: m3 requires m1, requires static m2
*/
public void testRequiresStatic6() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
- Configuration cf1 = resolveRequires(finder1, "m1");
+ Configuration cf1 = resolve(finder1, "m1");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m1").isPresent());
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m1")
.requires(Set.of(Requires.Modifier.STATIC), "m2")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
- Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+ Configuration cf2 = resolve(cf1, finder2, "m3");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m3").isPresent());
@@ -735,21 +708,19 @@
public void testRequiresStatic7() {
ModuleDescriptor descriptor1 = null; // not observable
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE,
Requires.Modifier.STATIC),
"m1")
.build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor2, descriptor3);
- Configuration cf = resolveRequires(finder, "m3");
+ Configuration cf = resolve(finder, "m3");
assertTrue(cf.modules().size() == 2);
assertTrue(cf.findModule("m2").isPresent());
@@ -770,8 +741,7 @@
public void testRequiresStatic8() {
ModuleDescriptor descriptor1 = null; // not observable
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE,
Requires.Modifier.STATIC),
"m1")
@@ -779,21 +749,20 @@
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2);
- Configuration cf1 = resolveRequires(finder1, "m2");
+ Configuration cf1 = resolve(finder1, "m2");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m2").isPresent());
ResolvedModule m2 = cf1.findModule("m2").get();
assertTrue(m2.reads().isEmpty());
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
- Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+ Configuration cf2 = resolve(cf1, finder2, "m3");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m3").isPresent());
@@ -810,22 +779,19 @@
*/
public void testServiceBinding1() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.exports("p")
.uses("p.S")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m1")
- .contains("q")
- .provides("p.S", "q.T")
+ .provides("p.S", List.of("q.T"))
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf = resolveRequiresAndUses(finder, "m1");
+ Configuration cf = resolveAndBind(finder, "m1");
assertTrue(cf.modules().size() == 2);
assertTrue(cf.findModule("m1").isPresent());
@@ -853,31 +819,26 @@
*/
public void testServiceBinding2() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.exports("p")
.uses("p.S1")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m1")
.uses("p.S2")
- .contains("q")
- .provides("p.S1", "q.Service1Impl")
+ .provides("p.S1", List.of("q.Service1Impl"))
.build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m1")
- .contains("q")
- .provides("p.S2", "q.Service2Impl")
+ .provides("p.S2", List.of("q.Service2Impl"))
.build();
ModuleFinder finder
= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
- Configuration cf = resolveRequiresAndUses(finder, "m1");
+ Configuration cf = resolveAndBind(finder, "m1");
assertTrue(cf.modules().size() == 3);
assertTrue(cf.findModule("m1").isPresent());
@@ -912,29 +873,26 @@
*/
public void testServiceBindingWithConfigurations1() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.exports("p")
.uses("p.S")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
- Configuration cf1 = resolveRequires(finder1, "m1");
+ Configuration cf1 = resolve(finder1, "m1");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m1").isPresent());
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m1")
- .contains("q")
- .provides("p.S", "q.T")
+ .provides("p.S", List.of("q.T"))
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
- Configuration cf2 = resolveRequiresAndUses(cf1, finder2); // no roots
+ Configuration cf2 = resolveAndBind(cf1, finder2); // no roots
assertTrue(cf2.parents().size() == 1);
assertTrue(cf2.parents().get(0) == cf1);
@@ -961,47 +919,39 @@
*/
public void testServiceBindingWithConfigurations2() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.exports("p")
.uses("p.S")
- .contains("p1")
- .provides("p.S", "p1.ServiceImpl")
+ .provides("p.S", List.of("p1.ServiceImpl"))
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m1")
- .contains("p2")
- .provides("p.S", "p2.ServiceImpl")
+ .provides("p.S", List.of("p2.ServiceImpl"))
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf1 = resolveRequiresAndUses(finder1, "m1");
+ Configuration cf1 = resolveAndBind(finder1, "m1");
assertTrue(cf1.modules().size() == 2);
assertTrue(cf1.findModule("m1").isPresent());
assertTrue(cf1.findModule("m2").isPresent());
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m1")
- .contains("p3")
- .provides("p.S", "p3.ServiceImpl")
+ .provides("p.S", List.of("p3.ServiceImpl"))
.build();
- ModuleDescriptor descriptor4
- = ModuleDescriptor.module("m4")
+ ModuleDescriptor descriptor4 = newBuilder("m4")
.requires("m1")
- .contains("p4")
- .provides("p.S", "p4.ServiceImpl")
+ .provides("p.S", List.of("p4.ServiceImpl"))
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
- Configuration cf2 = resolveRequiresAndUses(cf1, finder2); // no roots
+ Configuration cf2 = resolveAndBind(cf1, finder2); // no roots
assertTrue(cf2.parents().size() == 1);
assertTrue(cf2.parents().get(0) == cf1);
@@ -1037,22 +987,19 @@
*/
public void testServiceBindingWithConfigurations3() {
- ModuleDescriptor service
- = ModuleDescriptor.module("s")
+ ModuleDescriptor service = newBuilder("s")
.exports("p")
.build();
- ModuleDescriptor provider_v1
- = ModuleDescriptor.module("p")
+ ModuleDescriptor provider_v1 = newBuilder("p")
.version("1.0")
.requires("s")
- .contains("q")
- .provides("p.S", "q.T")
+ .provides("p.S", List.of("q.T"))
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(service, provider_v1);
- Configuration cf1 = resolveRequires(finder1, "p");
+ Configuration cf1 = resolve(finder1, "p");
assertTrue(cf1.modules().size() == 2);
assertTrue(cf1.findModule("s").isPresent());
@@ -1063,18 +1010,15 @@
assertEquals(p.reference().descriptor(), provider_v1);
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("s")
.uses("p.S")
.build();
- ModuleDescriptor provider_v2
- = ModuleDescriptor.module("p")
+ ModuleDescriptor provider_v2 = newBuilder("p")
.version("2.0")
.requires("s")
- .contains("q")
- .provides("p.S", "q.T")
+ .provides("p.S", List.of("q.T"))
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, provider_v2);
@@ -1082,7 +1026,7 @@
// finder2 is the before ModuleFinder and so p@2.0 should be located
- Configuration cf2 = resolveRequiresAndUses(cf1, finder2, "m1");
+ Configuration cf2 = resolveAndBind(cf1, finder2, "m1");
assertTrue(cf2.parents().size() == 1);
assertTrue(cf2.parents().get(0) == cf1);
@@ -1097,7 +1041,7 @@
// finder2 is the after ModuleFinder and so p@2.0 should not be located
// as module p is in parent configuration.
- cf2 = resolveRequiresAndUses(cf1, ModuleFinder.of(), finder2, "m1");
+ cf2 = resolveAndBind(cf1, ModuleFinder.of(), finder2, "m1");
assertTrue(cf2.parents().size() == 1);
assertTrue(cf2.parents().get(0) == cf1);
@@ -1117,25 +1061,22 @@
*/
public void testWithTwoFinders1() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
.build();
- ModuleDescriptor descriptor2_v1
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2_v1 = newBuilder("m2")
.version("1.0")
.build();
- ModuleDescriptor descriptor2_v2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2_v2 = newBuilder("m2")
.version("2.0")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor2_v1);
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor2_v2);
- Configuration cf = resolveRequires(finder1, finder2, "m1");
+ Configuration cf = resolve(finder1, finder2, "m1");
assertTrue(cf.modules().size() == 2);
assertTrue(cf.findModule("m1").isPresent());
@@ -1157,30 +1098,25 @@
*/
public void testWithTwoFinders2() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.exports("p")
.uses("p.S")
.build();
- ModuleDescriptor descriptor2_v1
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2_v1 = newBuilder("m2")
.requires("m1")
- .contains("q")
- .provides("p.S", "q.T")
+ .provides("p.S", List.of("q.T"))
.build();
- ModuleDescriptor descriptor2_v2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2_v2 = newBuilder("m2")
.requires("m1")
- .contains("q")
- .provides("p.S", "q.T")
+ .provides("p.S", List.of("q.T"))
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2_v1);
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2_v2);
- Configuration cf = resolveRequiresAndUses(finder1, finder2, "m1");
+ Configuration cf = resolveAndBind(finder1, finder2, "m1");
assertTrue(cf.modules().size() == 2);
assertTrue(cf.findModule("m1").isPresent());
@@ -1200,18 +1136,17 @@
*/
public void testResolvedInParent1() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
- Configuration cf1 = resolveRequires(finder, "m1");
+ Configuration cf1 = resolve(finder, "m1");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m1").isPresent());
- Configuration cf2 = resolveRequires(cf1, finder, "m1");
+ Configuration cf2 = resolve(cf1, finder, "m1");
assertTrue(cf2.modules().size() == 1);
}
@@ -1223,26 +1158,23 @@
*/
public void testResolvedInParent2() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .build();
+ ModuleDescriptor descriptor1 = newBuilder("m1").build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
- Configuration cf1 = resolveRequires(finder1, "m1");
+ Configuration cf1 = resolve(finder1, "m1");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m1").isPresent());
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m1")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
- Configuration cf2 = resolveRequires(cf1, ModuleFinder.of(), finder2, "m2");
+ Configuration cf2 = resolve(cf1, ModuleFinder.of(), finder2, "m2");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m2").isPresent());
@@ -1268,29 +1200,28 @@
public void testResolvedInMultipleParents1() {
// Configuration cf1: m1
- ModuleDescriptor descriptor1 = ModuleDescriptor.module("m1").build();
- Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
+ ModuleDescriptor descriptor1 = newBuilder("m1").build();
+ Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
assertEquals(cf1.parents(), List.of(Configuration.empty()));
assertTrue(cf1.findModule("m1").isPresent());
ResolvedModule m1 = cf1.findModule("m1").get();
assertTrue(m1.configuration() == cf1);
// Configuration cf2: m2
- ModuleDescriptor descriptor2 = ModuleDescriptor.module("m2").build();
- Configuration cf2 = resolveRequires(ModuleUtils.finderOf(descriptor2), "m2");
+ ModuleDescriptor descriptor2 = newBuilder("m2").build();
+ Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2");
assertEquals(cf2.parents(), List.of(Configuration.empty()));
assertTrue(cf2.findModule("m2").isPresent());
ResolvedModule m2 = cf2.findModule("m2").get();
assertTrue(m2.configuration() == cf2);
// Configuration cf3(cf1,cf2): m3 requires m1 and m2
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m1")
.requires("m2")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor3);
- Configuration cf3 = Configuration.resolveRequires(
+ Configuration cf3 = Configuration.resolve(
finder,
List.of(cf1, cf2), // parents
ModuleFinder.of(),
@@ -1319,19 +1250,18 @@
*/
public void testResolvedInMultipleParents2() {
// Configuration cf1: m1
- ModuleDescriptor descriptor1 = ModuleDescriptor.module("m1").build();
- Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
+ ModuleDescriptor descriptor1 = newBuilder("m1").build();
+ Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
assertEquals(cf1.parents(), List.of(Configuration.empty()));
assertTrue(cf1.findModule("m1").isPresent());
ResolvedModule m1 = cf1.findModule("m1").get();
assertTrue(m1.configuration() == cf1);
// Configuration cf2(cf1): m2 requires m1
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m1")
.build();
- Configuration cf2 = Configuration.resolveRequires(
+ Configuration cf2 = Configuration.resolve(
ModuleUtils.finderOf(descriptor2),
List.of(cf1), // parents
ModuleFinder.of(),
@@ -1342,11 +1272,10 @@
assertTrue(m2.configuration() == cf2);
// Configuration cf3(cf1): m3 requires m1
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m1")
.build();
- Configuration cf3 = Configuration.resolveRequires(
+ Configuration cf3 = Configuration.resolve(
ModuleUtils.finderOf(descriptor3),
List.of(cf1), // parents
ModuleFinder.of(),
@@ -1357,13 +1286,12 @@
assertTrue(m3.configuration() == cf3);
// Configuration cf4(cf2,cf3): m4 requires m1,m2,m3
- ModuleDescriptor descriptor4
- = ModuleDescriptor.module("m4")
+ ModuleDescriptor descriptor4 = newBuilder("m4")
.requires("m1")
.requires("m2")
.requires("m3")
.build();
- Configuration cf4 = Configuration.resolveRequires(
+ Configuration cf4 = Configuration.resolve(
ModuleUtils.finderOf(descriptor4),
List.of(cf2, cf3), // parents
ModuleFinder.of(),
@@ -1395,35 +1323,34 @@
ModuleDescriptor descriptor1, descriptor2, descriptor3;
// Configuration cf1: m1@1
- descriptor1 = ModuleDescriptor.module("m1").version("1").build();
- Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
+ descriptor1 = newBuilder("m1").version("1").build();
+ Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
assertEquals(cf1.parents(), List.of(Configuration.empty()));
// Configuration cf2: m1@2, m2@2
- descriptor1 = ModuleDescriptor.module("m1").version("2").build();
- descriptor2 = ModuleDescriptor.module("m2").version("2").build();
- Configuration cf2 = resolveRequires(
+ descriptor1 = newBuilder("m1").version("2").build();
+ descriptor2 = newBuilder("m2").version("2").build();
+ Configuration cf2 = resolve(
ModuleUtils.finderOf(descriptor1, descriptor2),
"m1", "m2");
assertEquals(cf2.parents(), List.of(Configuration.empty()));
// Configuration cf3: m1@3, m2@3, m3@3
- descriptor1 = ModuleDescriptor.module("m1").version("3").build();
- descriptor2 = ModuleDescriptor.module("m2").version("3").build();
- descriptor3 = ModuleDescriptor.module("m3").version("3").build();
- Configuration cf3 = resolveRequires(
+ descriptor1 = newBuilder("m1").version("3").build();
+ descriptor2 = newBuilder("m2").version("3").build();
+ descriptor3 = newBuilder("m3").version("3").build();
+ Configuration cf3 = resolve(
ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3),
"m1", "m2", "m3");
assertEquals(cf3.parents(), List.of(Configuration.empty()));
// Configuration cf4(cf1,cf2,cf3): m4 requires m1,m2,m3
- ModuleDescriptor descriptor4
- = ModuleDescriptor.module("m4")
+ ModuleDescriptor descriptor4 = newBuilder("m4")
.requires("m1")
.requires("m2")
.requires("m3")
.build();
- Configuration cf4 = Configuration.resolveRequires(
+ Configuration cf4 = Configuration.resolve(
ModuleUtils.finderOf(descriptor4),
List.of(cf1, cf2, cf3), // parents
ModuleFinder.of(),
@@ -1470,17 +1397,15 @@
* configuration.
*/
public void testOverriding1() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .build();
+ ModuleDescriptor descriptor1 = newBuilder("m1").build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
- Configuration cf1 = resolveRequires(finder, "m1");
+ Configuration cf1 = resolve(finder, "m1");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m1").isPresent());
- Configuration cf2 = resolveRequires(cf1, finder, "m1");
+ Configuration cf2 = resolve(cf1, finder, "m1");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m1").isPresent());
}
@@ -1490,24 +1415,24 @@
* configuration.
*/
public void testOverriding2() {
- ModuleDescriptor descriptor1 = ModuleDescriptor.module("m1").build();
- Configuration cf1 = resolveRequires(ModuleUtils.finderOf(descriptor1), "m1");
+ ModuleDescriptor descriptor1 = newBuilder("m1").build();
+ Configuration cf1 = resolve(ModuleUtils.finderOf(descriptor1), "m1");
assertTrue(cf1.modules().size() == 1);
assertTrue(cf1.findModule("m1").isPresent());
- ModuleDescriptor descriptor2 = ModuleDescriptor.module("m2").build();
- Configuration cf2 = resolveRequires(ModuleUtils.finderOf(descriptor2), "m2");
+ ModuleDescriptor descriptor2 = newBuilder("m2").build();
+ Configuration cf2 = resolve(ModuleUtils.finderOf(descriptor2), "m2");
assertTrue(cf2.modules().size() == 1);
assertTrue(cf2.findModule("m2").isPresent());
- ModuleDescriptor descriptor3 = ModuleDescriptor.module("m3").build();
- Configuration cf3 = resolveRequires(ModuleUtils.finderOf(descriptor3), "m3");
+ ModuleDescriptor descriptor3 = newBuilder("m3").build();
+ Configuration cf3 = resolve(ModuleUtils.finderOf(descriptor3), "m3");
assertTrue(cf3.modules().size() == 1);
assertTrue(cf3.findModule("m3").isPresent());
// override m2, m1 and m3 should be found in parent configurations
ModuleFinder finder = ModuleUtils.finderOf(descriptor2);
- Configuration cf4 = Configuration.resolveRequires(
+ Configuration cf4 = Configuration.resolve(
finder,
List.of(cf1, cf2, cf3),
ModuleFinder.of(),
@@ -1530,18 +1455,16 @@
*/
public void testOverriding3() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf1 = resolveRequires(finder1, "m2");
+ Configuration cf1 = resolve(finder1, "m2");
assertTrue(cf1.modules().size() == 2);
assertTrue(cf1.findModule("m1").isPresent());
@@ -1549,14 +1472,13 @@
// cf2: m3 requires m2, m1
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor1, descriptor3);
- Configuration cf2 = resolveRequires(cf1, finder2, "m1", "m3");
+ Configuration cf2 = resolve(cf1, finder2, "m1", "m3");
assertTrue(cf2.parents().size() == 1);
assertTrue(cf2.parents().get(0) == cf1);
@@ -1585,64 +1507,58 @@
/**
* Root module not found
*/
- @Test(expectedExceptions = { ResolutionException.class })
+ @Test(expectedExceptions = { FindException.class })
public void testRootNotFound() {
- resolveRequires(ModuleFinder.of(), "m1");
+ resolve(ModuleFinder.of(), "m1");
}
/**
* Direct dependency not found
*/
- @Test(expectedExceptions = { ResolutionException.class })
+ @Test(expectedExceptions = { FindException.class })
public void testDirectDependencyNotFound() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1").requires("m2").build();
+ ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
- resolveRequires(finder, "m1");
+ resolve(finder, "m1");
}
/**
* Transitive dependency not found
*/
- @Test(expectedExceptions = { ResolutionException.class })
+ @Test(expectedExceptions = { FindException.class })
public void testTransitiveDependencyNotFound() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1").requires("m2").build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2").requires("m3").build();
+ ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();
+ ModuleDescriptor descriptor2 = newBuilder("m2").requires("m3").build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
- resolveRequires(finder, "m1");
+ resolve(finder, "m1");
}
/**
* Service provider dependency not found
*/
- @Test(expectedExceptions = { ResolutionException.class })
+ @Test(expectedExceptions = { FindException.class })
public void testServiceProviderDependencyNotFound() {
// service provider dependency (on m3) not found
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.exports("p")
.uses("p.S")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m1")
.requires("m3")
- .contains("q")
- .provides("p.S", "q.T")
+ .provides("p.S", List.of("q.T"))
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
// should throw ResolutionException because m3 is not found
- Configuration cf = resolveRequiresAndUses(finder, "m1");
+ Configuration cf = resolveAndBind(finder, "m1");
}
@@ -1651,15 +1567,12 @@
*/
@Test(expectedExceptions = { ResolutionException.class })
public void testSimpleCycle() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1").requires("m2").build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2").requires("m3").build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3").requires("m1").build();
+ ModuleDescriptor descriptor1 = newBuilder("m1").requires("m2").build();
+ ModuleDescriptor descriptor2 = newBuilder("m2").requires("m3").build();
+ ModuleDescriptor descriptor3 = newBuilder("m3").requires("m1").build();
ModuleFinder finder
= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
- resolveRequires(finder, "m1");
+ resolve(finder, "m1");
}
/**
@@ -1668,20 +1581,16 @@
@Test(expectedExceptions = { ResolutionException.class })
public void testCycleInProvider() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.exports("p")
.uses("p.S")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m1")
.requires("m3")
- .contains("q")
- .provides("p.S", "q.T")
+ .provides("p.S", List.of("q.T"))
.build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
@@ -1689,7 +1598,7 @@
= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
// should throw ResolutionException because of the m2 <--> m3 cycle
- resolveRequiresAndUses(finder, "m1");
+ resolveAndBind(finder, "m1");
}
@@ -1699,19 +1608,16 @@
@Test(expectedExceptions = { ResolutionException.class })
public void testPackageSuppliedByTwoOthers() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
.requires("m3")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.exports("p")
.build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.exports("p", Set.of("m1"))
.build();
@@ -1719,7 +1625,7 @@
= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
// m2 and m3 export package p to module m1
- resolveRequires(finder, "m1");
+ resolve(finder, "m1");
}
@@ -1730,21 +1636,19 @@
@Test(expectedExceptions = { ResolutionException.class })
public void testPackageSuppliedBySelfAndOther() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
- .contains("p")
+ .packages(Set.of("p"))
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.exports("p")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
// m1 contains package p, module m2 exports package p to m1
- resolveRequires(finder, "m1");
+ resolve(finder, "m1");
}
@@ -1753,20 +1657,18 @@
* a module that also contains a package p.
*/
public void testContainsPackageInSelfAndOther() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
- .contains("p")
+ .packages(Set.of("p"))
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
- .contains("p")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
+ .packages(Set.of("p"))
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf = resolveRequires(finder, "m1");
+ Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 2);
assertTrue(cf.findModule("m1").isPresent());
@@ -1787,8 +1689,7 @@
*/
@Test(expectedExceptions = { ResolutionException.class })
public void testExportSamePackageAsBootLayer() {
- ModuleDescriptor descriptor
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor = newBuilder("m1")
.requires("java.base")
.exports("java.lang")
.build();
@@ -1798,7 +1699,7 @@
Configuration bootConfiguration = Layer.boot().configuration();
// m1 contains package java.lang, java.base exports package java.lang to m1
- resolveRequires(bootConfiguration, finder, "m1");
+ resolve(bootConfiguration, finder, "m1");
}
@@ -1806,15 +1707,14 @@
* Test "uses p.S" where p is contained in the same module.
*/
public void testContainsService1() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .contains("p")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
+ .packages(Set.of("p"))
.uses("p.S")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
- Configuration cf = resolveRequires(finder, "m1");
+ Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 1);
assertTrue(cf.findModule("m1").isPresent());
@@ -1826,13 +1726,11 @@
*/
@Test(expectedExceptions = { ResolutionException.class })
public void testContainsService2() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .contains("p")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
+ .packages(Set.of("p"))
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m1")
.uses("p.S")
.build();
@@ -1840,7 +1738,7 @@
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
// m2 does not read a module that exports p
- resolveRequires(finder, "m2");
+ resolve(finder, "m2");
}
@@ -1848,16 +1746,14 @@
* Test "provides p.S" where p is contained in the same module.
*/
public void testContainsService3() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .contains("p")
- .contains("q")
- .provides("p.S", "q.S1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
+ .packages(Set.of("p", "q"))
+ .provides("p.S", List.of("q.S1"))
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
- Configuration cf = resolveRequires(finder, "m1");
+ Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 1);
assertTrue(cf.findModule("m1").isPresent());
@@ -1869,22 +1765,19 @@
*/
@Test(expectedExceptions = { ResolutionException.class })
public void testContainsService4() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .contains("p")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
+ .packages(Set.of("p"))
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m1")
- .contains("q")
- .provides("p.S", "q.S1")
+ .provides("p.S", List.of("q.S1"))
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
// m2 does not read a module that exports p
- resolveRequires(finder, "m2");
+ resolve(finder, "m2");
}
@@ -1893,15 +1786,14 @@
*/
@Test(expectedExceptions = { ResolutionException.class })
public void testServiceTypePackageNotExported1() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.uses("p.S")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
// m1 does not read a module that exports p
- resolveRequires(finder, "m1");
+ resolve(finder, "m1");
}
@@ -1910,40 +1802,14 @@
*/
@Test(expectedExceptions = { ResolutionException.class })
public void testServiceTypePackageNotExported2() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .contains("q")
- .provides("p.S", "q.T")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
+ .provides("p.S", List.of("q.T"))
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
// m1 does not read a module that exports p
- resolveRequires(finder, "m1");
- }
-
-
- /**
- * Test "provides p.S with q.T" where q.T is not local
- */
- @Test(expectedExceptions = { ResolutionException.class })
- public void testProviderPackageNotLocal() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .exports("p")
- .exports("q")
- .build();
-
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
- .requires("m1")
- .provides("p.S", "q.T")
- .build();
-
- ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
-
- // q.T not in module m2
- resolveRequires(finder, "m2");
+ resolve(finder, "m1");
}
@@ -2007,34 +1873,17 @@
@Test(dataProvider = "platformmatch")
public void testPlatformMatch(String s1, String s2) {
- ModuleDescriptor.Builder builder
- = ModuleDescriptor.module("m1").requires("m2");
-
- String[] s = s1.split("-");
- if (!s[0].equals("*"))
- builder.osName(s[0]);
- if (!s[1].equals("*"))
- builder.osArch(s[1]);
- if (!s[2].equals("*"))
- builder.osVersion(s[2]);
-
+ Builder builder = newBuilder("m1").requires("m2");
+ addPlatformConstraints(builder, s1);
ModuleDescriptor descriptor1 = builder.build();
- builder = ModuleDescriptor.module("m2");
-
- s = s2.split("-");
- if (!s[0].equals("*"))
- builder.osName(s[0]);
- if (!s[1].equals("*"))
- builder.osArch(s[1]);
- if (!s[2].equals("*"))
- builder.osVersion(s[2]);
-
+ builder = newBuilder("m2");
+ addPlatformConstraints(builder, s2);
ModuleDescriptor descriptor2 = builder.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf = resolveRequires(finder, "m1");
+ Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 2);
assertTrue(cf.findModule("m1").isPresent());
@@ -2046,7 +1895,7 @@
* platforms.
*/
@Test(dataProvider = "platformmismatch",
- expectedExceptions = ResolutionException.class )
+ expectedExceptions = FindException.class )
public void testPlatformMisMatch(String s1, String s2) {
testPlatformMatch(s1, s2);
}
@@ -2057,16 +1906,67 @@
@Test(expectedExceptions = { IllegalArgumentException.class })
public void testResolveRequiresWithNoParents() {
ModuleFinder empty = ModuleFinder.of();
- Configuration.resolveRequires(empty, List.of(), empty, Set.of());
+ Configuration.resolve(empty, List.of(), empty, Set.of());
}
@Test(expectedExceptions = { IllegalArgumentException.class })
public void testResolveRequiresAndUsesWithNoParents() {
ModuleFinder empty = ModuleFinder.of();
- Configuration.resolveRequiresAndUses(empty, List.of(), empty, Set.of());
+ Configuration.resolveAndBind(empty, List.of(), empty, Set.of());
}
+ // parents with modules for specific platforms
+
+ @Test(dataProvider = "platformmatch")
+ public void testResolveRequiresWithCompatibleParents(String s1, String s2) {
+ Builder builder = newBuilder("m1");
+ addPlatformConstraints(builder, s1);
+ ModuleDescriptor descriptor1 = builder.build();
+
+ builder = newBuilder("m2");
+ addPlatformConstraints(builder, s2);
+ ModuleDescriptor descriptor2 = builder.build();
+
+ ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
+ Configuration cf1 = resolve(finder1, "m1");
+
+ ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
+ Configuration cf2 = resolve(finder2, "m2");
+
+ Configuration cf3 = Configuration.resolve(ModuleFinder.of(),
+ List.of(cf1, cf2),
+ ModuleFinder.of(),
+ Set.of());
+ assertTrue(cf3.parents().size() == 2);
+ }
+
+ @Test(dataProvider = "platformmismatch",
+ expectedExceptions = IllegalArgumentException.class )
+ public void testResolveRequiresWithConflictingParents(String s1, String s2) {
+ Builder builder = newBuilder("m1");
+ addPlatformConstraints(builder, s1);
+ ModuleDescriptor descriptor1 = builder.build();
+
+ builder = newBuilder("m2");
+ addPlatformConstraints(builder, s2);
+ ModuleDescriptor descriptor2 = builder.build();
+
+ ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
+ Configuration cf1 = resolve(finder1, "m1");
+
+ ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
+ Configuration cf2 = resolve(finder2, "m2");
+
+ // should throw IAE
+ Configuration.resolve(ModuleFinder.of(),
+ List.of(cf1, cf2),
+ ModuleFinder.of(),
+ Set.of());
+ }
+
+
+
// null handling
// finder1, finder2, roots
@@ -2074,72 +1974,72 @@
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresWithNull1() {
- resolveRequires((ModuleFinder)null, ModuleFinder.of());
+ resolve((ModuleFinder)null, ModuleFinder.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresWithNull2() {
- resolveRequires(ModuleFinder.of(), (ModuleFinder)null);
+ resolve(ModuleFinder.of(), (ModuleFinder)null);
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresWithNull3() {
Configuration empty = Configuration.empty();
- Configuration.resolveRequires(null, List.of(empty), ModuleFinder.of(), Set.of());
+ Configuration.resolve(null, List.of(empty), ModuleFinder.of(), Set.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresWithNull4() {
ModuleFinder empty = ModuleFinder.of();
- Configuration.resolveRequires(empty, null, empty, Set.of());
+ Configuration.resolve(empty, null, empty, Set.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresWithNull5() {
Configuration cf = Layer.boot().configuration();
- Configuration.resolveRequires(ModuleFinder.of(), List.of(cf), null, Set.of());
+ Configuration.resolve(ModuleFinder.of(), List.of(cf), null, Set.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresWithNull6() {
ModuleFinder empty = ModuleFinder.of();
Configuration cf = Layer.boot().configuration();
- Configuration.resolveRequires(empty, List.of(cf), empty, null);
+ Configuration.resolve(empty, List.of(cf), empty, null);
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresAndUsesWithNull1() {
- resolveRequiresAndUses((ModuleFinder) null, ModuleFinder.of());
+ resolveAndBind((ModuleFinder) null, ModuleFinder.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresAndUsesWithNull2() {
- resolveRequiresAndUses(ModuleFinder.of(), (ModuleFinder) null);
+ resolveAndBind(ModuleFinder.of(), (ModuleFinder) null);
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresAndUsesWithNull3() {
Configuration empty = Configuration.empty();
- Configuration.resolveRequiresAndUses(null, List.of(empty), ModuleFinder.of(), Set.of());
+ Configuration.resolveAndBind(null, List.of(empty), ModuleFinder.of(), Set.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresAndUsesWithNull4() {
ModuleFinder empty = ModuleFinder.of();
- Configuration.resolveRequiresAndUses(empty, null, empty, Set.of());
+ Configuration.resolveAndBind(empty, null, empty, Set.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresAndUsesWithNull5() {
Configuration cf = Layer.boot().configuration();
- Configuration.resolveRequiresAndUses(ModuleFinder.of(), List.of(cf), null, Set.of());
+ Configuration.resolveAndBind(ModuleFinder.of(), List.of(cf), null, Set.of());
}
@Test(expectedExceptions = { NullPointerException.class })
public void testResolveRequiresAndUsesWithNull6() {
ModuleFinder empty = ModuleFinder.of();
Configuration cf = Layer.boot().configuration();
- Configuration.resolveRequiresAndUses(empty, List.of(cf), empty, null);
+ Configuration.resolveAndBind(empty, List.of(cf), empty, null);
}
@Test(expectedExceptions = { NullPointerException.class })
@@ -2165,58 +2065,58 @@
/**
- * Invokes parent.resolveRequires(...)
+ * Invokes parent.resolve(...)
*/
- private Configuration resolveRequires(Configuration parent,
- ModuleFinder before,
- ModuleFinder after,
- String... roots) {
- return parent.resolveRequires(before, after, Set.of(roots));
+ private Configuration resolve(Configuration parent,
+ ModuleFinder before,
+ ModuleFinder after,
+ String... roots) {
+ return parent.resolve(before, after, Set.of(roots));
}
- private Configuration resolveRequires(Configuration parent,
- ModuleFinder before,
- String... roots) {
- return resolveRequires(parent, before, ModuleFinder.of(), roots);
+ private Configuration resolve(Configuration parent,
+ ModuleFinder before,
+ String... roots) {
+ return resolve(parent, before, ModuleFinder.of(), roots);
}
- private Configuration resolveRequires(ModuleFinder before,
- ModuleFinder after,
- String... roots) {
- return resolveRequires(Configuration.empty(), before, after, roots);
+ private Configuration resolve(ModuleFinder before,
+ ModuleFinder after,
+ String... roots) {
+ return resolve(Configuration.empty(), before, after, roots);
}
- private Configuration resolveRequires(ModuleFinder before,
- String... roots) {
- return resolveRequires(Configuration.empty(), before, roots);
+ private Configuration resolve(ModuleFinder before,
+ String... roots) {
+ return resolve(Configuration.empty(), before, roots);
}
/**
- * Invokes parent.resolveRequiresAndUses(...)
+ * Invokes parent.resolveAndBind(...)
*/
- private Configuration resolveRequiresAndUses(Configuration parent,
- ModuleFinder before,
- ModuleFinder after,
- String... roots) {
- return parent.resolveRequiresAndUses(before, after, Set.of(roots));
+ private Configuration resolveAndBind(Configuration parent,
+ ModuleFinder before,
+ ModuleFinder after,
+ String... roots) {
+ return parent.resolveAndBind(before, after, Set.of(roots));
}
- private Configuration resolveRequiresAndUses(Configuration parent,
- ModuleFinder before,
- String... roots) {
- return resolveRequiresAndUses(parent, before, ModuleFinder.of(), roots);
+ private Configuration resolveAndBind(Configuration parent,
+ ModuleFinder before,
+ String... roots) {
+ return resolveAndBind(parent, before, ModuleFinder.of(), roots);
}
- private Configuration resolveRequiresAndUses(ModuleFinder before,
- ModuleFinder after,
- String... roots) {
- return resolveRequiresAndUses(Configuration.empty(), before, after, roots);
+ private Configuration resolveAndBind(ModuleFinder before,
+ ModuleFinder after,
+ String... roots) {
+ return resolveAndBind(Configuration.empty(), before, after, roots);
}
- private Configuration resolveRequiresAndUses(ModuleFinder before,
- String... roots) {
- return resolveRequiresAndUses(Configuration.empty(), before, roots);
+ private Configuration resolveAndBind(ModuleFinder before,
+ String... roots) {
+ return resolveAndBind(Configuration.empty(), before, roots);
}
@@ -2234,5 +2134,17 @@
.anyMatch(mn2::equals);
}
-
+ /**
+ * Decodes the platform string and calls the builder osName/osArch/osVersion
+ * methods to set the platform constraints.
+ */
+ static void addPlatformConstraints(Builder builder, String platformString) {
+ String[] s = platformString.split("-");
+ if (!s[0].equals("*"))
+ builder.osName(s[0]);
+ if (!s[1].equals("*"))
+ builder.osArch(s[1]);
+ if (!s[2].equals("*"))
+ builder.osVersion(s[2]);
+ }
}
--- a/jdk/test/java/lang/module/ModuleDescriptorTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/module/ModuleDescriptorTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved.
* 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
* @modules java.base/jdk.internal.module
+ * java.base/jdk.internal.misc
* @run testng ModuleDescriptorTest
* @summary Basic test for java.lang.module.ModuleDescriptor and its builder
*/
@@ -42,14 +43,19 @@
import java.lang.module.ModuleDescriptor.Version;
import java.lang.reflect.Module;
import java.nio.ByteBuffer;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
+import java.util.stream.Collectors;
import static java.lang.module.ModuleDescriptor.Requires.Modifier.*;
+import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.ModuleInfoWriter;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -84,21 +90,27 @@
// requires
private Requires requires(Set<Modifier> mods, String mn) {
- return ModuleDescriptor.module("m")
- .requires(mods, mn)
- .build()
- .requires()
- .iterator()
- .next();
+ return requires(mods, mn, null);
}
private Requires requires(Set<Modifier> mods, String mn, Version v) {
- return ModuleDescriptor.module("m")
- .requires(mods, mn, v)
- .build()
- .requires()
- .iterator()
- .next();
+ Builder builder = ModuleDescriptor.newModule("m");
+ if (v == null) {
+ builder.requires(mods, mn);
+ } else {
+ builder.requires(mods, mn, v);
+ }
+ Set<Requires> requires = builder.build().requires();
+ assertTrue(requires.size() == 2);
+ Iterator<Requires> iterator = requires.iterator();
+ Requires r = iterator.next();
+ if (r.name().equals("java.base")) {
+ r = iterator.next();
+ } else {
+ Requires other = iterator.next();
+ assertEquals(other.name(), "java.base");
+ }
+ return r;
}
private Requires requires(String mn) {
@@ -107,7 +119,7 @@
public void testRequiresWithRequires() {
Requires r1 = requires("foo");
- ModuleDescriptor descriptor = ModuleDescriptor.module("m").requires(r1).build();
+ ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").requires(r1).build();
Requires r2 = descriptor.requires().iterator().next();
assertEquals(r1, r2);
}
@@ -162,28 +174,28 @@
@Test(expectedExceptions = IllegalStateException.class)
public void testRequiresWithDuplicatesRequires() {
Requires r = requires("foo");
- ModuleDescriptor.module("m").requires(r).requires(r);
+ ModuleDescriptor.newModule("m").requires(r).requires(r);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testRequiresSelfWithRequires() {
Requires r = requires("foo");
- ModuleDescriptor.module("foo").requires(r);
+ ModuleDescriptor.newModule("foo").requires(r);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testRequiresSelfWithNoModifier() {
- ModuleDescriptor.module("m").requires("m");
+ ModuleDescriptor.newModule("m").requires("m");
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testRequiresSelfWithOneModifier() {
- ModuleDescriptor.module("m").requires(Set.of(TRANSITIVE), "m");
+ ModuleDescriptor.newModule("m").requires(Set.of(TRANSITIVE), "m");
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testRequiresSelfWithAllModifiers() {
- ModuleDescriptor.module("m").requires(EnumSet.allOf(Modifier.class), "m");
+ ModuleDescriptor.newModule("m").requires(EnumSet.allOf(Modifier.class), "m");
}
@Test(dataProvider = "invalidjavaidentifiers",
@@ -194,17 +206,17 @@
@Test(expectedExceptions = NullPointerException.class)
public void testRequiresWithNullRequires() {
- ModuleDescriptor.module("m").requires((Requires) null);
+ ModuleDescriptor.newModule("m").requires((Requires) null);
}
@Test(expectedExceptions = NullPointerException.class)
public void testRequiresWithNullModifiers() {
- ModuleDescriptor.module("m").requires(null, "foo");
+ ModuleDescriptor.newModule("m").requires(null, "foo");
}
@Test(expectedExceptions = NullPointerException.class)
public void testRequiresWithNullVersion() {
- ModuleDescriptor.module("m").requires(Set.of(), "foo", null);
+ ModuleDescriptor.newModule("m").requires(Set.of(), "foo", null);
}
public void testRequiresCompare() {
@@ -284,7 +296,7 @@
// exports
private Exports exports(Set<Exports.Modifier> mods, String pn) {
- return ModuleDescriptor.module("foo")
+ return ModuleDescriptor.newModule("foo")
.exports(mods, pn)
.build()
.exports()
@@ -297,7 +309,7 @@
}
private Exports exports(Set<Exports.Modifier> mods, String pn, String target) {
- return ModuleDescriptor.module("foo")
+ return ModuleDescriptor.newModule("foo")
.exports(mods, pn, Set.of(target))
.build()
.exports()
@@ -312,7 +324,7 @@
public void testExportsExports() {
Exports e1 = exports("p");
- ModuleDescriptor descriptor = ModuleDescriptor.module("m").exports(e1).build();
+ ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").exports(e1).build();
Exports e2 = descriptor.exports().iterator().next();
assertEquals(e1, e2);
}
@@ -341,7 +353,7 @@
targets.add("bar");
targets.add("gus");
Exports e
- = ModuleDescriptor.module("foo")
+ = ModuleDescriptor.newModule("foo")
.exports("p", targets)
.build()
.exports()
@@ -380,69 +392,80 @@
@Test(expectedExceptions = IllegalStateException.class)
public void testExportsWithDuplicate1() {
Exports e = exports("p");
- ModuleDescriptor.module("foo").exports(e).exports(e);
+ ModuleDescriptor.newModule("foo").exports(e).exports(e);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testExportsWithDuplicate2() {
- ModuleDescriptor.module("foo").exports("p").exports("p");
- }
-
- @Test(expectedExceptions = IllegalStateException.class)
- public void testExportsOnContainedPackage() {
- ModuleDescriptor.module("foo").contains("p").exports("p");
- }
-
- @Test(expectedExceptions = IllegalStateException.class)
- public void testExportsToTargetOnContainedPackage() {
- ModuleDescriptor.module("foo").contains("p").exports("p", Set.of("bar"));
+ ModuleDescriptor.newModule("foo").exports("p").exports("p");
}
@Test(expectedExceptions = IllegalArgumentException.class )
public void testExportsWithEmptySet() {
- ModuleDescriptor.module("foo").exports("p", Collections.emptySet());
+ ModuleDescriptor.newModule("foo").exports("p", Collections.emptySet());
}
@Test(dataProvider = "invalidjavaidentifiers",
expectedExceptions = IllegalArgumentException.class )
public void testExportsWithBadName(String pn, String ignore) {
- ModuleDescriptor.module("foo").exports(pn);
+ ModuleDescriptor.newModule("foo").exports(pn);
}
@Test(expectedExceptions = NullPointerException.class )
public void testExportsWithNullExports() {
- ModuleDescriptor.module("foo").exports((Exports) null);
+ ModuleDescriptor.newModule("foo").exports((Exports) null);
}
@Test(expectedExceptions = NullPointerException.class )
public void testExportsWithNullTargets() {
- ModuleDescriptor.module("foo").exports("p", (Set<String>) null);
+ ModuleDescriptor.newModule("foo").exports("p", (Set<String>) null);
}
- public void testExportsEqualsAndHashCode() {
- Exports e1, e2;
+ public void testExportsCompare() {
+ Exports e1 = exports("p");
+ Exports e2 = exports("p");
+ assertEquals(e1, e2);
+ assertTrue(e1.hashCode() == e2.hashCode());
+ assertTrue(e1.compareTo(e2) == 0);
+ assertTrue(e2.compareTo(e1) == 0);
+ }
- e1 = exports("p");
- e2 = exports("p");
+ public void testExportsCompareWithSameModifiers() {
+ Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
+ Exports e2 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
assertEquals(e1, e2);
assertTrue(e1.hashCode() == e2.hashCode());
+ assertTrue(e1.compareTo(e2) == 0);
+ assertTrue(e2.compareTo(e1) == 0);
+ }
- e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
- e2 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
+ public void testExportsCompareWithDifferentModifiers() {
+ Exports e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
+ Exports e2 = exports("p");
+ assertNotEquals(e1, e2);
+ assertTrue(e1.compareTo(e2) == 1);
+ assertTrue(e2.compareTo(e1) == -1);
+ }
+
+ public void testExportsCompareWithSameTargets() {
+ Exports e1 = exports("p", "x");
+ Exports e2 = exports("p", "x");
assertEquals(e1, e2);
assertTrue(e1.hashCode() == e2.hashCode());
+ assertTrue(e1.compareTo(e2) == 0);
+ assertTrue(e2.compareTo(e1) == 0);
+ }
- e1 = exports("p");
- e2 = exports("q");
+ public void testExportsCompareWithDifferentTargets() {
+ Exports e1 = exports("p", "y");
+ Exports e2 = exports("p", "x");
assertNotEquals(e1, e2);
-
- e1 = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
- e2 = exports(Set.of(), "p");
- assertNotEquals(e1, e2);
+ assertTrue(e1.compareTo(e2) == 1);
+ assertTrue(e2.compareTo(e1) == -1);
}
public void testExportsToString() {
- String s = ModuleDescriptor.module("foo")
+ String s = ModuleDescriptor.newModule("foo")
.exports("p1", Set.of("bar"))
.build()
.exports()
@@ -457,7 +480,7 @@
// opens
private Opens opens(Set<Opens.Modifier> mods, String pn) {
- return ModuleDescriptor.module("foo")
+ return ModuleDescriptor.newModule("foo")
.opens(mods, pn)
.build()
.opens()
@@ -470,7 +493,7 @@
}
private Opens opens(Set<Opens.Modifier> mods, String pn, String target) {
- return ModuleDescriptor.module("foo")
+ return ModuleDescriptor.newModule("foo")
.opens(mods, pn, Set.of(target))
.build()
.opens()
@@ -484,7 +507,7 @@
public void testOpensOpens() {
Opens o1 = opens("p");
- ModuleDescriptor descriptor = ModuleDescriptor.module("m").opens(o1).build();
+ ModuleDescriptor descriptor = ModuleDescriptor.newModule("m").opens(o1).build();
Opens o2 = descriptor.opens().iterator().next();
assertEquals(o1, o2);
}
@@ -513,7 +536,7 @@
Set<String> targets = new HashSet<>();
targets.add("bar");
targets.add("gus");
- Opens o = ModuleDescriptor.module("foo")
+ Opens o = ModuleDescriptor.newModule("foo")
.opens("p", targets)
.build()
.opens()
@@ -528,98 +551,83 @@
assertTrue(o.targets().contains("gus"));
}
- /*
-
- public void testOpensToAllWithModifier() {
- Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p");
- assertEquals(e, e);
- assertTrue(e.modifiers().size() == 1);
- assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
- assertEquals(e.source(), "p");
- assertFalse(e.isQualified());
- assertTrue(e.targets().isEmpty());
- }
-
- public void testOpensToTargetWithModifier() {
- Exports e = exports(Set.of(Exports.Modifier.SYNTHETIC), "p", Set.of("bar"));
- assertEquals(e, e);
- assertTrue(e.modifiers().size() == 1);
- assertTrue(e.modifiers().contains(Exports.Modifier.SYNTHETIC));
- assertEquals(e.source(), "p");
- assertTrue(e.isQualified());
- assertTrue(e.targets().size() == 1);
- assertTrue(e.targets().contains("bar"));
- }
-
-
- */
-
@Test(expectedExceptions = IllegalStateException.class)
public void testOpensWithDuplicate1() {
Opens o = opens("p");
- ModuleDescriptor.module("foo").opens(o).opens(o);
+ ModuleDescriptor.newModule("foo").opens(o).opens(o);
}
@Test(expectedExceptions = IllegalStateException.class)
public void testOpensWithDuplicate2() {
- ModuleDescriptor.module("foo").opens("p").opens("p");
- }
-
- @Test(expectedExceptions = IllegalStateException.class)
- public void testOpensOnContainedPackage() {
- ModuleDescriptor.module("foo").contains("p").opens("p");
- }
-
- @Test(expectedExceptions = IllegalStateException.class)
- public void testOpensToTargetOnContainedPackage() {
- ModuleDescriptor.module("foo").contains("p").opens("p", Set.of("bar"));
+ ModuleDescriptor.newModule("foo").opens("p").opens("p");
}
@Test(expectedExceptions = IllegalArgumentException.class )
public void testOpensWithEmptySet() {
- ModuleDescriptor.module("foo").opens("p", Collections.emptySet());
+ ModuleDescriptor.newModule("foo").opens("p", Collections.emptySet());
}
@Test(dataProvider = "invalidjavaidentifiers",
expectedExceptions = IllegalArgumentException.class )
public void testOpensWithBadName(String pn, String ignore) {
- ModuleDescriptor.module("foo").opens(pn);
+ ModuleDescriptor.newModule("foo").opens(pn);
}
@Test(expectedExceptions = NullPointerException.class )
public void testOpensWithNullExports() {
- ModuleDescriptor.module("foo").opens((Opens) null);
+ ModuleDescriptor.newModule("foo").opens((Opens) null);
}
@Test(expectedExceptions = NullPointerException.class )
public void testOpensWithNullTargets() {
- ModuleDescriptor.module("foo").opens("p", (Set<String>) null);
+ ModuleDescriptor.newModule("foo").opens("p", (Set<String>) null);
+ }
+
+ public void testOpensCompare() {
+ Opens o1 = opens("p");
+ Opens o2 = opens("p");
+ assertEquals(o1, o2);
+ assertTrue(o1.hashCode() == o2.hashCode());
+ assertTrue(o1.compareTo(o2) == 0);
+ assertTrue(o2.compareTo(o1) == 0);
+ }
+
+ public void testOpensCompareWithSameModifiers() {
+ Opens o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
+ Opens o2 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
+ assertEquals(o1, o2);
+ assertTrue(o1.hashCode() == o2.hashCode());
+ assertTrue(o1.compareTo(o2) == 0);
+ assertTrue(o2.compareTo(o1) == 0);
}
- public void testOpensEqualsAndHashCode() {
- Opens o1, o2;
+ public void testOpensCompareWithDifferentModifiers() {
+ Opens o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
+ Opens o2 = opens("p");
+ assertNotEquals(o1, o2);
+ assertTrue(o1.compareTo(o2) == 1);
+ assertTrue(o2.compareTo(o1) == -1);
+ }
- o1 = opens("p");
- o2 = opens("p");
- assertEquals(o1, o2);
- assertTrue(o1.hashCode() == o1.hashCode());
-
- o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
- o2 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
+ public void testOpensCompareWithSameTargets() {
+ Opens o1 = opens("p", "x");
+ Opens o2 = opens("p", "x");
assertEquals(o1, o2);
assertTrue(o1.hashCode() == o2.hashCode());
+ assertTrue(o1.compareTo(o2) == 0);
+ assertTrue(o2.compareTo(o1) == 0);
+ }
- o1 = opens("p");
- o2 = opens("q");
+ public void testOpensCompareWithDifferentTargets() {
+ Opens o1 = opens("p", "y");
+ Opens o2 = opens("p", "x");
assertNotEquals(o1, o2);
-
- o1 = opens(Set.of(Opens.Modifier.SYNTHETIC), "p");
- o2 = opens(Set.of(), "p");
- assertNotEquals(o1, o2);
+ assertTrue(o1.compareTo(o2) == 1);
+ assertTrue(o2.compareTo(o1) == -1);
}
public void testOpensToString() {
- String s = ModuleDescriptor.module("foo")
+ String s = ModuleDescriptor.newModule("foo")
.opens("p1", Set.of("bar"))
.build()
.opens()
@@ -635,7 +643,7 @@
public void testUses() {
Set<String> uses
- = ModuleDescriptor.module("foo")
+ = ModuleDescriptor.newModule("foo")
.uses("p.S")
.uses("q.S")
.build()
@@ -647,30 +655,44 @@
@Test(expectedExceptions = IllegalStateException.class)
public void testUsesWithDuplicate() {
- ModuleDescriptor.module("foo").uses("p.S").uses("p.S");
+ ModuleDescriptor.newModule("foo").uses("p.S").uses("p.S");
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testUsesWithSimpleIdentifier() {
+ ModuleDescriptor.newModule("foo").uses("S");
}
@Test(dataProvider = "invalidjavaidentifiers",
expectedExceptions = IllegalArgumentException.class )
public void testUsesWithBadName(String service, String ignore) {
- ModuleDescriptor.module("foo").uses(service);
+ ModuleDescriptor.newModule("foo").uses(service);
}
// provides
private Provides provides(String st, String pc) {
- return ModuleDescriptor.module("foo")
- .provides(st, pc)
+ return ModuleDescriptor.newModule("foo")
+ .provides(st, List.of(pc))
.build()
.provides()
.iterator()
.next();
}
+ private Provides provides(String st, List<String> pns) {
+ return ModuleDescriptor.newModule("foo")
+ .provides(st, pns)
+ .build()
+ .provides()
+ .iterator()
+ .next();
+ }
+
public void testProvidesWithProvides() {
Provides p1 = provides("p.S", "q.S1");
- ModuleDescriptor descriptor = ModuleDescriptor.module("m")
+ ModuleDescriptor descriptor = ModuleDescriptor.newModule("m")
.provides(p1)
.build();
Provides p2 = descriptor.provides().iterator().next();
@@ -679,7 +701,7 @@
public void testProvides() {
- Set<Provides> set = ModuleDescriptor.module("foo")
+ Set<Provides> set = ModuleDescriptor.newModule("foo")
.provides("p.S", List.of("q.P1", "q.P2"))
.build()
.provides();
@@ -696,59 +718,86 @@
@Test(expectedExceptions = IllegalStateException.class )
public void testProvidesWithDuplicateProvides() {
Provides p = provides("p.S", "q.S2");
- ModuleDescriptor.module("m").provides("p.S", "q.S1").provides(p);
+ ModuleDescriptor.newModule("m").provides("p.S", List.of("q.S1")).provides(p);
}
@Test(expectedExceptions = IllegalArgumentException.class )
public void testProvidesWithEmptySet() {
- ModuleDescriptor.module("foo").provides("p.Service", Collections.emptyList());
+ ModuleDescriptor.newModule("foo").provides("p.Service", Collections.emptyList());
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class )
+ public void testProvidesWithSimpleIdentifier1() {
+ ModuleDescriptor.newModule("foo").provides("S", List.of("q.P"));
+ }
+
+ @Test(expectedExceptions = IllegalArgumentException.class )
+ public void testProvidesWithSimpleIdentifier2() {
+ ModuleDescriptor.newModule("foo").provides("p.S", List.of("P"));
}
@Test(dataProvider = "invalidjavaidentifiers",
expectedExceptions = IllegalArgumentException.class )
public void testProvidesWithBadService(String service, String ignore) {
- ModuleDescriptor.module("foo").provides(service, "p.Provider");
+ ModuleDescriptor.newModule("foo").provides(service, List.of("p.Provider"));
}
@Test(dataProvider = "invalidjavaidentifiers",
expectedExceptions = IllegalArgumentException.class )
public void testProvidesWithBadProvider(String provider, String ignore) {
- ModuleDescriptor.module("foo").provides("p.Service", provider);
+ List<String> names = new ArrayList<>(); // allows nulls
+ names.add(provider);
+ ModuleDescriptor.newModule("foo").provides("p.Service", names);
}
@Test(expectedExceptions = NullPointerException.class )
public void testProvidesWithNullProvides() {
- ModuleDescriptor.module("foo").provides((Provides) null);
+ ModuleDescriptor.newModule("foo").provides((Provides) null);
}
@Test(expectedExceptions = NullPointerException.class )
public void testProvidesWithNullProviders() {
- ModuleDescriptor.module("foo").provides("p.S", (List<String>) null);
+ ModuleDescriptor.newModule("foo").provides("p.S", (List<String>) null);
}
- public void testProvidesEqualsAndHashCode() {
- Provides p1, p2;
-
- p1 = provides("p.S", "q.S1");
- p2 = provides("p.S", "q.S1");
+ public void testProvidesCompare() {
+ Provides p1 = provides("p.S", "q.S1");
+ Provides p2 = provides("p.S", "q.S1");
assertEquals(p1, p2);
assertTrue(p1.hashCode() == p2.hashCode());
+ assertTrue(p1.compareTo(p2) == 0);
+ assertTrue(p2.compareTo(p1) == 0);
+ }
- p1 = provides("p.S", "q.S1");
- p2 = provides("p.S", "q.S2");
+ public void testProvidesCompareWithDifferentService() {
+ Provides p1 = provides("p.S2", "q.S1");
+ Provides p2 = provides("p.S1", "q.S1");
assertNotEquals(p1, p2);
-
- p1 = provides("p.S", "q.S1");
- p2 = provides("p.S2", "q.S1");
- assertNotEquals(p1, p2);
+ assertTrue(p1.compareTo(p2) == 1);
+ assertTrue(p2.compareTo(p1) == -1);
}
- // contains
+ public void testProvidesCompareWithDifferentProviders1() {
+ Provides p1 = provides("p.S", "q.S2");
+ Provides p2 = provides("p.S", "q.S1");
+ assertNotEquals(p1, p2);
+ assertTrue(p1.compareTo(p2) == 1);
+ assertTrue(p2.compareTo(p1) == -1);
+ }
- public void testContains() {
- Set<String> packages = ModuleDescriptor.module("foo")
- .contains("p")
- .contains("q")
+ public void testProvidesCompareWithDifferentProviders2() {
+ Provides p1 = provides("p.S", List.of("q.S1", "q.S2"));
+ Provides p2 = provides("p.S", "q.S1");
+ assertNotEquals(p1, p2);
+ assertTrue(p1.compareTo(p2) == 1);
+ assertTrue(p2.compareTo(p1) == -1);
+ }
+
+ // packages
+
+ public void testPackages1() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .packages(Set.of("p", "q"))
.build()
.packages();
assertTrue(packages.size() == 2);
@@ -756,37 +805,10 @@
assertTrue(packages.contains("q"));
}
- public void testContainsWithEmptySet() {
- Set<String> packages = ModuleDescriptor.module("foo")
- .contains(Collections.emptySet())
- .build()
- .packages();
- assertTrue(packages.size() == 0);
- }
-
- @Test(expectedExceptions = IllegalStateException.class)
- public void testContainsWithDuplicate() {
- ModuleDescriptor.module("foo").contains("p").contains("p");
- }
-
- @Test(expectedExceptions = IllegalStateException.class)
- public void testContainsWithExportedPackage() {
- ModuleDescriptor.module("foo").exports("p").contains("p");
- }
-
- @Test(dataProvider = "invalidjavaidentifiers",
- expectedExceptions = IllegalArgumentException.class )
- public void testContainsWithBadName(String pn, String ignore) {
- ModuleDescriptor.module("foo").contains(pn);
- }
-
-
- // packages
-
- public void testPackages() {
- Set<String> packages = ModuleDescriptor.module("foo")
- .exports("p")
- .contains("q")
+ public void testPackages2() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .packages(Set.of("p"))
+ .packages(Set.of("q"))
.build()
.packages();
assertTrue(packages.size() == 2);
@@ -795,17 +817,135 @@
}
+ public void testPackagesWithEmptySet() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .packages(Collections.emptySet())
+ .build()
+ .packages();
+ assertTrue(packages.size() == 0);
+ }
+
+ public void testPackagesDuplicate() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .packages(Set.of("p"))
+ .packages(Set.of("p"))
+ .build()
+ .packages();
+ assertTrue(packages.size() == 1);
+ assertTrue(packages.contains("p"));
+ }
+
+ public void testPackagesAndExportsPackage1() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .packages(Set.of("p"))
+ .exports("p")
+ .build()
+ .packages();
+ assertTrue(packages.size() == 1);
+ assertTrue(packages.contains("p"));
+ }
+
+ public void testPackagesAndExportsPackage2() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .exports("p")
+ .packages(Set.of("p"))
+ .build()
+ .packages();
+ assertTrue(packages.size() == 1);
+ assertTrue(packages.contains("p"));
+ }
+
+ public void testPackagesAndOpensPackage1() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .packages(Set.of("p"))
+ .opens("p")
+ .build()
+ .packages();
+ assertTrue(packages.size() == 1);
+ assertTrue(packages.contains("p"));
+ }
+
+ public void testPackagesAndOpensPackage2() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .opens("p")
+ .packages(Set.of("p"))
+ .build()
+ .packages();
+ assertTrue(packages.size() == 1);
+ assertTrue(packages.contains("p"));
+ }
+
+ public void testPackagesAndProvides1() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .packages(Set.of("p"))
+ .provides("q.S", List.of("p.T"))
+ .build()
+ .packages();
+ assertTrue(packages.size() == 1);
+ assertTrue(packages.contains("p"));
+ }
+
+ public void testPackagesAndProvides2() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .provides("q.S", List.of("p.T"))
+ .packages(Set.of("p"))
+ .build()
+ .packages();
+ assertTrue(packages.size() == 1);
+ assertTrue(packages.contains("p"));
+ }
+
+ public void testPackagesAndMainClass1() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .packages(Set.of("p"))
+ .mainClass("p.Main")
+ .build()
+ .packages();
+ assertTrue(packages.size() == 1);
+ assertTrue(packages.contains("p"));
+ }
+
+ public void testPackagesAndMainClass2() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .mainClass("p.Main")
+ .packages(Set.of("p"))
+ .build()
+ .packages();
+ assertTrue(packages.size() == 1);
+ assertTrue(packages.contains("p"));
+ }
+
+ public void testPackagesAndAll() {
+ Set<String> packages = ModuleDescriptor.newModule("foo")
+ .exports("p1")
+ .opens("p2")
+ .packages(Set.of("p3"))
+ .provides("q.S", List.of("p4.T"))
+ .mainClass("p5.Main")
+ .build()
+ .packages();
+ assertTrue(Objects.equals(packages, Set.of("p1", "p2", "p3", "p4", "p5")));
+ }
+
+ @Test(dataProvider = "invalidjavaidentifiers",
+ expectedExceptions = IllegalArgumentException.class )
+ public void testPackagesWithBadName(String pn, String ignore) {
+ Set<String> pkgs = new HashSet<>(); // allows nulls
+ pkgs.add(pn);
+ ModuleDescriptor.newModule("foo").packages(pkgs);
+ }
+
// name
public void testModuleName() {
- String mn = ModuleDescriptor.module("foo").build().name();
+ String mn = ModuleDescriptor.newModule("foo").build().name();
assertEquals(mn, "foo");
}
@Test(dataProvider = "invalidjavaidentifiers",
expectedExceptions = IllegalArgumentException.class )
public void testBadModuleName(String mn, String ignore) {
- ModuleDescriptor.module(mn);
+ ModuleDescriptor.newModule(mn);
}
@@ -813,7 +953,7 @@
public void testVersion1() {
Version v1 = Version.parse("1.0");
- Version v2 = ModuleDescriptor.module("foo")
+ Version v2 = ModuleDescriptor.newModule("foo")
.version(v1)
.build()
.version()
@@ -823,7 +963,7 @@
public void testVersion2() {
String vs = "1.0";
- Version v1 = ModuleDescriptor.module("foo")
+ Version v1 = ModuleDescriptor.newModule("foo")
.version(vs)
.build()
.version()
@@ -834,86 +974,178 @@
@Test(expectedExceptions = NullPointerException.class )
public void testNullVersion1() {
- ModuleDescriptor.module("foo").version((Version) null);
+ ModuleDescriptor.newModule("foo").version((Version) null);
}
@Test(expectedExceptions = IllegalArgumentException.class )
public void testNullVersion2() {
- ModuleDescriptor.module("foo").version((String) null);
+ ModuleDescriptor.newModule("foo").version((String) null);
}
@Test(expectedExceptions = IllegalArgumentException.class )
public void testEmptyVersion() {
- ModuleDescriptor.module("foo").version("");
+ ModuleDescriptor.newModule("foo").version("");
}
// toNameAndVersion
public void testToNameAndVersion() {
- ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
+ ModuleDescriptor md1 = ModuleDescriptor.newModule("foo").build();
assertEquals(md1.toNameAndVersion(), "foo");
- ModuleDescriptor md2 = ModuleDescriptor.module("foo").version("1.0").build();
+ ModuleDescriptor md2 = ModuleDescriptor.newModule("foo").version("1.0").build();
assertEquals(md2.toNameAndVersion(), "foo@1.0");
}
// open modules
- public void testOpenModules() {
- ModuleDescriptor descriptor = ModuleDescriptor.openModule("m")
- .requires("java.base")
- .contains("p")
+ public void testOpenModule() {
+ ModuleDescriptor descriptor = ModuleDescriptor.newOpenModule("foo")
+ .requires("bar")
+ .exports("p")
+ .provides("p.Service", List.of("q.ServiceImpl"))
.build();
+
+ // modifiers
+ assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.OPEN));
assertTrue(descriptor.isOpen());
- assertTrue(descriptor.packages().size() == 1);
- assertTrue(descriptor.packages().contains("p"));
- assertTrue(descriptor.exports().isEmpty());
+
+ // requires
+ assertTrue(descriptor.requires().size() == 2);
+ Set<String> names = descriptor.requires()
+ .stream()
+ .map(Requires::name)
+ .collect(Collectors.toSet());
+ assertEquals(names, Set.of("bar", "java.base"));
+
+ // packages
+ assertEquals(descriptor.packages(), Set.of("p", "q"));
+
+ // exports
+ assertTrue(descriptor.exports().size() == 1);
+ names = descriptor.exports()
+ .stream()
+ .map(Exports::source)
+ .collect(Collectors.toSet());
+ assertEquals(names, Set.of("p"));
+
+ // opens
+ assertTrue(descriptor.opens().isEmpty());
}
@Test(expectedExceptions = IllegalStateException.class)
- public void testOpensOnWeakModule1() {
- ModuleDescriptor.openModule("foo").opens("p");
+ public void testOpensOnOpenModule1() {
+ ModuleDescriptor.newOpenModule("foo").opens("p");
}
@Test(expectedExceptions = IllegalStateException.class)
- public void testOpensOnWeakModule2() {
- ModuleDescriptor.openModule("foo").opens("p", Set.of("bar"));
+ public void testOpensOnOpenModule2() {
+ ModuleDescriptor.newOpenModule("foo").opens("p", Set.of("bar"));
}
public void testIsOpen() {
- assertFalse(ModuleDescriptor.module("m").build().isOpen());
- assertFalse(ModuleDescriptor.automaticModule("m").build().isOpen());
- assertTrue(ModuleDescriptor.openModule("m").build().isOpen());
+ assertFalse(ModuleDescriptor.newModule("m").build().isOpen());
+ assertFalse(ModuleDescriptor.newAutomaticModule("m").build().isOpen());
+ assertTrue(ModuleDescriptor.newOpenModule("m").build().isOpen());
}
// automatic modules
+ public void testAutomaticModule() {
+ ModuleDescriptor descriptor = ModuleDescriptor.newAutomaticModule("foo")
+ .packages(Set.of("p"))
+ .provides("p.Service", List.of("q.ServiceImpl"))
+ .build();
+
+ // modifiers
+ assertTrue(descriptor.modifiers().contains(ModuleDescriptor.Modifier.AUTOMATIC));
+ assertTrue(descriptor.isAutomatic());
+
+ // requires
+ assertTrue(descriptor.requires().size() == 1);
+ Set<String> names = descriptor.requires()
+ .stream()
+ .map(Requires::name)
+ .collect(Collectors.toSet());
+ assertEquals(names, Set.of("java.base"));
+
+ // packages
+ assertEquals(descriptor.packages(), Set.of("p", "q"));
+ assertTrue(descriptor.exports().isEmpty());
+ assertTrue(descriptor.opens().isEmpty());
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testRequiresOnAutomaticModule() {
+ ModuleDescriptor.newAutomaticModule("foo").requires("java.base");
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testExportsOnAutomaticModule1() {
+ ModuleDescriptor.newAutomaticModule("foo").exports("p");
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testExportsOnAutomaticModule2() {
+ ModuleDescriptor.newAutomaticModule("foo").exports("p", Set.of("bar"));
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testOpensOnAutomaticModule1() {
+ ModuleDescriptor.newAutomaticModule("foo").opens("p");
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testOpensOnAutomaticModule2() {
+ ModuleDescriptor.newAutomaticModule("foo").opens("p", Set.of("bar"));
+ }
+
+ @Test(expectedExceptions = IllegalStateException.class)
+ public void testUsesOnAutomaticModule() {
+ ModuleDescriptor.newAutomaticModule("foo").uses("p.Service");
+ }
+
public void testIsAutomatic() {
- ModuleDescriptor descriptor1 = ModuleDescriptor.module("foo").build();
+ ModuleDescriptor descriptor1 = ModuleDescriptor.newModule("foo").build();
assertFalse(descriptor1.isAutomatic());
- ModuleDescriptor descriptor2 = ModuleDescriptor.openModule("foo").build();
+ ModuleDescriptor descriptor2 = ModuleDescriptor.newOpenModule("foo").build();
assertFalse(descriptor2.isAutomatic());
- ModuleDescriptor descriptor3 = ModuleDescriptor.automaticModule("foo").build();
+ ModuleDescriptor descriptor3 = ModuleDescriptor.newAutomaticModule("foo").build();
assertTrue(descriptor3.isAutomatic());
}
- // isSynthetic
- public void testIsSynthetic() {
- assertFalse(Object.class.getModule().getDescriptor().isSynthetic());
+
+ // newModule with modifiers
+
+ public void testNewModuleToBuildAutomaticModule() {
+ Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.AUTOMATIC);
+ ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo", ms).build();
+ assertTrue(descriptor.modifiers().equals(ms));
+ assertTrue(descriptor.isAutomatic());
+ }
- ModuleDescriptor descriptor1 = ModuleDescriptor.module("foo").build();
- assertFalse(descriptor1.isSynthetic());
+ public void testNewModuleToBuildOpenModule() {
+ Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.OPEN);
+ ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo", ms).build();
+ assertTrue(descriptor.modifiers().equals(ms));
+ assertTrue(descriptor.isOpen());
- ModuleDescriptor descriptor2 = ModuleDescriptor.openModule("foo").build();
- assertFalse(descriptor2.isSynthetic());
+ ms = Set.of(ModuleDescriptor.Modifier.OPEN, ModuleDescriptor.Modifier.SYNTHETIC);
+ descriptor = ModuleDescriptor.newModule("foo", ms).build();
+ assertTrue(descriptor.modifiers().equals(ms));
+ assertTrue(descriptor.isOpen());
+ }
- ModuleDescriptor descriptor3 = ModuleDescriptor.automaticModule("foo").build();
- assertFalse(descriptor3.isSynthetic());
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testNewModuleToBuildAutomaticAndOpenModule() {
+ Set<ModuleDescriptor.Modifier> ms = Set.of(ModuleDescriptor.Modifier.AUTOMATIC,
+ ModuleDescriptor.Modifier.OPEN);
+ ModuleDescriptor.newModule("foo", ms);
}
@@ -921,14 +1153,19 @@
public void testMainClass() {
String mainClass
- = ModuleDescriptor.module("foo").mainClass("p.Main").build().mainClass().get();
+ = ModuleDescriptor.newModule("foo").mainClass("p.Main").build().mainClass().get();
assertEquals(mainClass, "p.Main");
}
+ @Test(expectedExceptions = IllegalArgumentException.class)
+ public void testMainClassWithSimpleIdentifier() {
+ ModuleDescriptor.newModule("foo").mainClass("Main");
+ }
+
@Test(dataProvider = "invalidjavaidentifiers",
expectedExceptions = IllegalArgumentException.class )
public void testMainClassWithBadName(String mainClass, String ignore) {
- Builder builder = ModuleDescriptor.module("foo");
+ Builder builder = ModuleDescriptor.newModule("foo");
builder.mainClass(mainClass);
}
@@ -936,54 +1173,54 @@
// osName
public void testOsName() {
- String osName = ModuleDescriptor.module("foo").osName("Linux").build().osName().get();
+ String osName = ModuleDescriptor.newModule("foo").osName("Linux").build().osName().get();
assertEquals(osName, "Linux");
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullOsName() {
- ModuleDescriptor.module("foo").osName(null);
+ ModuleDescriptor.newModule("foo").osName(null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testEmptyOsName() {
- ModuleDescriptor.module("foo").osName("");
+ ModuleDescriptor.newModule("foo").osName("");
}
// osArch
public void testOsArch() {
- String osArch = ModuleDescriptor.module("foo").osName("arm").build().osName().get();
+ String osArch = ModuleDescriptor.newModule("foo").osName("arm").build().osName().get();
assertEquals(osArch, "arm");
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullOsArch() {
- ModuleDescriptor.module("foo").osArch(null);
+ ModuleDescriptor.newModule("foo").osArch(null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testEmptyOsArch() {
- ModuleDescriptor.module("foo").osArch("");
+ ModuleDescriptor.newModule("foo").osArch("");
}
// osVersion
public void testOsVersion() {
- String osVersion = ModuleDescriptor.module("foo").osName("11.2").build().osName().get();
+ String osVersion = ModuleDescriptor.newModule("foo").osName("11.2").build().osName().get();
assertEquals(osVersion, "11.2");
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testNullOsVersion() {
- ModuleDescriptor.module("foo").osVersion(null);
+ ModuleDescriptor.newModule("foo").osVersion(null);
}
@Test(expectedExceptions = IllegalArgumentException.class)
public void testEmptyOsVersion() {
- ModuleDescriptor.module("foo").osVersion("");
+ ModuleDescriptor.newModule("foo").osVersion("");
}
// reads
@@ -1023,7 +1260,7 @@
* Test ModuleDescriptor with a packager finder
*/
public void testReadsWithPackageFinder() throws Exception {
- ModuleDescriptor descriptor = ModuleDescriptor.module("foo")
+ ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
.requires("java.base")
.build();
@@ -1044,7 +1281,7 @@
*/
@Test(expectedExceptions = InvalidModuleDescriptorException.class)
public void testReadsWithBadPackageFinder() throws Exception {
- ModuleDescriptor descriptor = ModuleDescriptor.module("foo")
+ ModuleDescriptor descriptor = ModuleDescriptor.newModule("foo")
.requires("java.base")
.exports("p")
.build();
@@ -1077,7 +1314,7 @@
@Test(expectedExceptions = InvalidModuleDescriptorException.class)
public void testReadOfJavaBaseWithRequires() {
ModuleDescriptor descriptor
- = ModuleDescriptor.module("java.base")
+ = ModuleDescriptor.newModule("java.base")
.requires("other")
.build();
ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
@@ -1087,7 +1324,8 @@
// The requires table must have an entry for java.base
@Test(expectedExceptions = InvalidModuleDescriptorException.class)
public void testReadWithEmptyRequires() {
- ModuleDescriptor descriptor = ModuleDescriptor.module("m1").build();
+ ModuleDescriptor descriptor = SharedSecrets.getJavaLangModuleAccess()
+ .newModuleBuilder("m1", false, Set.of()).build();
ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
ModuleDescriptor.read(bb);
}
@@ -1095,10 +1333,8 @@
// The requires table must have an entry for java.base
@Test(expectedExceptions = InvalidModuleDescriptorException.class)
public void testReadWithNoRequiresBase() {
- ModuleDescriptor descriptor
- = ModuleDescriptor.module("m1")
- .requires("m2")
- .build();
+ ModuleDescriptor descriptor = SharedSecrets.getJavaLangModuleAccess()
+ .newModuleBuilder("m1", false, Set.of()).requires("m2").build();
ByteBuffer bb = ModuleInfoWriter.toByteBuffer(descriptor);
ModuleDescriptor.read(bb);
}
@@ -1138,22 +1374,50 @@
// equals/hashCode/compareTo/toString
public void testEqualsAndHashCode() {
- ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
- ModuleDescriptor md2 = ModuleDescriptor.module("foo").build();
+ ModuleDescriptor md1 = ModuleDescriptor.newModule("m").build();
+ ModuleDescriptor md2 = ModuleDescriptor.newModule("m").build();
assertEquals(md1, md1);
assertEquals(md1.hashCode(), md2.hashCode());
+ assertTrue(md1.compareTo(md2) == 0);
+ assertTrue(md2.compareTo(md1) == 0);
}
- public void testCompare() {
- ModuleDescriptor md1 = ModuleDescriptor.module("foo").build();
- ModuleDescriptor md2 = ModuleDescriptor.module("bar").build();
- int n = "foo".compareTo("bar");
- assertTrue(md1.compareTo(md2) == n);
- assertTrue(md2.compareTo(md1) == -n);
+ @DataProvider(name = "sortedModuleDescriptors")
+ public Object[][] sortedModuleDescriptors() {
+ return new Object[][]{
+
+ { ModuleDescriptor.newModule("m2").build(),
+ ModuleDescriptor.newModule("m1").build()
+ },
+
+ { ModuleDescriptor.newModule("m").version("2").build(),
+ ModuleDescriptor.newModule("m").version("1").build()
+ },
+
+ { ModuleDescriptor.newModule("m").version("1").build(),
+ ModuleDescriptor.newModule("m").build()
+ },
+
+ { ModuleDescriptor.newOpenModule("m").build(),
+ ModuleDescriptor.newModule("m").build()
+ },
+
+ };
+ }
+
+ @Test(dataProvider = "sortedModuleDescriptors")
+ public void testCompare(ModuleDescriptor md1, ModuleDescriptor md2) {
+ assertNotEquals(md1, md2);
+ assertTrue(md1.compareTo(md2) == 1);
+ assertTrue(md2.compareTo(md1) == -1);
}
public void testToString() {
- String s = ModuleDescriptor.module("m1").requires("m2").exports("p1").build().toString();
+ String s = ModuleDescriptor.newModule("m1")
+ .requires("m2")
+ .exports("p1")
+ .build()
+ .toString();
assertTrue(s.contains("m1"));
assertTrue(s.contains("m2"));
assertTrue(s.contains("p1"));
--- a/jdk/test/java/lang/module/ModuleFinderTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/module/ModuleFinderTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -471,37 +471,11 @@
* Test ModuleFinder.of with a file path to a directory containing a file
* that will not be recognized as a module.
*/
- public void testOfWithUnrecognizedEntryInDirectory() throws Exception {
+ public void testOfWithUnrecognizedEntryInDirectory1() throws Exception {
Path dir = Files.createTempDirectory(USER_DIR, "mods");
Files.createTempFile(dir, "m", ".junk");
ModuleFinder finder = ModuleFinder.of(dir);
- try {
- finder.find("java.rhubarb");
- assertTrue(false);
- } catch (FindException e) {
- // expected
- }
-
- finder = ModuleFinder.of(dir);
- try {
- finder.findAll();
- assertTrue(false);
- } catch (FindException e) {
- // expected
- }
- }
-
-
- /**
- * Test ModuleFinder.of with a file path to a directory containing a file
- * starting with ".", the file should be ignored.
- */
- public void testOfWithHiddenEntryInDirectory() throws Exception {
- Path dir = Files.createTempDirectory(USER_DIR, "mods");
- Files.createTempFile(dir, ".marker", "");
-
- ModuleFinder finder = ModuleFinder.of(dir);
assertFalse(finder.find("java.rhubarb").isPresent());
finder = ModuleFinder.of(dir);
@@ -510,6 +484,24 @@
/**
+ * Test ModuleFinder.of with a file path to a directory containing a file
+ * that will not be recognized as a module.
+ */
+ public void testOfWithUnrecognizedEntryInDirectory2() throws Exception {
+ Path dir = Files.createTempDirectory(USER_DIR, "mods");
+ createModularJar(dir.resolve("m1.jar"), "m1");
+ Files.createTempFile(dir, "m2", ".junk");
+
+ ModuleFinder finder = ModuleFinder.of(dir);
+ assertTrue(finder.find("m1").isPresent());
+ assertFalse(finder.find("m2").isPresent());
+
+ finder = ModuleFinder.of(dir);
+ assertTrue(finder.findAll().size() == 1);
+ }
+
+
+ /**
* Test ModuleFinder.of with a directory that contains two
* versions of the same module
*/
@@ -748,7 +740,7 @@
vs = mid.substring(i+1);
}
ModuleDescriptor.Builder builder
- = ModuleDescriptor.module(mn).requires("java.base");
+ = ModuleDescriptor.newModule(mn).requires("java.base");
if (vs != null)
builder.version(vs);
return builder.build();
--- a/jdk/test/java/lang/module/ModuleNamesTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/module/ModuleNamesTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -235,7 +235,7 @@
*/
private Builder newBuilder(String mn) {
return SharedSecrets.getJavaLangModuleAccess()
- .newModuleBuilder(mn, false, false, false);
+ .newModuleBuilder(mn, false, Set.of());
}
/**
--- a/jdk/test/java/lang/module/ModuleReader/ModuleReaderTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/module/ModuleReader/ModuleReaderTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -79,14 +79,52 @@
"java/lang/Object.class"
};
+ // resource names that should not be found in the base module
+ private static final String[] BAD_BASE_RESOURCES = {
+ "NotFound",
+ "java",
+ "/java",
+ "//java",
+ "java/",
+ "java/lang",
+ "/java/lang",
+ "//java/lang",
+ "java/lang/",
+ "java//lang",
+ "/java/lang/Object.class",
+ "//java/lang/Object.class",
+ "java/lang/Object.class/",
+ "java//lang//Object.class",
+ "./java/lang/Object.class",
+ "java/./lang/Object.class",
+ "java/lang/./Object.class",
+ "../java/lang/Object.class",
+ "java/../lang/Object.class",
+ "java/lang/../Object.class",
+ };
+
// resources in test module (can't use module-info.class as a test
// resource as it will be modified by the jmod tool)
private static final String[] TEST_RESOURCES = {
"p/Main.class"
};
- // a resource that is not in the base or test module
- private static final String NOT_A_RESOURCE = "NotAResource";
+ // resource names that should not be found in the test module
+ private static final String[] BAD_TEST_RESOURCES = {
+ "NotFound",
+ "p",
+ "/p",
+ "//p",
+ "p/",
+ "/p/Main.class",
+ "//p/Main.class",
+ "p/Main.class/",
+ "p//Main.class",
+ "./p/Main.class",
+ "p/./Main.class",
+ "../p/Main.class",
+ "p/../p/Main.class"
+ };
@BeforeTest
@@ -126,10 +164,11 @@
}
// test "not found"
- assertFalse(reader.find(NOT_A_RESOURCE).isPresent());
- assertFalse(reader.open(NOT_A_RESOURCE).isPresent());
- assertFalse(reader.read(NOT_A_RESOURCE).isPresent());
-
+ for (String name : BAD_BASE_RESOURCES) {
+ assertFalse(reader.find(name).isPresent());
+ assertFalse(reader.open(name).isPresent());
+ assertFalse(reader.read(name).isPresent());
+ }
// test nulls
try {
@@ -216,7 +255,7 @@
*/
void test(Path mp) throws IOException {
- ModuleFinder finder = new ModulePath(Runtime.version(), true, mp);
+ ModuleFinder finder = ModulePath.of(Runtime.version(), true, mp);
ModuleReference mref = finder.find(TEST_MODULE).get();
ModuleReader reader = mref.open();
@@ -236,9 +275,11 @@
}
// test "not found"
- assertFalse(reader.find(NOT_A_RESOURCE).isPresent());
- assertFalse(reader.open(NOT_A_RESOURCE).isPresent());
- assertFalse(reader.read(NOT_A_RESOURCE).isPresent());
+ for (String name : BAD_TEST_RESOURCES) {
+ assertFalse(reader.find(name).isPresent());
+ assertFalse(reader.open(name).isPresent());
+ assertFalse(reader.read(name).isPresent());
+ }
// test nulls
try {
--- a/jdk/test/java/lang/module/ModuleReferenceTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/module/ModuleReferenceTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -31,6 +31,7 @@
import java.lang.module.ModuleReader;
import java.lang.module.ModuleReference;
import java.net.URI;
+import java.util.Set;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@@ -49,10 +50,10 @@
public void testBasic() throws Exception {
ModuleDescriptor descriptor
- = ModuleDescriptor.module("m")
+ = ModuleDescriptor.newModule("m")
.exports("p")
.exports("q")
- .contains("p.internal")
+ .packages(Set.of("p.internal"))
.build();
URI uri = URI.create("module:/m");
@@ -71,7 +72,7 @@
public void testNullLocation() {
ModuleDescriptor descriptor
- = ModuleDescriptor.module("m")
+ = ModuleDescriptor.newModule("m")
.exports("p")
.build();
ModuleReference mref = newModuleReference(descriptor, null);
--- a/jdk/test/java/lang/module/MultiReleaseJarTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/module/MultiReleaseJarTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -65,7 +65,7 @@
private static final String MODULE_INFO = "module-info.class";
- private static final int RELEASE = Runtime.version().major();
+ private static final int VERSION = Runtime.version().major();
// are multi-release JARs enabled?
private static final boolean MULTI_RELEASE;
@@ -80,7 +80,7 @@
public void testBasic() throws Exception {
String name = "m1";
- ModuleDescriptor descriptor = ModuleDescriptor.module(name)
+ ModuleDescriptor descriptor = ModuleDescriptor.newModule(name)
.requires("java.base")
.build();
@@ -88,8 +88,8 @@
.moduleInfo("module-info.class", descriptor)
.resource("p/Main.class")
.resource("p/Helper.class")
- .resource("META-INF/versions/9/p/Helper.class")
- .resource("META-INF/versions/9/p/internal/Helper9.class")
+ .resource("META-INF/versions/" + VERSION + "/p/Helper.class")
+ .resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
.build();
// find the module
@@ -117,12 +117,12 @@
public void testModuleInfoInVersionedSection() throws Exception {
String name = "m1";
- ModuleDescriptor descriptor1 = ModuleDescriptor.module(name)
+ ModuleDescriptor descriptor1 = ModuleDescriptor.newModule(name)
.requires("java.base")
.build();
// module descriptor for versioned section
- ModuleDescriptor descriptor2 = ModuleDescriptor.module(name)
+ ModuleDescriptor descriptor2 = ModuleDescriptor.newModule(name)
.requires("java.base")
.requires("jdk.unsupported")
.build();
@@ -131,9 +131,9 @@
.moduleInfo(MODULE_INFO, descriptor1)
.resource("p/Main.class")
.resource("p/Helper.class")
- .moduleInfo("META-INF/versions/9/" + MODULE_INFO, descriptor2)
- .resource("META-INF/versions/9/p/Helper.class")
- .resource("META-INF/versions/9/p/internal/Helper9.class")
+ .moduleInfo("META-INF/versions/" + VERSION + "/" + MODULE_INFO, descriptor2)
+ .resource("META-INF/versions/" + VERSION + "/p/Helper.class")
+ .resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
.build();
// find the module
@@ -161,8 +161,8 @@
Path jar = new JarBuilder(name)
.resource("p/Main.class")
.resource("p/Helper.class")
- .resource("META-INF/versions/9/p/Helper.class")
- .resource("META-INF/versions/9/p/internal/Helper9.class")
+ .resource("META-INF/versions/" + VERSION + "/p/Helper.class")
+ .resource("META-INF/versions/" + VERSION + "/p/internal/Helper.class")
.build();
// find the module
@@ -188,19 +188,19 @@
public void testModuleReader() throws Exception {
String name = "m1";
- ModuleDescriptor descriptor1 = ModuleDescriptor.module(name)
+ ModuleDescriptor descriptor1 = ModuleDescriptor.newModule(name)
.requires("java.base")
.build();
// module descriptor for versioned section
- ModuleDescriptor descriptor2 = ModuleDescriptor.module(name)
+ ModuleDescriptor descriptor2 = ModuleDescriptor.newModule(name)
.requires("java.base")
.requires("jdk.unsupported")
.build();
Path jar = new JarBuilder(name)
.moduleInfo(MODULE_INFO, descriptor1)
- .moduleInfo("META-INF/versions/9/" + MODULE_INFO, descriptor2)
+ .moduleInfo("META-INF/versions/" + VERSION + "/" + MODULE_INFO, descriptor2)
.build();
// find the module
@@ -243,7 +243,7 @@
String expectedTail = "!/";
if (MULTI_RELEASE)
- expectedTail += "META-INF/versions/" + RELEASE + "/";
+ expectedTail += "META-INF/versions/" + VERSION + "/";
expectedTail += MODULE_INFO;
assertTrue(uri.toString().endsWith(expectedTail));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessibleObject/CanAccessTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
+ * @build CanAccessTest
+ * @modules java.base/jdk.internal.misc:+open
+ * @run testng CanAccessTest
+ * @summary Test AccessibleObject::canAccess method
+ */
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.security.SecureClassLoader;
+
+import jdk.internal.misc.Unsafe;
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+@Test
+public class CanAccessTest {
+ private static Unsafe INSTANCE = Unsafe.getUnsafe();
+
+ /**
+ * null object parameter for Constructor
+ */
+ public void testConstructor() throws Exception {
+ Constructor<?> ctor = Unsafe.class.getDeclaredConstructor();
+ assertFalse(ctor.canAccess(null));
+ assertTrue(ctor.trySetAccessible());
+
+ try {
+ // non-null object parameter
+ ctor.canAccess(INSTANCE);
+ assertTrue(false);
+ } catch (IllegalArgumentException expected) {}
+ }
+
+ /**
+ * Test protected constructors
+ */
+ public void testProtectedConstructor() throws Exception {
+ TestLoader.testProtectedConstructorNonOpenedPackage();
+
+ Constructor<?> ctor = TestLoader.class.getDeclaredConstructor();
+ assertTrue(ctor.canAccess(null));
+ }
+
+ /**
+ * null object parameter for static members
+ */
+ public void testStaticMember() throws Exception {
+ Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError");
+ assertFalse(m.canAccess(null));
+ assertTrue(m.trySetAccessible());
+
+ try {
+ // non-null object parameter
+ m.canAccess(INSTANCE);
+ assertTrue(false);
+ } catch (IllegalArgumentException expected) { }
+ }
+
+ /**
+ * Test protected static
+ */
+ public void testProtectedStatic() throws Exception {
+ Method m = TestLoader.testProtectedStatic();
+ assertFalse(m.canAccess(null));
+ }
+
+ /**
+ * the specified object must be an instance of the declaring class
+ * for instance members
+ */
+ public void testInstanceMethod() throws Exception {
+ Method m = Unsafe.class.getDeclaredMethod("addressSize0");
+ assertFalse(m.canAccess(INSTANCE));
+
+ try {
+ m.canAccess(null);
+ assertTrue(false);
+ } catch (IllegalArgumentException expected) { }
+ }
+
+ /**
+ * the specified object must be an instance of the declaring class
+ * for instance members
+ */
+ public void testInvalidInstanceObject() throws Exception {
+ Class<?> clazz = Class.forName("sun.security.x509.X500Name");
+ Method m = clazz.getDeclaredMethod("size");
+
+ try {
+ m.canAccess(INSTANCE);
+ assertTrue(false);
+ } catch (IllegalArgumentException expected) { }
+ }
+
+
+ static class TestLoader extends SecureClassLoader {
+ public static Method testProtectedStatic() throws Exception {
+ Method m = ClassLoader.class.getDeclaredMethod("registerAsParallelCapable");
+ assertTrue(m.canAccess(null));
+ return m;
+ }
+
+ protected TestLoader() throws Exception {
+ Constructor<?> ctor = SecureClassLoader.class.getDeclaredConstructor();
+ assertFalse(ctor.canAccess(null));
+ assertFalse(ctor.trySetAccessible());
+ }
+
+ public static void testProtectedConstructorNonOpenedPackage() throws Exception {
+ new TestLoader();
+ }
+ }
+}
--- a/jdk/test/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/reflect/AccessibleObject/ModuleSetAccessibleTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -30,7 +30,6 @@
* @summary Test java.lang.reflect.AccessibleObject with modules
*/
-import java.lang.module.ModuleDescriptor;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessibleObject/TrySetAccessibleTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
+ * @build TrySetAccessibleTest
+ * @modules java.base/java.lang:open
+ * java.base/jdk.internal.perf
+ * java.base/jdk.internal.misc:+open
+ * @run testng TrySetAccessibleTest
+ * @summary Test AccessibleObject::trySetAccessible method
+ */
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import jdk.internal.misc.Unsafe;
+import jdk.internal.perf.Perf;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+@Test
+public class TrySetAccessibleTest {
+ /**
+ * Invoke a private constructor on a public class in an exported package
+ */
+ public void testPrivateConstructorInExportedPackage() throws Exception {
+ Constructor<?> ctor = Perf.class.getDeclaredConstructor();
+
+ try {
+ ctor.newInstance();
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ assertFalse(ctor.trySetAccessible());
+ assertFalse(ctor.canAccess(null));
+ }
+
+ /**
+ * Invoke a private constructor on a public class in an open package
+ */
+ public void testPrivateConstructorInOpenedPackage() throws Exception {
+ Constructor<?> ctor = Unsafe.class.getDeclaredConstructor();
+
+ try {
+ ctor.newInstance();
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ assertTrue(ctor.trySetAccessible());
+ assertTrue(ctor.canAccess(null));
+ Unsafe unsafe = (Unsafe) ctor.newInstance();
+ }
+
+ /**
+ * Invoke a private method on a public class in an exported package
+ */
+ public void testPrivateMethodInExportedPackage() throws Exception {
+ Method m = Perf.class.getDeclaredMethod("getBytes", String.class);
+ try {
+ m.invoke(null);
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ assertFalse(m.trySetAccessible());
+ assertFalse(m.canAccess(null));
+ }
+
+
+ /**
+ * Invoke a private method on a public class in an open package
+ */
+ public void testPrivateMethodInOpenedPackage() throws Exception {
+ Method m = Unsafe.class.getDeclaredMethod("throwIllegalAccessError");
+ assertFalse(m.canAccess(null));
+
+ try {
+ m.invoke(null);
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ assertTrue(m.trySetAccessible());
+ assertTrue(m.canAccess(null));
+ try {
+ m.invoke(null);
+ assertTrue(false);
+ } catch (InvocationTargetException e) {
+ // thrown by throwIllegalAccessError
+ assertTrue(e.getCause() instanceof IllegalAccessError);
+ }
+ }
+
+ /**
+ * Invoke a private method on a public class in an exported package
+ */
+ public void testPrivateFieldInExportedPackage() throws Exception {
+ Field f = Perf.class.getDeclaredField("instance");
+ try {
+ f.get(null);
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ assertFalse(f.trySetAccessible());
+ assertFalse(f.canAccess(null));
+ try {
+ f.get(null);
+ assertTrue(false);
+ } catch (IllegalAccessException expected) {}
+ }
+
+ /**
+ * Access a private field in a public class that is an exported package
+ */
+ public void testPrivateFieldInOpenedPackage() throws Exception {
+ Field f = Unsafe.class.getDeclaredField("theUnsafe");
+
+ try {
+ f.get(null);
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ assertTrue(f.trySetAccessible());
+ assertTrue(f.canAccess(null));
+ Unsafe unsafe = (Unsafe) f.get(null);
+ }
+
+
+ /**
+ * Invoke a public constructor on a public class in a non-exported package
+ */
+ public void testPublicConstructorInNonExportedPackage() throws Exception {
+ Class<?> clazz = Class.forName("sun.security.x509.X500Name");
+ Constructor<?> ctor = clazz.getConstructor(String.class);
+
+ try {
+ ctor.newInstance("cn=duke");
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ assertFalse(ctor.trySetAccessible());
+ assertFalse(ctor.canAccess(null));
+ assertTrue(ctor.trySetAccessible() == ctor.isAccessible());
+ }
+
+
+ /**
+ * Access a public field in a public class that in a non-exported package
+ */
+ public void testPublicFieldInNonExportedPackage() throws Exception {
+ Class<?> clazz = Class.forName("sun.security.x509.X500Name");
+ Field f = clazz.getField("SERIALNUMBER_OID");
+
+ try {
+ f.get(null);
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ assertFalse(f.trySetAccessible());
+ assertFalse(f.canAccess(null));
+ }
+
+
+ /**
+ * Test that the Class constructor cannot be make accessible.
+ */
+ public void testJavaLangClass() throws Exception {
+
+ // non-public constructor
+ Constructor<?> ctor
+ = Class.class.getDeclaredConstructor(ClassLoader.class, Class.class);
+ AccessibleObject[] ctors = { ctor };
+
+ assertFalse(ctor.trySetAccessible());
+ assertFalse(ctor.canAccess(null));
+ }
+
+}
--- a/jdk/test/java/lang/reflect/Layer/BasicLayerTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/reflect/Layer/BasicLayerTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 java.base/jdk.internal.misc
* @build BasicLayerTest ModuleUtils
* @compile layertest/Test.java
* @run testng BasicLayerTest
@@ -43,6 +44,7 @@
import java.util.Set;
import java.util.stream.Collectors;
+import jdk.internal.misc.SharedSecrets;
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@@ -50,6 +52,15 @@
public class BasicLayerTest {
/**
+ * Creates a "non-strict" builder for building a module. This allows the
+ * test the create ModuleDescriptor objects that do not require java.base.
+ */
+ private static ModuleDescriptor.Builder newBuilder(String mn) {
+ return SharedSecrets.getJavaLangModuleAccess()
+ .newModuleBuilder(mn, false, Set.of());
+ }
+
+ /**
* Exercise Layer.empty()
*/
public void testEmpty() {
@@ -109,25 +120,22 @@
* Exercise Layer defineModules, created with empty layer as parent
*/
public void testLayerOnEmpty() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
.exports("p1")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("m3")
.build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.build();
ModuleFinder finder
= ModuleUtils.finderOf(descriptor1, descriptor2, descriptor3);
- Configuration cf = resolveRequires(finder, "m1");
+ Configuration cf = resolve(finder, "m1");
// map each module to its own class loader for this test
ClassLoader loader1 = new ClassLoader() { };
@@ -191,15 +199,13 @@
* Exercise Layer defineModules, created with boot layer as parent
*/
public void testLayerOnBoot() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
.requires("java.base")
.exports("p1")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires("java.base")
.build();
@@ -207,7 +213,7 @@
= ModuleUtils.finderOf(descriptor1, descriptor2);
Configuration parent = Layer.boot().configuration();
- Configuration cf = resolveRequires(parent, finder, "m1");
+ Configuration cf = resolve(parent, finder, "m1");
ClassLoader loader = new ClassLoader() { };
@@ -256,21 +262,19 @@
* have the same module-private package.
*/
public void testPackageContainedInSelfAndOther() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
- .contains("p")
+ .packages(Set.of("p"))
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
- .contains("p")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
+ .packages(Set.of("p"))
.build();
ModuleFinder finder
= ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf = resolveRequires(finder, "m1");
+ Configuration cf = resolve(finder, "m1");
assertTrue(cf.modules().size() == 2);
// one loader per module, should be okay
@@ -292,22 +296,18 @@
public void testSameExportInPartitionedGraph() {
// m1 reads m2, m2 exports p to m1
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("m2")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.exports("p", Set.of("m1"))
.build();
// m3 reads m4, m4 exports p to m3
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m4")
.build();
- ModuleDescriptor descriptor4
- = ModuleDescriptor.module("m4")
+ ModuleDescriptor descriptor4 = newBuilder("m4")
.exports("p", Set.of("m3"))
.build();
@@ -317,7 +317,7 @@
descriptor3,
descriptor4);
- Configuration cf = resolveRequires(finder, "m1", "m3");
+ Configuration cf = resolve(finder, "m1", "m3");
assertTrue(cf.modules().size() == 4);
// one loader per module
@@ -353,16 +353,15 @@
ModuleDescriptor base = Object.class.getModule().getDescriptor();
assertTrue(base.packages().contains("sun.launcher"));
- ModuleDescriptor descriptor
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor = newBuilder("m1")
.requires("java.base")
- .contains("sun.launcher")
+ .packages(Set.of("sun.launcher"))
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor);
Configuration parent = Layer.boot().configuration();
- Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
+ Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));
assertTrue(cf.modules().size() == 1);
ClassLoader loader = new ClassLoader() { };
@@ -382,18 +381,16 @@
// cf1: m1 and m2, m2 requires transitive m1
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf1 = resolveRequires(finder1, "m2");
+ Configuration cf1 = resolve(finder1, "m2");
ClassLoader cl1 = new ClassLoader() { };
Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
@@ -401,14 +398,13 @@
// cf2: m3, m3 requires m2
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3);
- Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+ Configuration cf2 = resolve(cf1, finder2, "m3");
ClassLoader cl2 = new ClassLoader() { };
Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
@@ -456,13 +452,11 @@
// cf1: m1
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .build();
+ ModuleDescriptor descriptor1 = newBuilder("m1").build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
- Configuration cf1 = resolveRequires(finder1, "m1");
+ Configuration cf1 = resolve(finder1, "m1");
ClassLoader cl1 = new ClassLoader() { };
Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
@@ -470,19 +464,17 @@
// cf2: m2, m3: m2 requires transitive m1, m3 requires m2
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2, descriptor3);
- Configuration cf2 = resolveRequires(cf1, finder2, "m3");
+ Configuration cf2 = resolve(cf1, finder2, "m3");
ClassLoader cl2 = new ClassLoader() { };
Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
@@ -527,13 +519,11 @@
// cf1: m1
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .build();
+ ModuleDescriptor descriptor1 = newBuilder("m1").build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1);
- Configuration cf1 = resolveRequires(finder1, "m1");
+ Configuration cf1 = resolve(finder1, "m1");
ClassLoader cl1 = new ClassLoader() { };
Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
@@ -541,14 +531,13 @@
// cf2: m2 requires transitive m1
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor2);
- Configuration cf2 = resolveRequires(cf1, finder2, "m2");
+ Configuration cf2 = resolve(cf1, finder2, "m2");
ClassLoader cl2 = new ClassLoader() { };
Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
@@ -556,14 +545,13 @@
// cf3: m3 requires m2
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires("m2")
.build();
ModuleFinder finder3 = ModuleUtils.finderOf(descriptor3);
- Configuration cf3 = resolveRequires(cf2, finder3, "m3");
+ Configuration cf3 = resolve(cf2, finder3, "m3");
ClassLoader cl3 = new ClassLoader() { };
Layer layer3 = layer2.defineModules(cf3, mn -> cl3);
@@ -610,18 +598,16 @@
// cf1: m1, m2 requires transitive m1
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
- ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ ModuleDescriptor descriptor2 = newBuilder("m2")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m1")
.build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
- Configuration cf1 = resolveRequires(finder1, "m2");
+ Configuration cf1 = resolve(finder1, "m2");
ClassLoader cl1 = new ClassLoader() { };
Layer layer1 = Layer.empty().defineModules(cf1, mn -> cl1);
@@ -629,20 +615,18 @@
// cf2: m3 requires transitive m2, m4 requires m3
- ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3")
+ ModuleDescriptor descriptor3 = newBuilder("m3")
.requires(Set.of(Requires.Modifier.TRANSITIVE), "m2")
.build();
- ModuleDescriptor descriptor4
- = ModuleDescriptor.module("m4")
+ ModuleDescriptor descriptor4 = newBuilder("m4")
.requires("m3")
.build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
- Configuration cf2 = resolveRequires(cf1, finder2, "m3", "m4");
+ Configuration cf2 = resolve(cf1, finder2, "m3", "m4");
ClassLoader cl2 = new ClassLoader() { };
Layer layer2 = layer1.defineModules(cf2, mn -> cl2);
@@ -693,8 +677,7 @@
@Test(expectedExceptions = { LayerInstantiationException.class })
public void testModuleAlreadyDefinedToLoader() {
- ModuleDescriptor md
- = ModuleDescriptor.module("m")
+ ModuleDescriptor md = newBuilder("m")
.requires("java.base")
.build();
@@ -702,7 +685,7 @@
Configuration parent = Layer.boot().configuration();
- Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m"));
+ Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m"));
ClassLoader loader = new ClassLoader() { };
@@ -722,15 +705,13 @@
@Test(expectedExceptions = { LayerInstantiationException.class })
public void testPackageAlreadyInNamedModule() {
- ModuleDescriptor md1
- = ModuleDescriptor.module("m1")
- .contains("p")
+ ModuleDescriptor md1 = newBuilder("m1")
+ .packages(Set.of("p"))
.requires("java.base")
.build();
- ModuleDescriptor md2
- = ModuleDescriptor.module("m2")
- .contains("p")
+ ModuleDescriptor md2 = newBuilder("m2")
+ .packages(Set.of("p"))
.requires("java.base")
.build();
@@ -742,13 +723,13 @@
Configuration parent = Layer.boot().configuration();
- Configuration cf1 = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
+ Configuration cf1 = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));
Layer layer1 = Layer.boot().defineModules(cf1, mn -> loader);
// attempt to define m2 containing package p to class loader
- Configuration cf2 = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m2"));
+ Configuration cf2 = parent.resolve(finder, ModuleFinder.of(), Set.of("m2"));
// should throw exception because p already in m1
Layer layer2 = Layer.boot().defineModules(cf2, mn -> loader);
@@ -767,16 +748,15 @@
Class<?> c = layertest.Test.class;
assertFalse(c.getModule().isNamed()); // in unnamed module
- ModuleDescriptor md
- = ModuleDescriptor.module("m")
- .contains(c.getPackageName())
+ ModuleDescriptor md = newBuilder("m")
+ .packages(Set.of(c.getPackageName()))
.requires("java.base")
.build();
ModuleFinder finder = ModuleUtils.finderOf(md);
Configuration parent = Layer.boot().configuration();
- Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m"));
+ Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m"));
Layer.boot().defineModules(cf, mn -> c.getClassLoader());
}
@@ -786,8 +766,7 @@
* Attempt to create a Layer with a module named "java.base".
*/
public void testLayerWithJavaBase() {
- ModuleDescriptor descriptor
- = ModuleDescriptor.module("java.base")
+ ModuleDescriptor descriptor = newBuilder("java.base")
.exports("java.lang")
.build();
@@ -795,7 +774,7 @@
Configuration cf = Layer.boot()
.configuration()
- .resolveRequires(finder, ModuleFinder.of(), Set.of("java.base"));
+ .resolve(finder, ModuleFinder.of(), Set.of("java.base"));
assertTrue(cf.modules().size() == 1);
ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -824,16 +803,15 @@
*/
@Test(enabled = false)
public void testLayerWithJavaPackage() {
- ModuleDescriptor descriptor
- = ModuleDescriptor.module("foo")
- .contains("java.foo")
+ ModuleDescriptor descriptor = newBuilder("foo")
+ .packages(Set.of("java.foo"))
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor);
Configuration cf = Layer.boot()
.configuration()
- .resolveRequires(finder, ModuleFinder.of(), Set.of("foo"));
+ .resolve(finder, ModuleFinder.of(), Set.of("foo"));
assertTrue(cf.modules().size() == 1);
ClassLoader pcl = ClassLoader.getPlatformClassLoader();
@@ -870,15 +848,14 @@
*/
@Test(expectedExceptions = { LayerInstantiationException.class })
public void testLayerWithBootLoader() {
- ModuleDescriptor descriptor
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor = newBuilder("m1")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor);
Configuration cf = Layer.boot()
.configuration()
- .resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
+ .resolve(finder, ModuleFinder.of(), Set.of("m1"));
assertTrue(cf.modules().size() == 1);
Layer.boot().defineModules(cf, mn -> null );
@@ -891,15 +868,14 @@
@Test(expectedExceptions = { IllegalArgumentException.class })
public void testIncorrectParent1() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.requires("java.base")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
Configuration parent = Layer.boot().configuration();
- Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), Set.of("m1"));
+ Configuration cf = parent.resolve(finder, ModuleFinder.of(), Set.of("m1"));
ClassLoader loader = new ClassLoader() { };
Layer.empty().defineModules(cf, mn -> loader);
@@ -912,13 +888,12 @@
@Test(expectedExceptions = { IllegalArgumentException.class })
public void testIncorrectParent2() {
- ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
+ ModuleDescriptor descriptor1 = newBuilder("m1")
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1);
- Configuration cf = resolveRequires(finder, "m1");
+ Configuration cf = resolve(finder, "m1");
ClassLoader loader = new ClassLoader() { };
Layer.boot().defineModules(cf, mn -> loader);
@@ -935,7 +910,7 @@
@Test(expectedExceptions = { NullPointerException.class })
public void testCreateWithNull2() {
- Configuration cf = resolveRequires(Layer.boot().configuration(), ModuleFinder.of());
+ Configuration cf = resolve(Layer.boot().configuration(), ModuleFinder.of());
Layer.boot().defineModules(cf, null);
}
@@ -975,14 +950,14 @@
* Resolve the given modules, by name, and returns the resulting
* Configuration.
*/
- private static Configuration resolveRequires(Configuration cf,
- ModuleFinder finder,
- String... roots) {
- return cf.resolveRequires(finder, ModuleFinder.of(), Set.of(roots));
+ private static Configuration resolve(Configuration cf,
+ ModuleFinder finder,
+ String... roots) {
+ return cf.resolve(finder, ModuleFinder.of(), Set.of(roots));
}
- private static Configuration resolveRequires(ModuleFinder finder,
- String... roots) {
- return resolveRequires(Configuration.empty(), finder, roots);
+ private static Configuration resolve(ModuleFinder finder,
+ String... roots) {
+ return resolve(Configuration.empty(), finder, roots);
}
}
--- a/jdk/test/java/lang/reflect/Layer/LayerAndLoadersTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/reflect/Layer/LayerAndLoadersTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -81,7 +81,7 @@
*/
public void testWithOneLoader() throws Exception {
- Configuration cf = resolveRequires("m1");
+ Configuration cf = resolve("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -110,7 +110,7 @@
*/
public void testWithManyLoaders() throws Exception {
- Configuration cf = resolveRequires("m1");
+ Configuration cf = resolve("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -145,7 +145,7 @@
*/
public void testServicesWithOneLoader() throws Exception {
- Configuration cf = resolveRequiresAndUses("m1");
+ Configuration cf = resolveAndBind("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -186,7 +186,7 @@
*/
public void testServicesWithManyLoaders() throws Exception {
- Configuration cf = resolveRequiresAndUses("m1");
+ Configuration cf = resolveAndBind("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -233,7 +233,7 @@
*/
public void testDelegationToParent() throws Exception {
- Configuration cf = resolveRequires("m1");
+ Configuration cf = resolve("m1");
ClassLoader parent = this.getClass().getClassLoader();
String cn = this.getClass().getName();
@@ -267,16 +267,16 @@
public void testOverlappingPackages() {
ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1").exports("p").build();
+ = ModuleDescriptor.newModule("m1").exports("p").build();
ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2").exports("p").build();
+ = ModuleDescriptor.newModule("m2").exports("p").build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
Configuration cf = Layer.boot()
.configuration()
- .resolveRequires(finder, ModuleFinder.of(), Set.of("m1", "m2"));
+ .resolve(finder, ModuleFinder.of(), Set.of("m1", "m2"));
// cannot define both module m1 and m2 to the same class loader
try {
@@ -301,29 +301,29 @@
public void testSplitDelegation() {
ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1").exports("p").build();
+ = ModuleDescriptor.newModule("m1").exports("p").build();
ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2").exports("p").build();
+ = ModuleDescriptor.newModule("m2").exports("p").build();
ModuleFinder finder1 = ModuleUtils.finderOf(descriptor1, descriptor2);
Configuration cf1 = Layer.boot()
.configuration()
- .resolveRequires(finder1, ModuleFinder.of(), Set.of("m1", "m2"));
+ .resolve(finder1, ModuleFinder.of(), Set.of("m1", "m2"));
Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
checkLayer(layer1, "m1", "m2");
ModuleDescriptor descriptor3
- = ModuleDescriptor.module("m3").requires("m1").build();
+ = ModuleDescriptor.newModule("m3").requires("m1").build();
ModuleDescriptor descriptor4
- = ModuleDescriptor.module("m4").requires("m2").build();
+ = ModuleDescriptor.newModule("m4").requires("m2").build();
ModuleFinder finder2 = ModuleUtils.finderOf(descriptor3, descriptor4);
- Configuration cf2 = cf1.resolveRequires(finder2, ModuleFinder.of(),
+ Configuration cf2 = cf1.resolve(finder2, ModuleFinder.of(),
Set.of("m3", "m4"));
// package p cannot be supplied by two class loaders
@@ -349,13 +349,13 @@
*/
public void testOverriding1() throws Exception {
- Configuration cf1 = resolveRequires("m1");
+ Configuration cf1 = resolve("m1");
Layer layer1 = Layer.boot().defineModulesWithOneLoader(cf1, null);
checkLayer(layer1, "m1", "m2", "m3");
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
- Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
+ Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
Set.of("m1"));
Layer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
@@ -398,13 +398,13 @@
*/
public void testOverriding2() throws Exception {
- Configuration cf1 = resolveRequires("m1");
+ Configuration cf1 = resolve("m1");
Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
checkLayer(layer1, "m1", "m2", "m3");
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
- Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
+ Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
Set.of("m1"));
Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
@@ -492,14 +492,14 @@
*/
public void testOverriding3() throws Exception {
- Configuration cf1 = resolveRequires("m1");
+ Configuration cf1 = resolve("m1");
Layer layer1 = Layer.boot().defineModulesWithOneLoader(cf1, null);
checkLayer(layer1, "m1", "m2", "m3");
ModuleFinder finder = finderFor("m1", "m3");
- Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
+ Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
Set.of("m1"));
Layer layer2 = layer1.defineModulesWithOneLoader(cf2, null);
@@ -529,14 +529,14 @@
*/
public void testOverriding4() throws Exception {
- Configuration cf1 = resolveRequires("m1");
+ Configuration cf1 = resolve("m1");
Layer layer1 = Layer.boot().defineModulesWithManyLoaders(cf1, null);
checkLayer(layer1, "m1", "m2", "m3");
ModuleFinder finder = finderFor("m1", "m3");
- Configuration cf2 = cf1.resolveRequires(finder, ModuleFinder.of(),
+ Configuration cf2 = cf1.resolve(finder, ModuleFinder.of(),
Set.of("m1"));
Layer layer2 = layer1.defineModulesWithManyLoaders(cf2, null);
@@ -577,7 +577,7 @@
* Layer.defineModulesWithOneLoader.
*/
public void testResourcesOneLoader() throws Exception {
- Configuration cf = resolveRequires("m1");
+ Configuration cf = resolve("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = Layer.boot().defineModulesWithOneLoader(cf, scl);
ClassLoader loader = layer.findLoader("m1");
@@ -589,7 +589,7 @@
* Layer.defineModulesWithOneLoader.
*/
public void testResourcesManyLoaders() throws Exception {
- Configuration cf = resolveRequires("m1");
+ Configuration cf = resolve("m1");
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = Layer.boot().defineModulesWithManyLoaders(cf, scl);
ClassLoader loader = layer.findLoader("m1");
@@ -621,22 +621,22 @@
* Resolve the given modules, by name, and returns the resulting
* Configuration.
*/
- private static Configuration resolveRequires(String... roots) {
+ private static Configuration resolve(String... roots) {
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
return Layer.boot()
.configuration()
- .resolveRequires(finder, ModuleFinder.of(), Set.of(roots));
+ .resolve(finder, ModuleFinder.of(), Set.of(roots));
}
/**
* Resolve the given modules, by name, and returns the resulting
* Configuration.
*/
- private static Configuration resolveRequiresAndUses(String... roots) {
+ private static Configuration resolveAndBind(String... roots) {
ModuleFinder finder = ModuleFinder.of(MODS_DIR);
return Layer.boot()
.configuration()
- .resolveRequiresAndUses(finder, ModuleFinder.of(), Set.of(roots));
+ .resolveAndBind(finder, ModuleFinder.of(), Set.of(roots));
}
--- a/jdk/test/java/lang/reflect/Layer/LayerControllerTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/reflect/Layer/LayerControllerTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -50,22 +50,22 @@
*/
private Layer.Controller createTestLayer() {
ModuleDescriptor descriptor1
- = ModuleDescriptor.module("m1")
- .contains("p1")
+ = ModuleDescriptor.newModule("m1")
+ .packages(Set.of("p1"))
.requires("java.base")
.build();
ModuleDescriptor descriptor2
- = ModuleDescriptor.module("m2")
+ = ModuleDescriptor.newModule("m2")
.requires("java.base")
- .contains("p2")
+ .packages(Set.of("p2"))
.build();
ModuleFinder finder = ModuleUtils.finderOf(descriptor1, descriptor2);
Layer bootLayer = Layer.boot();
Configuration cf = bootLayer.configuration()
- .resolveRequires(finder, ModuleFinder.of(), Set.of("m1", "m2"));
+ .resolve(finder, ModuleFinder.of(), Set.of("m1", "m2"));
ClassLoader scl = ClassLoader.getSystemClassLoader();
@@ -193,4 +193,4 @@
assertTrue(false);
} catch (NullPointerException expected) { }
}
-}
\ No newline at end of file
+}
--- a/jdk/test/java/lang/reflect/Module/AnnotationsTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/reflect/Module/AnnotationsTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -144,7 +144,7 @@
Layer bootLayer = Layer.boot();
Configuration cf = bootLayer.configuration()
- .resolveRequires(finder, ModuleFinder.of(), Set.of(name));
+ .resolve(finder, ModuleFinder.of(), Set.of(name));
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
--- a/jdk/test/java/lang/reflect/Module/BasicModuleTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/reflect/Module/BasicModuleTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,10 @@
import java.lang.module.ResolvedModule;
import java.lang.reflect.Layer;
import java.lang.reflect.Module;
+import java.nio.file.spi.FileSystemProvider; // service type in java.base
import java.util.function.Predicate;
import java.util.stream.Stream;
+import javax.print.PrintServiceLookup; // service type in java.desktop
import org.testng.annotations.Test;
import static org.testng.Assert.*;
@@ -170,6 +172,14 @@
// canRead
assertTrue(base.canRead(base));
+ assertFalse(base.canRead(thisModule));
+
+ // addReads
+ try {
+ base.addReads(thisModule);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ assertFalse(base.canRead(thisModule));
// isExported
assertTrue(base.isExported("java.lang"));
@@ -182,6 +192,18 @@
assertFalse(base.isExported("java.wombat", thisModule));
assertFalse(base.isExported("java.wombat", base));
+ // addExports
+ try {
+ base.addExports("java.lang", thisModule);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ try {
+ base.addExports("jdk.internal.misc", thisModule);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ assertFalse(base.isExported("jdk.internal.misc"));
+ assertFalse(base.isExported("jdk.internal.misc", thisModule));
+
// isOpen
assertFalse(base.isOpen("java.lang"));
assertFalse(base.isOpen("java.lang", thisModule));
@@ -192,6 +214,29 @@
assertFalse(base.isOpen("java.wombat"));
assertFalse(base.isOpen("java.wombat", thisModule));
assertFalse(base.isOpen("java.wombat", base));
+
+ // addOpens
+ try {
+ base.addOpens("jdk.internal.misc", thisModule);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ assertFalse(base.isOpen("jdk.internal.misc"));
+ assertFalse(base.isOpen("jdk.internal.misc", thisModule));
+
+ // canUse
+ assertTrue(base.canUse(FileSystemProvider.class));
+ assertFalse(base.canUse(Thread.class));
+
+ // addUses
+ try {
+ base.addUses(FileSystemProvider.class);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ try {
+ base.addUses(Thread.class);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ assertFalse(base.canUse(Thread.class));
}
@@ -226,26 +271,68 @@
assertTrue(desktop.canRead(base));
assertTrue(desktop.canRead(xml));
+ // addReads
+ try {
+ desktop.addReads(thisModule);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ assertFalse(desktop.canRead(thisModule));
+
// isExported
assertTrue(desktop.isExported("java.awt"));
assertTrue(desktop.isExported("java.awt", thisModule));
+ assertFalse(desktop.isExported("sun.awt"));
+ assertFalse(desktop.isExported("sun.awt", thisModule));
+ assertTrue(desktop.isExported("sun.awt", desktop));
assertFalse(desktop.isExported("java.wombat"));
assertFalse(desktop.isExported("java.wombat", thisModule));
+ assertFalse(desktop.isExported("java.wombat", base));
+
+ // addExports
+ try {
+ desktop.addExports("java.awt", thisModule);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ try {
+ desktop.addExports("sun.awt", thisModule);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ assertFalse(desktop.isExported("sun.awt"));
+ assertFalse(desktop.isExported("sun.awt", thisModule));
+
+ // isOpen
+ assertFalse(desktop.isOpen("java.awt"));
+ assertFalse(desktop.isOpen("java.awt", thisModule));
+ assertTrue(desktop.isOpen("java.awt", desktop));
+ assertFalse(desktop.isOpen("sun.awt"));
+ assertFalse(desktop.isOpen("sun.awt", thisModule));
+ assertTrue(desktop.isOpen("sun.awt", desktop));
+ assertFalse(desktop.isOpen("java.wombat"));
+ assertFalse(desktop.isOpen("java.wombat", thisModule));
+ assertFalse(desktop.isOpen("java.wombat", desktop));
+
+ // addOpens
+ try {
+ base.addOpens("sun.awt", thisModule);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ assertFalse(desktop.isOpen("sun.awt"));
+ assertFalse(desktop.isOpen("sun.awt", thisModule));
+
+ // canUse
+ assertTrue(base.canUse(FileSystemProvider.class));
+ assertFalse(base.canUse(Thread.class));
+
+ // addUses
+ try {
+ desktop.addUses(PrintServiceLookup.class);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ try {
+ desktop.addUses(Thread.class);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ assertFalse(desktop.canUse(Thread.class));
}
-
- @Test(expectedExceptions = { NullPointerException.class })
- public void testIsExportedNull() {
- Module thisModule = this.getClass().getModule();
- thisModule.isExported(null, thisModule);
- }
-
-
- @Test(expectedExceptions = { NullPointerException.class })
- public void testIsExportedToNull() {
- Module thisModule = this.getClass().getModule();
- thisModule.isExported("", null);
- }
-
-
}
--- a/jdk/test/java/lang/reflect/Module/WithSecurityManager.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/reflect/Module/WithSecurityManager.java Wed Jul 05 22:52:22 2017 +0200
@@ -126,7 +126,7 @@
Layer bootLayer = Layer.boot();
Configuration cf = bootLayer
.configuration()
- .resolveRequires(finder, ModuleFinder.of(), Set.of(ANOTHER_MODULE));
+ .resolve(finder, ModuleFinder.of(), Set.of(ANOTHER_MODULE));
Layer layer = bootLayer.defineModulesWithOneLoader(cf, null);
Optional<Module> om = layer.findModule(mn);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/Driver.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
+ * @build test/* m1/* m2/* m3/* m4/*
+ * @run testng/othervm test/test.Main
+ * @summary Basic test case for Module::addXXX methods
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m1/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+module m1 {
+ exports p1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m1/p1/C.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p1;
+
+public class C {
+ public C() { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m2/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+module m2 {
+ exports p2;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m2/p2/C.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p2;
+
+import java.lang.reflect.Module;
+
+public class C {
+
+ public static void export(String pn, Module m) {
+ C.class.getModule().addExports(pn, m);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m2/p2/internal/C.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p2.internal;
+
+public class C {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m3/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+module m3 {
+ exports p3 to test;
+ opens p3 to test;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m3/p3/C.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p3;
+
+public class C {
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m4/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+module m4 {
+ exports p4;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/m4/p4/C.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p4;
+
+import java.lang.reflect.Constructor;
+
+public class C {
+ public static Object tryNewInstance(Class<?> clazz) throws Exception {
+ Constructor<?> ctor = clazz.getDeclaredConstructor();
+ return ctor.newInstance();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/test/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+module test {
+ exports test to testng;
+
+ requires m2;
+ requires m3;
+ requires m4;
+ requires testng;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/test/test/C.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 test;
+
+public class C { }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/test/test/Main.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,196 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 test;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Module;
+import java.util.ServiceConfigurationError;
+import java.util.ServiceLoader;
+
+import org.testng.annotations.Test;
+import static org.testng.Assert.*;
+
+/**
+ * Basic test case for Module::addXXXX methods
+ */
+
+@Test
+public class Main {
+
+ /**
+ * Test Module::addReads
+ *
+ * module test { }
+ *
+ * module m1 {
+ * exports p1;
+ * }
+ */
+ public void testAddReads() throws Throwable {
+ Module thisModule = Main.class.getModule();
+ Class<?> clazz = Class.forName("p1.C");
+ Module m1 = clazz.getModule();
+
+ // test does not read m1
+ assertFalse(thisModule.canRead(m1));
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(void.class);
+ try {
+ lookup.findConstructor(clazz, mt);
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ // update test to read m1
+ Module result = thisModule.addReads(m1);
+ assertTrue(result== thisModule);
+ assertTrue(thisModule.canRead(m1));
+ MethodHandle mh = lookup.findConstructor(clazz, mt);
+ Object obj = mh.invoke();
+
+ // attempt to update m1 to read test
+ try {
+ m1.addReads(thisModule);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ }
+
+
+ /**
+ * Test Module::addExports
+ *
+ * module test {
+ * requires m2;
+ * }
+ * module m2 {
+ * exports p2;
+ * contains package p2.internal;
+ * }
+ */
+ public void testAddExports() throws Exception {
+ Module thisModule = Main.class.getModule();
+ Module m2 = p2.C.class.getModule();
+ Class<?> targetClass = Class.forName("p2.internal.C");
+ String p2Internal = targetClass.getPackageName();
+ assertTrue(targetClass.getModule() == m2);
+
+ // m2 does not export p2.internal to test
+ assertFalse(m2.isExported(p2Internal, thisModule));
+ Constructor<?> ctor = targetClass.getDeclaredConstructor();
+ try {
+ ctor.newInstance();
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ // update m2 to export p2.internal to test
+ p2.C.export(p2Internal, thisModule);
+ assertTrue(m2.isExported(p2Internal, thisModule));
+ ctor.newInstance(); // should succeed
+
+ // attempt to update m2 to export a package to test
+ try {
+ m2.addExports("p2.other", thisModule);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ }
+
+ /**
+ * Test Module::addOpens
+ *
+ * module test {
+ * requires m3;
+ * requires m4;
+ * }
+ *
+ * module m3 {
+ * exports p3 to test;
+ * opens p3 to test;
+ * }
+ *
+ * module m4 {
+ * exports p4;
+ * }
+ */
+ public void testAddOpens() throws Exception {
+ Module thisModule = Main.class.getModule();
+ Module m3 = p3.C.class.getModule();
+ Module m4 = p4.C.class.getModule();
+
+ // test does not open package test to m4
+ assertFalse(thisModule.isOpen("test", m4));
+ try {
+ p4.C.tryNewInstance(test.C.class);
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+ // open test to m4
+ thisModule.addOpens("test", m4);
+ p4.C.tryNewInstance(test.C.class); // should succeed
+
+
+ // m3 does not open p3 to m4
+ assertFalse(m3.isOpen("p3", m4));
+ try {
+ p4.C.tryNewInstance(p3.C.class);
+ assertTrue(false);
+ } catch (IllegalAccessException expected) { }
+
+
+ // m3 opens p3 to test => test allowed to open m3/p3 to m4
+ assertTrue(m3.isOpen("p3", thisModule));
+ m3.addOpens("p3", m4);
+ assertTrue(m3.isOpen("p3", m4));
+ p4.C.tryNewInstance(p3.C.class); // should succeed
+
+
+ // attempt to update m4 to open package to m3
+ try {
+ m4.addOpens("p4", m3);
+ assertTrue(false);
+ } catch (IllegalCallerException expected) { }
+ }
+
+
+ /**
+ * Test Module::addUses
+ */
+ public void testAddUses() {
+ Module thisModule = Main.class.getModule();
+
+ assertFalse(thisModule.canUse(Service.class));
+ try {
+ ServiceLoader.load(Service.class);
+ assertTrue(false);
+ } catch (ServiceConfigurationError expected) { }
+
+ Module result = thisModule.addUses(Service.class);
+ assertTrue(result== thisModule);
+
+ assertTrue(thisModule.canUse(Service.class));
+ ServiceLoader.load(Service.class); // no exception
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/Module/addXXX/test/test/Service.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 test;
+
+/**
+ * Simple service type
+ */
+public interface Service { }
--- a/jdk/test/java/lang/reflect/Proxy/ProxyClassAccessTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/reflect/Proxy/ProxyClassAccessTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -91,7 +91,7 @@
Layer bootLayer = Layer.boot();
Configuration cf = bootLayer
.configuration()
- .resolveRequiresAndUses(ModuleFinder.of(), finder, modules);
+ .resolveAndBind(ModuleFinder.of(), finder, modules);
ClassLoader parentLoader = this.getClass().getClassLoader();
Layer layer = bootLayer.defineModulesWithOneLoader(cf, parentLoader);
--- a/jdk/test/java/lang/reflect/Proxy/ProxyLayerTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/reflect/Proxy/ProxyLayerTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -79,7 +79,7 @@
Layer bootLayer = Layer.boot();
Configuration cf = bootLayer
.configuration()
- .resolveRequiresAndUses(ModuleFinder.of(), finder, Arrays.asList(modules));
+ .resolveAndBind(ModuleFinder.of(), finder, Arrays.asList(modules));
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
@@ -113,7 +113,7 @@
Layer bootLayer = Layer.boot();
Configuration cf = bootLayer
.configuration()
- .resolveRequiresAndUses(ModuleFinder.of(), finder, Arrays.asList(modules));
+ .resolveAndBind(ModuleFinder.of(), finder, Arrays.asList(modules));
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
@@ -143,7 +143,7 @@
Layer bootLayer = Layer.boot();
Configuration cf = bootLayer
.configuration()
- .resolveRequiresAndUses(ModuleFinder.of(), finder, Arrays.asList(modules));
+ .resolveAndBind(ModuleFinder.of(), finder, Arrays.asList(modules));
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
--- a/jdk/test/java/lang/reflect/PublicMethods/PublicMethodsTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/lang/reflect/PublicMethods/PublicMethodsTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -57,6 +57,9 @@
/*
* @test
* @bug 8062389
+ * @modules java.compiler
+ * jdk.compiler
+ * jdk.zipfs
* @summary Nearly exhaustive test of Class.getMethod() and Class.getMethods()
* @run main PublicMethodsTest
*/
--- a/jdk/test/java/net/httpclient/security/Driver.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/net/httpclient/security/Driver.java Wed Jul 05 22:52:22 2017 +0200
@@ -127,6 +127,7 @@
cmd.add("-Dtest.src=" + testSrc);
cmd.add("-Dtest.classes=" + testClasses);
cmd.add("-Djava.security.manager");
+ cmd.add("--add-modules=jdk.incubator.httpclient");
cmd.add("-Djava.security.policy=" + testSrc + sep + policy);
cmd.add("-Dport.number=" + Integer.toString(Utils.getFreePort()));
cmd.add("-Dport.number1=" + Integer.toString(Utils.getFreePort()));
--- a/jdk/test/java/nio/channels/FileChannel/Transfer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/nio/channels/FileChannel/Transfer.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,43 +24,53 @@
/* @test
* @bug 4434723 4482726 4559072 4638365 4795550 5081340 5103988 6253145
* 6984545
- * @summary Test FileChannel.transferFrom and transferTo
+ * @summary Test FileChannel.transferFrom and transferTo (use -Dseed=X to set PRNG seed)
* @library ..
+ * @library /lib/testlibrary/
+ * @build jdk.testlibrary.*
+ * @run testng Transfer
* @key randomness
*/
-import java.io.*;
-import java.net.*;
-import java.nio.*;
-import java.nio.channels.*;
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.RandomAccessFile;
+import java.io.Reader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.NonReadableChannelException;
+import java.nio.channels.Pipe;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.nio.file.StandardOpenOption;
import java.nio.file.FileAlreadyExistsException;
import java.util.Random;
+import java.util.concurrent.TimeUnit;
+import jdk.testlibrary.RandomFactory;
+
+import org.testng.annotations.Test;
public class Transfer {
- private static Random generator = new Random();
-
- private static int[] testSizes = {
- 0, 10, 1023, 1024, 1025, 2047, 2048, 2049 };
+ private static Random generator = RandomFactory.getRandom();
+ private static PrintStream err = System.err;
+ private static PrintStream out = System.out;
- public static void main(String[] args) throws Exception {
- testFileChannel();
- for (int i=0; i<testSizes.length; i++)
- testReadableByteChannel(testSizes[i]);
- xferTest02(); // for bug 4482726
- xferTest03(); // for bug 4559072
- xferTest04(); // for bug 4638365
- xferTest05(); // for bug 4638365
- xferTest06(); // for bug 5081340
- xferTest07(); // for bug 5103988
- xferTest08(); // for bug 6253145
- xferTest09(); // for bug 6984545
- }
-
- private static void testFileChannel() throws Exception {
+ @Test
+ public void testFileChannel() throws Exception {
File source = File.createTempFile("source", null);
source.deleteOnExit();
File sink = File.createTempFile("sink", null);
@@ -105,52 +115,58 @@
sink.delete();
}
- private static void testReadableByteChannel(int size) throws Exception {
- SelectorProvider sp = SelectorProvider.provider();
- Pipe p = sp.openPipe();
- Pipe.SinkChannel sink = p.sink();
- Pipe.SourceChannel source = p.source();
- sink.configureBlocking(false);
+ @Test
+ public void testReadableByteChannel() throws Exception {
+ int[] testSizes = { 0, 10, 1023, 1024, 1025, 2047, 2048, 2049 };
- ByteBuffer outgoingdata = ByteBuffer.allocateDirect(size + 10);
- byte[] someBytes = new byte[size + 10];
- generator.nextBytes(someBytes);
- outgoingdata.put(someBytes);
- outgoingdata.flip();
+ for (int size : testSizes) {
+ SelectorProvider sp = SelectorProvider.provider();
+ Pipe p = sp.openPipe();
+ Pipe.SinkChannel sink = p.sink();
+ Pipe.SourceChannel source = p.source();
+ sink.configureBlocking(false);
- int totalWritten = 0;
- while (totalWritten < size + 10) {
- int written = sink.write(outgoingdata);
- if (written < 0)
- throw new Exception("Write failed");
- totalWritten += written;
- }
+ ByteBuffer outgoingdata = ByteBuffer.allocateDirect(size + 10);
+ byte[] someBytes = new byte[size + 10];
+ generator.nextBytes(someBytes);
+ outgoingdata.put(someBytes);
+ outgoingdata.flip();
- File f = File.createTempFile("blah"+size, null);
- f.deleteOnExit();
- RandomAccessFile raf = new RandomAccessFile(f, "rw");
- FileChannel fc = raf.getChannel();
- long oldPosition = fc.position();
+ int totalWritten = 0;
+ while (totalWritten < size + 10) {
+ int written = sink.write(outgoingdata);
+ if (written < 0)
+ throw new Exception("Write failed");
+ totalWritten += written;
+ }
- long bytesWritten = fc.transferFrom(source, 0, size);
- fc.force(true);
- if (bytesWritten != size)
- throw new RuntimeException("Transfer failed");
+ File f = File.createTempFile("blah"+size, null);
+ f.deleteOnExit();
+ RandomAccessFile raf = new RandomAccessFile(f, "rw");
+ FileChannel fc = raf.getChannel();
+ long oldPosition = fc.position();
- if (fc.position() != oldPosition)
- throw new RuntimeException("Position changed");
+ long bytesWritten = fc.transferFrom(source, 0, size);
+ fc.force(true);
+ if (bytesWritten != size)
+ throw new RuntimeException("Transfer failed");
- if (fc.size() != size)
- throw new RuntimeException("Unexpected sink size "+ fc.size());
+ if (fc.position() != oldPosition)
+ throw new RuntimeException("Position changed");
- fc.close();
- sink.close();
- source.close();
+ if (fc.size() != size)
+ throw new RuntimeException("Unexpected sink size "+ fc.size());
- f.delete();
+ fc.close();
+ sink.close();
+ source.close();
+
+ f.delete();
+ }
}
- public static void xferTest02() throws Exception {
+ @Test
+ public void xferTest02() throws Exception { // for bug 4482726
byte[] srcData = new byte[5000];
for (int i=0; i<5000; i++)
srcData[i] = (byte)generator.nextInt();
@@ -187,7 +203,8 @@
dest.delete();
}
- public static void xferTest03() throws Exception {
+ @Test
+ public void xferTest03() throws Exception { // for bug 4559072
byte[] srcData = new byte[] {1,2,3,4} ;
// get filechannel for the source file.
@@ -225,7 +242,8 @@
}
// Test transferTo with large file
- public static void xferTest04() throws Exception {
+ @Test
+ public void xferTest04() throws Exception { // for bug 4638365
// Windows and Linux can't handle the really large file sizes for a
// truncate or a positional write required by the test for 4563125
String osName = System.getProperty("os.name");
@@ -264,7 +282,8 @@
}
// Test transferFrom with large file
- public static void xferTest05() throws Exception {
+ @Test
+ public void xferTest05() throws Exception { // for bug 4638365
// Create a source file & large sink file for the test
File source = File.createTempFile("blech", null);
source.deleteOnExit();
@@ -294,7 +313,7 @@
testSize - 40);
} catch (IOException e) {
// Can't set up the test, abort it
- System.err.println("xferTest05 was aborted.");
+ err.println("xferTest05 was aborted.");
return;
} finally {
fc.close();
@@ -337,7 +356,8 @@
}
// Test transferFrom asking for more bytes than remain in source
- public static void xferTest06() throws Exception {
+ @Test
+ public void xferTest06() throws Exception { // for bug 5081340
String data = "Use the source, Luke!";
File source = File.createTempFile("source", null);
@@ -370,7 +390,8 @@
}
// Test transferTo to non-blocking socket channel
- public static void xferTest07() throws Exception {
+ @Test
+ public void xferTest07() throws Exception { // for bug 5103988
File source = File.createTempFile("source", null);
source.deleteOnExit();
@@ -405,7 +426,8 @@
// Test transferTo with file positions larger than 2 and 4GB
- public static void xferTest08() throws Exception {
+ @Test
+ public void xferTest08() throws Exception { // for bug 6253145
// Creating a sparse 6GB file on Windows takes too long
String osName = System.getProperty("os.name");
if (osName.startsWith("Windows"))
@@ -421,10 +443,15 @@
RandomAccessFile raf = new RandomAccessFile(file, "rw");
FileChannel fc = raf.getChannel();
+ out.println(" Creating large file...");
+ long t0 = System.nanoTime();
try {
fc.write(ByteBuffer.wrap("0123456789012345".getBytes("UTF-8")), 6*G);
+ long t1 = System.nanoTime();
+ out.printf(" Created large file in %d ns (%d ms) %n",
+ t1 - t0, TimeUnit.NANOSECONDS.toMillis(t1 - t0));
} catch (IOException x) {
- System.err.println("Unable to create test file:" + x);
+ err.println(" Unable to create test file:" + x);
fc.close();
return;
}
@@ -480,7 +507,10 @@
// write to file and transfer to echo server
fc.write(sendbuf, position);
+ t0 = System.nanoTime();
fc.transferTo(position, count, source);
+ out.printf(" transferTo(%d, %2d, source): %d ns%n",
+ position, count, System.nanoTime() - t0);
// read from echo server
long nread = 0;
@@ -495,7 +525,7 @@
readbuf.flip();
sendbuf.flip();
if (!readbuf.equals(sendbuf))
- throw new RuntimeException("Echo'ed bytes do not match!");
+ throw new RuntimeException("Echoed bytes do not match!");
readbuf.clear();
sendbuf.clear();
}
@@ -509,7 +539,8 @@
// Test that transferFrom with FileChannel source that is not readable
// throws NonReadableChannelException
- static void xferTest09() throws Exception {
+ @Test
+ public void xferTest09() throws Exception { // for bug 6984545
File source = File.createTempFile("source", null);
source.deleteOnExit();
--- a/jdk/test/java/nio/channels/Selector/SelectTimeout.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/nio/channels/Selector/SelectTimeout.java Wed Jul 05 22:52:22 2017 +0200
@@ -30,14 +30,13 @@
*/
import java.io.IOException;
import java.nio.channels.Selector;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
public class SelectTimeout {
private static final long BIG_TIMEOUT = 100_000_001_000L; // 8165000
private static final long BIGGER_TIMEOUT = 850_000_000_000_000L; // 8172547
- private static final long SLEEP_MILLIS = 10000;
-
- private static volatile Exception theException;
- private static volatile boolean isTimedOut;
+ private static final long SLEEP_MILLIS = 10_000;
public static void main(String[] args)
throws IOException, InterruptedException {
@@ -59,17 +58,18 @@
private static boolean test(final long timeout)
throws InterruptedException, IOException {
- theException = null;
+ AtomicReference<Exception> theException =
+ new AtomicReference<>();
+ AtomicBoolean isTimedOut = new AtomicBoolean();
Selector selector = Selector.open();
Thread t = new Thread(() -> {
try {
- isTimedOut = false;
selector.select(timeout);
- isTimedOut = true;
+ isTimedOut.set(true);
} catch (IOException ioe) {
- theException = ioe;
+ theException.set(ioe);
}
});
t.start();
@@ -77,8 +77,8 @@
t.join(SLEEP_MILLIS);
boolean result;
- if (theException == null) {
- if (timeout > SLEEP_MILLIS && isTimedOut) {
+ if (theException.get() == null) {
+ if (timeout > SLEEP_MILLIS && isTimedOut.get()) {
System.err.printf("Test timed out early with timeout %d%n",
timeout);
result = false;
@@ -88,11 +88,12 @@
}
} else {
System.err.printf("Test failed with timeout %d%n", timeout);
- theException.printStackTrace();
+ theException.get().printStackTrace();
result = false;
}
t.interrupt();
+ selector.close();
return result;
}
--- a/jdk/test/java/nio/file/FileSystem/Basic.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/nio/file/FileSystem/Basic.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -30,11 +30,18 @@
*/
import java.io.File;
-import java.nio.file.*;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
+import java.nio.file.Files;
+import java.nio.file.FileStore;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.ProviderNotFoundException;
import java.util.HashMap;
+import java.util.concurrent.TimeUnit;
import jdk.testlibrary.FileUtils;
/**
@@ -47,6 +54,44 @@
throw new RuntimeException(msg);
}
+ static void checkFileStores(String os, FileSystem fs) throws IOException {
+ boolean checkFileStores = true;
+ if (!os.equals("Windows")) {
+ // try to check whether 'df' hangs
+ System.out.println("\n--- Begin df output ---");
+ System.out.flush();
+ Process proc = new ProcessBuilder("df").inheritIO().start();
+ try {
+ proc.waitFor(90, TimeUnit.SECONDS);
+ } catch (InterruptedException ignored) {
+ }
+ System.out.println("--- End df output ---\n");
+ System.out.flush();
+ try {
+ int exitValue = proc.exitValue();
+ if (exitValue != 0) {
+ System.err.printf("df process exited with %d != 0%n",
+ exitValue);
+ checkFileStores = false;
+ }
+ } catch (IllegalThreadStateException ignored) {
+ System.err.println("df command apparently hung");
+ checkFileStores = false;
+ }
+ }
+
+ // sanity check method
+ if (checkFileStores) {
+ System.out.println("\n--- Begin FileStores ---");
+ for (FileStore store: fs.getFileStores()) {
+ System.out.println(store);
+ }
+ System.out.println("--- EndFileStores ---\n");
+ } else {
+ System.err.println("Skipping FileStore check due to df failure");
+ }
+ }
+
static void checkSupported(FileSystem fs, String... views) {
for (String view: views) {
check(fs.supportedFileAttributeViews().contains(view),
@@ -70,7 +115,9 @@
}
}
- public static void main(String[] args) throws IOException, URISyntaxException {
+ public static void main(String[] args)
+ throws IOException, URISyntaxException {
+ String os = System.getProperty("os.name");
FileSystem fs = FileSystems.getDefault();
// close should throw UOE
@@ -85,15 +132,11 @@
check(fs.provider().getScheme().equals("file"),
"should use 'file' scheme");
- // santity check method - need to re-visit this in future as I/O errors
- // are possible
- for (FileStore store: fs.getFileStores()) {
- System.out.println(store);
- }
+ // sanity check FileStores
+ checkFileStores(os, fs);
// sanity check supportedFileAttributeViews
checkSupported(fs, "basic");
- String os = System.getProperty("os.name");
if (os.equals("SunOS"))
checkSupported(fs, "posix", "unix", "owner", "acl", "user");
if (os.equals("Linux"))
--- a/jdk/test/java/security/modules/ModularTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/security/modules/ModularTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -164,9 +164,9 @@
final Builder builder;
if (moduleType == MODULE_TYPE.EXPLICIT) {
System.out.format(" %nGenerating ModuleDescriptor object");
- builder = ModuleDescriptor.module(moduleName).exports(pkg);
+ builder = ModuleDescriptor.newModule(moduleName).exports(pkg);
if (isService && serviceInterface != null && serviceImpl != null) {
- builder.provides(serviceInterface, serviceImpl);
+ builder.provides(serviceInterface, List.of(serviceImpl));
} else {
if (serviceInterface != null) {
builder.uses(serviceInterface);
--- a/jdk/test/java/time/TEST.properties Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/time/TEST.properties Wed Jul 05 22:52:22 2017 +0200
@@ -1,6 +1,5 @@
-# Threeten test uses TestNG
+# java.time tests use TestNG
TestNG.dirs = .
othervm.dirs = tck/java/time/chrono test/java/time/chrono test/java/time/format
lib.dirs = ../../lib/testlibrary
lib.build = jdk.testlibrary.RandomFactory
-modules = java.base/java.time:open java.base/java.time.chrono:open java.base/java.time.zone:open
--- a/jdk/test/java/time/tck/java/time/AbstractTCKTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/time/tck/java/time/AbstractTCKTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,14 +69,35 @@
import java.io.ObjectOutputStream;
import java.io.ObjectStreamConstants;
import java.io.Serializable;
-import java.lang.reflect.Field;
import java.util.Formatter;
+import java.util.Map;
/**
* Base test class.
*/
public abstract class AbstractTCKTest {
+ /**
+ * Map from package name to the serialVersionUID of the .Ser class for the package.
+ */
+ private static Map<String, Long> serialVersionUIDs = Map.of(
+ "java.time", -7683839454370182990L,
+ "java.time.chrono", -6103370247208168577L,
+ "java.time.zone", -8885321777449118786L
+ );
+
+ /**
+ * Returns the serialVersionUID for the class.
+ * The SUIDs are defined by the specification for each class.
+ * @param serClass the class to return the SUID of
+ * @return returns the serialVersionUID for the class
+ */
+ public final static long getSUID(Class<?> serClass) {
+ String pkgName = serClass.getPackageName();
+ return serialVersionUIDs.get(pkgName);
+ }
+
+
protected static boolean isIsoLeap(long year) {
if (year % 4 != 0) {
return false;
@@ -111,10 +132,8 @@
protected static void assertSerializedBySer(Object object, byte[] expectedBytes, byte[]... matches) throws Exception {
String serClass = object.getClass().getPackage().getName() + ".Ser";
- Class<?> serCls = Class.forName(serClass);
- Field field = serCls.getDeclaredField("serialVersionUID");
- field.setAccessible(true);
- long serVer = (Long) field.get(null);
+ long serVer = getSUID(object.getClass());
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (ObjectOutputStream oos = new ObjectOutputStream(baos) ) {
oos.writeObject(object);
@@ -172,9 +191,8 @@
* @throws Exception if an unexpected condition occurs
*/
protected static void assertNotSerializable(Class<?> serClass) throws Exception {
- Field field = serClass.getDeclaredField("serialVersionUID");
- field.setAccessible(true);
- long serVer = (Long) field.get(null);
+ long serVer = getSUID(serClass);
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (DataOutputStream out = new DataOutputStream(baos)) {
out.writeShort(ObjectStreamConstants.STREAM_MAGIC);
@@ -201,7 +219,6 @@
fail("Class should not be deserializable " + serClass.getName());
}
-
/**
* Utility method to dump a byte array in a java syntax.
* @param bytes and array of bytes
--- a/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/time/tck/java/time/TCKOffsetDateTime.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -104,8 +104,6 @@
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.time.Clock;
import java.time.DateTimeException;
import java.time.Duration;
@@ -470,24 +468,12 @@
//-----------------------------------------------------------------------
@Test(expectedExceptions=NullPointerException.class)
public void constructor_nullTime() throws Throwable {
- Constructor<OffsetDateTime> con = OffsetDateTime.class.getDeclaredConstructor(LocalDateTime.class, ZoneOffset.class);
- con.setAccessible(true);
- try {
- con.newInstance(null, OFFSET_PONE);
- } catch (InvocationTargetException ex) {
- throw ex.getCause();
- }
+ OffsetDateTime.of(null, OFFSET_PONE);
}
@Test(expectedExceptions=NullPointerException.class)
public void constructor_nullOffset() throws Throwable {
- Constructor<OffsetDateTime> con = OffsetDateTime.class.getDeclaredConstructor(LocalDateTime.class, ZoneOffset.class);
- con.setAccessible(true);
- try {
- con.newInstance(LocalDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30)), null);
- } catch (InvocationTargetException ex) {
- throw ex.getCause();
- }
+ OffsetDateTime.of(LocalDateTime.of(LocalDate.of(2008, 6, 30), LocalTime.of(11, 30)), null);
}
//-----------------------------------------------------------------------
--- a/jdk/test/java/time/tck/java/time/TCKOffsetTime.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/time/tck/java/time/TCKOffsetTime.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -89,8 +89,6 @@
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
import java.time.Clock;
import java.time.DateTimeException;
import java.time.Instant;
@@ -465,28 +463,16 @@
}
//-----------------------------------------------------------------------
- // constructor
+ // constructor via factory
//-----------------------------------------------------------------------
@Test(expectedExceptions=NullPointerException.class)
public void constructor_nullTime() throws Throwable {
- Constructor<OffsetTime> con = OffsetTime.class.getDeclaredConstructor(LocalTime.class, ZoneOffset.class);
- con.setAccessible(true);
- try {
- con.newInstance(null, OFFSET_PONE);
- } catch (InvocationTargetException ex) {
- throw ex.getCause();
- }
+ OffsetTime.of(null, OFFSET_PONE);
}
@Test(expectedExceptions=NullPointerException.class)
public void constructor_nullOffset() throws Throwable {
- Constructor<OffsetTime> con = OffsetTime.class.getDeclaredConstructor(LocalTime.class, ZoneOffset.class);
- con.setAccessible(true);
- try {
- con.newInstance(LocalTime.of(11, 30, 0, 0), null);
- } catch (InvocationTargetException ex) {
- throw ex.getCause();
- }
+ OffsetTime.of(LocalTime.of(11, 30, 0, 0), null);
}
//-----------------------------------------------------------------------
--- a/jdk/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/time/tck/java/time/serial/TCKZoneIdSerialization.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -63,8 +63,11 @@
import org.testng.annotations.Test;
import tck.java.time.AbstractTCKTest;
-import java.io.*;
-import java.lang.reflect.Field;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamConstants;
import java.time.DateTimeException;
import java.time.ZoneId;
import java.time.zone.ZoneRulesException;
@@ -153,10 +156,8 @@
private ZoneId deserialize(String id) throws Exception {
String serClass = ZoneId.class.getPackage().getName() + ".Ser";
- Class<?> serCls = Class.forName(serClass);
- Field field = serCls.getDeclaredField("serialVersionUID");
- field.setAccessible(true);
- long serVer = (Long) field.get(null);
+ long serVer = getSUID(ZoneId.class);
+
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (DataOutputStream dos = new DataOutputStream(baos)) {
dos.writeShort(ObjectStreamConstants.STREAM_MAGIC);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/time/test/java/time/TEST.properties Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,2 @@
+# java.time test system clock
+modules = java.base/java.time:open
--- a/jdk/test/java/util/ServiceLoader/modules/BadProvidersTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/BadProvidersTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -90,7 +90,7 @@
Layer bootLayer = Layer.boot();
Configuration cf = bootLayer.configuration()
- .resolveRequiresAndUses(finder, ModuleFinder.of(), Set.of(moduleName));
+ .resolveAndBind(finder, ModuleFinder.of(), Set.of(moduleName));
ClassLoader scl = ClassLoader.getSystemClassLoader();
--- a/jdk/test/java/util/ServiceLoader/modules/Basic.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/java/util/ServiceLoader/modules/Basic.java Wed Jul 05 22:52:22 2017 +0200
@@ -311,17 +311,17 @@
ModuleFinder finder = ModuleFinder.of(dir);
// layer1
- Configuration cf1 = cf0.resolveRequiresAndUses(finder, ModuleFinder.of(), Set.of());
+ Configuration cf1 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
Layer layer1 = bootLayer.defineModulesWithOneLoader(cf1, scl);
assertTrue(layer1.modules().size() == 1);
// layer2
- Configuration cf2 = cf0.resolveRequiresAndUses(finder, ModuleFinder.of(), Set.of());
+ Configuration cf2 = cf0.resolveAndBind(finder, ModuleFinder.of(), Set.of());
Layer layer2 = bootLayer.defineModulesWithOneLoader(cf2, scl);
assertTrue(layer2.modules().size() == 1);
// layer3 with layer1 and layer2 as parents
- Configuration cf3 = Configuration.resolveRequiresAndUses(finder,
+ Configuration cf3 = Configuration.resolveAndBind(finder,
List.of(cf1, cf2),
ModuleFinder.of(),
Set.of());
@@ -413,7 +413,7 @@
Collections.addAll(roots, modules);
Layer bootLayer = Layer.boot();
Configuration parent = bootLayer.configuration();
- Configuration cf = parent.resolveRequires(finder, ModuleFinder.of(), roots);
+ Configuration cf = parent.resolve(finder, ModuleFinder.of(), roots);
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = bootLayer.defineModulesWithOneLoader(cf, scl);
assertTrue(layer.modules().size() == 1);
--- a/jdk/test/javax/xml/jaxp/common/8035437/Document.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,28 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.w3c.dom;
-
-public interface Document {
-
- public org.w3c.dom.DocumentType getDoctype();
-}
--- a/jdk/test/javax/xml/jaxp/common/8035437/DocumentImpl.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +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.
- *
- * 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.sun.org.apache.xerces.internal.dom;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.DOMImplementation;
-
-public class DocumentImpl implements Document, Node {
-
- public short getNodeType() {
- return 9; //DOCUMENT_NODE = 9
- }
-
- public org.w3c.dom.Document getOwnerDocument() {
- return null;
- }
-
- public Node getFirstChild() {
- return null;
- }
-
- public String getPrefix() {
- return "TestPrefix";
- }
-
- public String getLocalName() {
- return "LocalName";
- }
-
- public boolean hasAttributes() {
- return false;
- }
-
- public Node renameNode(Node n, String namespaceURI, String name) {
- return n;
- }
-
- public org.w3c.dom.DocumentType getDoctype() {
- return null;
- }
-
- public DOMImplementation getImplementation() {
- return DOMImplementationImpl.getDOMImplementation();
- }
-
-}
--- a/jdk/test/javax/xml/jaxp/common/8035437/Node.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package org.w3c.dom;
-
-public interface Node {
-
- public short getNodeType();
-
- public org.w3c.dom.Document getOwnerDocument();
-
- public Node getFirstChild();
-
- public String getPrefix();
-
- public String getLocalName();
-
- public boolean hasAttributes();
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/common/8035437/patch-src1/org/w3c/dom/Document.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.w3c.dom;
+
+public interface Document {
+
+ public org.w3c.dom.DocumentType getDoctype();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/common/8035437/patch-src1/org/w3c/dom/Node.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package org.w3c.dom;
+
+public interface Node {
+
+ public short getNodeType();
+
+ public org.w3c.dom.Document getOwnerDocument();
+
+ public Node getFirstChild();
+
+ public String getPrefix();
+
+ public String getLocalName();
+
+ public boolean hasAttributes();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/xml/jaxp/common/8035437/patch-src2/com/sun/org/apache/xerces/internal/dom/DocumentImpl.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ *
+ * 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.sun.org.apache.xerces.internal.dom;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.DOMImplementation;
+
+public class DocumentImpl implements Document, Node {
+
+ public short getNodeType() {
+ return 9; //DOCUMENT_NODE = 9
+ }
+
+ public org.w3c.dom.Document getOwnerDocument() {
+ return null;
+ }
+
+ public Node getFirstChild() {
+ return null;
+ }
+
+ public String getPrefix() {
+ return "TestPrefix";
+ }
+
+ public String getLocalName() {
+ return "LocalName";
+ }
+
+ public boolean hasAttributes() {
+ return false;
+ }
+
+ public Node renameNode(Node n, String namespaceURI, String name) {
+ return n;
+ }
+
+ public org.w3c.dom.DocumentType getDoctype() {
+ return null;
+ }
+
+ public DOMImplementation getImplementation() {
+ return DOMImplementationImpl.getDOMImplementation();
+ }
+
+}
--- a/jdk/test/javax/xml/jaxp/common/8035437/run.sh Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/javax/xml/jaxp/common/8035437/run.sh Wed Jul 05 22:52:22 2017 +0200
@@ -28,13 +28,43 @@
# @summary Tests that java.lang.AbstractMethodError is not thrown when
# serializing improper version of DocumentImpl class.
+OS=`uname -s`
+case "$OS" in
+ SunOS )
+ PS=":"
+ ;;
+ Linux )
+ PS=":"
+ ;;
+ Darwin )
+ PS=":"
+ ;;
+ AIX )
+ PS=":"
+ ;;
+ Windows*)
+ PS=";"
+ ;;
+ CYGWIN*)
+ PS=";"
+ ;;
+ * )
+ echo "Unrecognized system!"
+ exit 1;
+ ;;
+esac
+
mkdir -p exec/java.xml compile/java.xml
$COMPILEJAVA/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
- -d compile/java.xml -Xmodule:java.xml $TESTSRC/Document.java $TESTSRC/Node.java || exit 1
+ -d compile/java.xml --patch-module java.xml=$TESTSRC/patch-src1 \
+ $TESTSRC/patch-src1/org/w3c/dom/Document.java \
+ $TESTSRC/patch-src1/org/w3c/dom/Node.java || exit 1
$COMPILEJAVA/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
- -d exec/java.xml --patch-module java.xml=compile/java.xml -Xmodule:java.xml $TESTSRC/DocumentImpl.java || exit 2
+ -d exec/java.xml --patch-module java.xml=compile/java.xml${PS}$TESTSRC/patch-src2 \
+ $TESTSRC/patch-src2/com/sun/org/apache/xerces/internal/dom/DocumentImpl.java \
+ || exit 2
$COMPILEJAVA/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
$TESTSRC/AbstractMethodErrorTest.java -d exec || exit 3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/jdk/internal/reflect/CallerSensitive/CheckCSMs.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,251 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 com.sun.tools.classfile.*;
+import com.sun.tools.jdeps.ClassFileReader;
+import static com.sun.tools.classfile.ConstantPool.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.net.URI;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ConcurrentSkipListSet;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/*
+ * @test
+ * @summary CallerSensitive methods should be static or final instance
+ * methods except the known list of non-final instance methods
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ * jdk.jdeps/com.sun.tools.jdeps
+ * @build CheckCSMs
+ * @run main/othervm/timeout=900 CheckCSMs
+ */
+public class CheckCSMs {
+ private static int numThreads = 3;
+ private static boolean listCSMs = false;
+ private final ExecutorService pool;
+
+ // The goal is to remove this list of Non-final instance @CS methods
+ // over time. Do not add any new one to this list.
+ private static Set<String> KNOWN_NON_FINAL_CSMS =
+ Set.of("java/io/ObjectStreamField#getType ()Ljava/lang/Class;",
+ "java/io/ObjectStreamClass#forClass ()Ljava/lang/Class;",
+ "java/lang/Runtime#load (Ljava/lang/String;)V",
+ "java/lang/Runtime#loadLibrary (Ljava/lang/String;)V",
+ "java/lang/Thread#getContextClassLoader ()Ljava/lang/ClassLoader;",
+ "javax/sql/rowset/serial/SerialJavaObject#getFields ()[Ljava/lang/reflect/Field;"
+ );
+
+ public static void main(String[] args) throws Exception {
+ if (args.length > 0 && args[0].equals("--list")) {
+ listCSMs = true;
+ }
+
+ CheckCSMs checkCSMs = new CheckCSMs();
+ Set<String> result = checkCSMs.run(getPlatformClasses());
+ if (!KNOWN_NON_FINAL_CSMS.equals(result)) {
+ Set<String> diff = new HashSet<>(result);
+ diff.removeAll(KNOWN_NON_FINAL_CSMS);
+ throw new RuntimeException("Unexpected non-final instance method: " +
+ result.stream().sorted()
+ .collect(Collectors.joining("\n", "\n", "")));
+ }
+ }
+
+ private final Set<String> nonFinalCSMs = new ConcurrentSkipListSet<>();
+ private final ReferenceFinder finder;
+ public CheckCSMs() {
+ this.finder = new ReferenceFinder(getFilter(), getVisitor());
+ pool = Executors.newFixedThreadPool(numThreads);
+
+ }
+
+ public Set<String> run(Stream<Path> classes)
+ throws IOException, InterruptedException, ExecutionException,
+ ConstantPoolException
+ {
+ classes.forEach(this::processPath);
+ waitForCompletion();
+ pool.shutdown();
+ return nonFinalCSMs;
+ }
+
+
+ private ReferenceFinder.Filter getFilter() {
+ final String classname = "jdk/internal/reflect/Reflection";
+ final String method = "getCallerClass";
+ return new ReferenceFinder.Filter() {
+ public boolean accept(ConstantPool cpool, CPRefInfo cpref) {
+ try {
+ CONSTANT_NameAndType_info nat = cpref.getNameAndTypeInfo();
+ return cpref.getClassName().equals(classname) && nat.getName().equals(method);
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ };
+ }
+
+ private ReferenceFinder.Visitor getVisitor() {
+ return new ReferenceFinder.Visitor() {
+ public void visit(ClassFile cf, Method m, List<CPRefInfo> refs) {
+ try {
+ // ignore jdk.unsupported/sun.reflect.Reflection.getCallerClass
+ // which is a "special" delegate to the internal getCallerClass
+ if (cf.getName().equals("sun/reflect/Reflection") &&
+ m.getName(cf.constant_pool).equals("getCallerClass"))
+ return;
+
+ String name = String.format("%s#%s %s", cf.getName(),
+ m.getName(cf.constant_pool),
+ m.descriptor.getValue(cf.constant_pool));
+ if (!CheckCSMs.isStaticOrFinal(cf, m, cf.constant_pool)) {
+ System.err.println("Unsupported @CallerSensitive: " + name);
+ nonFinalCSMs.add(name);
+ } else {
+ if (listCSMs) {
+ System.out.format("@CS %s%n", name);
+ }
+ }
+ } catch (ConstantPoolException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ };
+ }
+
+ void processPath(Path path) {
+ try {
+ ClassFileReader reader = ClassFileReader.newInstance(path);
+ for (ClassFile cf : reader.getClassFiles()) {
+ if (cf.access_flags.is(AccessFlags.ACC_MODULE))
+ continue;
+
+ String classFileName = cf.getName();
+ // for each ClassFile
+ // parse constant pool to find matching method refs
+ // parse each method (caller)
+ // - visit and find method references matching the given method name
+ pool.submit(getTask(cf));
+ }
+ } catch (IOException x) {
+ throw new UncheckedIOException(x);
+ } catch (ConstantPoolException x) {
+ throw new RuntimeException(x);
+ }
+ }
+
+ private static final String CALLER_SENSITIVE_ANNOTATION
+ = "Ljdk/internal/reflect/CallerSensitive;";
+
+ private static boolean isCallerSensitive(Method m, ConstantPool cp)
+ throws ConstantPoolException
+ {
+ RuntimeAnnotations_attribute attr =
+ (RuntimeAnnotations_attribute)m.attributes.get(Attribute.RuntimeVisibleAnnotations);
+ if (attr != null) {
+ for (int i = 0; i < attr.annotations.length; i++) {
+ Annotation ann = attr.annotations[i];
+ String annType = cp.getUTF8Value(ann.type_index);
+ if (CALLER_SENSITIVE_ANNOTATION.equals(annType)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean isStaticOrFinal(ClassFile cf, Method m, ConstantPool cp)
+ throws ConstantPoolException
+ {
+ if (!isCallerSensitive(m, cp))
+ return false;
+
+ // either a static method or a final instance method
+ return m.access_flags.is(AccessFlags.ACC_STATIC) ||
+ m.access_flags.is(AccessFlags.ACC_FINAL) ||
+ cf.access_flags.is(AccessFlags.ACC_FINAL);
+ }
+
+ private final List<FutureTask<Void>> tasks = new ArrayList<FutureTask<Void>>();
+ private FutureTask<Void> getTask(final ClassFile cf) {
+ FutureTask<Void> task = new FutureTask<Void>(new Callable<Void>() {
+ public Void call() throws Exception {
+ finder.parse(cf);
+ return null;
+ }
+ });
+ tasks.add(task);
+ return task;
+ }
+
+ private void waitForCompletion() throws InterruptedException, ExecutionException {
+ for (FutureTask<Void> t : tasks) {
+ t.get();
+ }
+ if (tasks.isEmpty()) {
+ throw new RuntimeException("No classes found, or specified.");
+ }
+ System.out.println("Parsed " + tasks.size() + " classfiles");
+ }
+
+ static Stream<Path> getPlatformClasses() throws IOException {
+ Path home = Paths.get(System.getProperty("java.home"));
+
+ // Either an exploded build or an image.
+ File classes = home.resolve("modules").toFile();
+ if (classes.isDirectory()) {
+ return Stream.of(classes.toPath());
+ } else {
+ return jrtPaths();
+ }
+ }
+
+ static Stream<Path> jrtPaths() {
+ FileSystem jrt = FileSystems.getFileSystem(URI.create("jrt:/"));
+ Path root = jrt.getPath("/");
+
+ try {
+ return Files.walk(root)
+ .filter(p -> p.getNameCount() > 1)
+ .filter(p -> p.toString().endsWith(".class"));
+ } catch (IOException x) {
+ throw new UncheckedIOException(x);
+ }
+ }
+}
--- a/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/jdk/modules/etc/VerifyModuleDelegation.java Wed Jul 05 22:52:22 2017 +0200
@@ -46,7 +46,7 @@
private static final String JAVA_BASE = "java.base";
private static final ModuleDescriptor BASE
- = ModuleDescriptor.module(JAVA_BASE).build();
+ = ModuleDescriptor.newModule(JAVA_BASE).build();
private static final Set<ModuleDescriptor> MREFS
= Layer.boot().modules().stream().map(Module::getDescriptor)
--- a/jdk/test/jdk/modules/scenarios/container/src/container/container/Main.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/jdk/modules/scenarios/container/src/container/container/Main.java Wed Jul 05 22:52:22 2017 +0200
@@ -71,9 +71,9 @@
ModuleFinder finder = ModuleFinder.of(paths);
Configuration cf = Layer.boot().configuration()
- .resolveRequiresAndUses(finder,
- ModuleFinder.of(),
- Set.of(appModuleName));
+ .resolveAndBind(finder,
+ ModuleFinder.of(),
+ Set.of(appModuleName));
System.out.println("Resolved");
cf.modules().stream()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/org/omg/CORBA/OrbPropertiesTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.BufferedWriter;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+
+import org.omg.CORBA.ORB;
+
+/*
+ * @test
+ * @bug 8049375
+ * @summary Extend how the org.omg.CORBA.ORB handles the search for orb.properties
+ * @library /lib/testlibrary
+ * @build jdk.testlibrary.*
+ * @modules java.corba
+ * @compile OrbPropertiesTest.java TestOrbImpl.java TestSingletonOrbImpl.java
+ * @run main/othervm
+ * -Djava.naming.provider.url=iiop://localhost:1050
+ * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ * OrbPropertiesTest -port 1049
+ * @run main/othervm/secure=java.lang.SecurityManager/policy=jtreg.test.policy
+ * -Djava.naming.provider.url=iiop://localhost:3050
+ * -Djava.naming.factory.initial=com.sun.jndi.cosnaming.CNCtxFactory
+ * OrbPropertiesTest -port 3049
+ */
+public class OrbPropertiesTest {
+
+ public static void main(String[] args) throws Exception {
+ updateOrbPropertiesFile();
+ // create and initialize the ORB
+ ORB orb = ORB.init(args, null);
+ if (!(orb instanceof TestOrbImpl)) {
+ throw new RuntimeException("org.omg.CORBA.ORBClass property not set as expected");
+ }
+ ORB singletonOrb = ORB.init();
+ System.out.println("singletonOrb class == " + singletonOrb.getClass().getName());
+ if (!(singletonOrb instanceof TestSingletonOrbImpl)) {
+ throw new RuntimeException("org.omg.CORBA.ORBSingletonClass property not set as expected");
+ }
+
+ }
+
+ private static void updateOrbPropertiesFile() throws Exception {
+ String orbPropertiesFile = System.getProperty("java.home", ".") + "/conf/orb.properties";
+ String orbClassMapping = "org.omg.CORBA.ORBClass TestOrbImpl";
+ String orbSingletonClassMapping = "org.omg.CORBA.ORBSingletonClass TestSingletonOrbImpl";
+ String orbPropertiesMappings = orbClassMapping + "\n" + orbSingletonClassMapping +"\n";
+ try (PrintWriter hfPWriter = new PrintWriter(new BufferedWriter(
+ new FileWriter(orbPropertiesFile, false)))) {
+ hfPWriter.println(orbPropertiesMappings);
+ } catch (IOException ioEx) {
+ ioEx.printStackTrace();
+ throw ioEx;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/org/omg/CORBA/TestOrbImpl.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.applet.Applet;
+import java.util.Properties;
+
+import org.omg.CORBA.Any;
+import org.omg.CORBA.Context;
+import org.omg.CORBA.ContextList;
+import org.omg.CORBA.Environment;
+import org.omg.CORBA.ExceptionList;
+import org.omg.CORBA.NVList;
+import org.omg.CORBA.NamedValue;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.Object;
+import org.omg.CORBA.Request;
+import org.omg.CORBA.StructMember;
+import org.omg.CORBA.TCKind;
+import org.omg.CORBA.TypeCode;
+import org.omg.CORBA.UnionMember;
+import org.omg.CORBA.WrongTransaction;
+import org.omg.CORBA.ORBPackage.InvalidName;
+import org.omg.CORBA.portable.OutputStream;
+
+
+public class TestOrbImpl extends ORB{
+
+ @Override
+ protected void set_parameters(String[] args, Properties props) {
+
+ }
+
+ @Override
+ protected void set_parameters(Applet app, Properties props) {
+
+ }
+
+ @Override
+ public String[] list_initial_services() {
+ return null;
+ }
+
+ @Override
+ public Object resolve_initial_references(String object_name)
+ throws InvalidName {
+ return null;
+ }
+
+ @Override
+ public String object_to_string(Object obj) {
+ return null;
+ }
+
+ @Override
+ public Object string_to_object(String str) {
+ return null;
+ }
+
+ @Override
+ public NVList create_list(int count) {
+ return null;
+ }
+
+ @Override
+ public NamedValue create_named_value(String s, Any any, int flags) {
+ return null;
+ }
+
+ @Override
+ public ExceptionList create_exception_list() {
+ return null;
+ }
+
+ @Override
+ public ContextList create_context_list() {
+ return null;
+ }
+
+ @Override
+ public Context get_default_context() {
+ return null;
+ }
+
+ @Override
+ public Environment create_environment() {
+ return null;
+ }
+
+ @Override
+ public OutputStream create_output_stream() {
+ return null;
+ }
+
+ @Override
+ public void send_multiple_requests_oneway(Request[] req) {
+
+ }
+
+ @Override
+ public void send_multiple_requests_deferred(Request[] req) {
+
+ }
+
+ @Override
+ public boolean poll_next_response() {
+ return false;
+ }
+
+ @Override
+ public Request get_next_response() throws WrongTransaction {
+ return null;
+ }
+
+ @Override
+ public TypeCode get_primitive_tc(TCKind tcKind) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_struct_tc(String id, String name,
+ StructMember[] members) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_union_tc(String id, String name,
+ TypeCode discriminator_type, UnionMember[] members) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_enum_tc(String id, String name, String[] members) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_alias_tc(String id, String name,
+ TypeCode original_type) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_exception_tc(String id, String name,
+ StructMember[] members) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_interface_tc(String id, String name) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_string_tc(int bound) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_wstring_tc(int bound) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_sequence_tc(int bound, TypeCode element_type) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_recursive_sequence_tc(int bound, int offset) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_array_tc(int length, TypeCode element_type) {
+ return null;
+ }
+
+ @Override
+ public Any create_any() {
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/org/omg/CORBA/TestSingletonOrbImpl.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.applet.Applet;
+import java.util.Properties;
+
+import org.omg.CORBA.Any;
+import org.omg.CORBA.Context;
+import org.omg.CORBA.ContextList;
+import org.omg.CORBA.Environment;
+import org.omg.CORBA.ExceptionList;
+import org.omg.CORBA.NVList;
+import org.omg.CORBA.NamedValue;
+import org.omg.CORBA.ORB;
+import org.omg.CORBA.Object;
+import org.omg.CORBA.Request;
+import org.omg.CORBA.StructMember;
+import org.omg.CORBA.TCKind;
+import org.omg.CORBA.TypeCode;
+import org.omg.CORBA.UnionMember;
+import org.omg.CORBA.WrongTransaction;
+import org.omg.CORBA.ORBPackage.InvalidName;
+import org.omg.CORBA.portable.OutputStream;
+
+
+public class TestSingletonOrbImpl extends ORB {
+
+ @Override
+ protected void set_parameters(String[] args, Properties props) {
+
+ }
+
+ @Override
+ protected void set_parameters(Applet app, Properties props) {
+
+ }
+
+ @Override
+ public String[] list_initial_services() {
+ return null;
+ }
+
+ @Override
+ public Object resolve_initial_references(String object_name)
+ throws InvalidName {
+ return null;
+ }
+
+ @Override
+ public String object_to_string(Object obj) {
+ return null;
+ }
+
+ @Override
+ public Object string_to_object(String str) {
+ return null;
+ }
+
+ @Override
+ public NVList create_list(int count) {
+ return null;
+ }
+
+ @Override
+ public NamedValue create_named_value(String s, Any any, int flags) {
+ return null;
+ }
+
+ @Override
+ public ExceptionList create_exception_list() {
+ return null;
+ }
+
+ @Override
+ public ContextList create_context_list() {
+ return null;
+ }
+
+ @Override
+ public Context get_default_context() {
+ return null;
+ }
+
+ @Override
+ public Environment create_environment() {
+ return null;
+ }
+
+ @Override
+ public OutputStream create_output_stream() {
+ return null;
+ }
+
+ @Override
+ public void send_multiple_requests_oneway(Request[] req) {
+
+ }
+
+ @Override
+ public void send_multiple_requests_deferred(Request[] req) {
+
+ }
+
+ @Override
+ public boolean poll_next_response() {
+ return false;
+ }
+
+ @Override
+ public Request get_next_response() throws WrongTransaction {
+ return null;
+ }
+
+ @Override
+ public TypeCode get_primitive_tc(TCKind tcKind) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_struct_tc(String id, String name,
+ StructMember[] members) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_union_tc(String id, String name,
+ TypeCode discriminator_type, UnionMember[] members) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_enum_tc(String id, String name, String[] members) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_alias_tc(String id, String name,
+ TypeCode original_type) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_exception_tc(String id, String name,
+ StructMember[] members) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_interface_tc(String id, String name) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_string_tc(int bound) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_wstring_tc(int bound) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_sequence_tc(int bound, TypeCode element_type) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_recursive_sequence_tc(int bound, int offset) {
+ return null;
+ }
+
+ @Override
+ public TypeCode create_array_tc(int length, TypeCode element_type) {
+ return null;
+ }
+
+ @Override
+ public Any create_any() {
+ return null;
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/org/omg/CORBA/jtreg.test.policy Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+grant {
+ permission java.util.PropertyPermission "*", "read";
+ permission java.io.FilePermission "<<ALL FILES>>", "read, write, execute";
+};
+
+grant codeBase "file:${test.classes}/*" {
+ permission java.net.SocketPermission "*:*", "connect, accept, listen, resolve";
+ permission java.lang.RuntimePermission "accessClassInPackage.com.sun.jndi.cosnaming";
+};
--- a/jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/sun/management/jdp/JdpJmxRemoteDynamicPortTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -27,7 +27,7 @@
* @summary Verify a non-zero value is assigned to jmxremote.port
* when VM is started with jmxremote.port=0.
* @library /lib/testlibrary
- * @modules java.management/sun.management.jdp
+ * @modules jdk.management.agent/sun.management.jdp
* @build jdk.testlibrary.* ClientConnection JdpTestUtil JdpTestCase JdpJmxRemoteDynamicPortTestCase DynamicLauncher
* @run main JdpJmxRemoteDynamicPortTest
*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ssl/ServerHandshaker/HelloExtensionsTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8173783
+ * @summary 6u141 IllegalArgumentException: jdk.tls.namedGroups
+ * run main/othervm HelloExtensionsTest
+ * run main/othervm HelloExtensionsTest -Djdk.tls.namedGroups="bug, bug"
+ * run main/othervm HelloExtensionsTest -Djdk.tls.namedGroups="secp521r1"
+ *
+ */
+import javax.crypto.*;
+import javax.net.ssl.*;
+import javax.net.ssl.SSLEngineResult.*;
+import java.io.*;
+import java.nio.*;
+import java.security.*;
+
+public class HelloExtensionsTest {
+
+ private static boolean debug = false;
+ private static boolean proceed = true;
+ private static boolean EcAvailable = isEcAvailable();
+
+ static String pathToStores = "../../../../javax/net/ssl/etc";
+ private static String keyStoreFile = "keystore";
+ private static String trustStoreFile = "truststore";
+ private static String passwd = "passphrase";
+
+ private static String keyFilename =
+ System.getProperty("test.src", "./") + "/" + pathToStores +
+ "/" + keyStoreFile;
+ private static String trustFilename =
+ System.getProperty("test.src", "./") + "/" + pathToStores +
+ "/" + trustStoreFile;
+
+ private static void checkDone(SSLEngine ssle) throws Exception {
+ if (!ssle.isInboundDone()) {
+ throw new Exception("isInboundDone isn't done");
+ }
+ if (!ssle.isOutboundDone()) {
+ throw new Exception("isOutboundDone isn't done");
+ }
+ }
+
+ private static void runTest(SSLEngine ssle) throws Exception {
+
+ /*
+
+ A client hello message captured via wireshark by selecting
+ a TLSv1.2 Client Hello record and clicking through to the
+ TLSv1.2 Record Layer line and then selecting the hex stream
+ via "copy -> bytes -> hex stream".
+
+ For Record purposes, here's the ClientHello :
+
+ *** ClientHello, TLSv1.2
+ RandomCookie: GMT: 1469560450 bytes = { 108, 140, 12, 202,
+ 2, 213, 10, 236, 143, 223, 58, 162, 228, 155, 239, 3, 98,
+ 232, 89, 41, 116, 120, 13, 37, 105, 153, 97, 241 }
+ Session ID: {}
+ Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256,
+ TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA256,
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA256,
+ TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_RSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
+ TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
+ TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
+ TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
+ TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256,
+ TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_DSS_WITH_AES_128_GCM_SHA256,
+ TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ SSL_RSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
+ TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
+ SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
+ SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
+ TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
+ Compression Methods: { 0 }
+ Extension elliptic_curves, curve names: {secp256r1,
+ sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1,
+ sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1,
+ sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1,
+ secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1}
+ Extension ec_point_formats, formats: [uncompressed]
+ Extension signature_algorithms, signature_algorithms:
+ SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA,
+ SHA256withECDSA, SHA256withRSA, Unknown (hash:0x3, signature:0x3),
+ Unknown (hash:0x3, signature:0x1), SHA1withECDSA,
+ SHA1withRSA, SHA1withDSA
+ Extension server_name, server_name:
+ [host_name: bugs.openjdk.java.net]
+ */
+
+ String hello = "16030300df010000db03035898b7826c8c0cc" +
+ "a02d50aec8fdf3aa2e49bef0362e8592974780d25699961f" +
+ "100003ac023c027003cc025c02900670040c009c013002fc" +
+ "004c00e00330032c02bc02f009cc02dc031009e00a2c008c" +
+ "012000ac003c00d0016001300ff01000078000a003400320" +
+ "0170001000300130015000600070009000a0018000b000c0" +
+ "019000d000e000f001000110002001200040005001400080" +
+ "016000b00020100000d00180016060306010503050104030" +
+ "401030303010203020102020000001a00180000156275677" +
+ "32e6f70656e6a646b2e6a6176612e6e6574";
+
+ byte[] msg_clihello = hexStringToByteArray(hello);
+ ByteBuffer bf_clihello = ByteBuffer.wrap(msg_clihello);
+
+ SSLSession session = ssle.getSession();
+ int appBufferMax = session.getApplicationBufferSize();
+ int netBufferMax = session.getPacketBufferSize();
+
+ ByteBuffer serverIn = ByteBuffer.allocate(appBufferMax + 50);
+ ByteBuffer serverOut = ByteBuffer.wrap("I'm Server".getBytes());
+ ByteBuffer sTOc = ByteBuffer.allocate(netBufferMax);
+
+ ssle.beginHandshake();
+
+ // unwrap the clientHello message.
+ SSLEngineResult result = ssle.unwrap(bf_clihello, serverIn);
+ System.out.println("server unwrap " + result);
+ runDelegatedTasks(result, ssle);
+
+ if (!proceed) {
+ //expected exception occurred. Don't process anymore
+ return;
+ }
+
+ // one more step, ensure the clientHello message is parsed.
+ SSLEngineResult.HandshakeStatus status = ssle.getHandshakeStatus();
+ if ( status == HandshakeStatus.NEED_UNWRAP) {
+ result = ssle.unwrap(bf_clihello, serverIn);
+ System.out.println("server unwrap " + result);
+ runDelegatedTasks(result, ssle);
+ } else if ( status == HandshakeStatus.NEED_WRAP) {
+ result = ssle.wrap(serverOut, sTOc);
+ System.out.println("server wrap " + result);
+ runDelegatedTasks(result, ssle);
+ } else {
+ throw new Exception("unexpected handshake status " + status);
+ }
+
+ // enough, stop
+ }
+
+ /*
+ * If the result indicates that we have outstanding tasks to do,
+ * go ahead and run them in this thread.
+ */
+ private static void runDelegatedTasks(SSLEngineResult result,
+ SSLEngine engine) throws Exception {
+
+ if (result.getHandshakeStatus() == HandshakeStatus.NEED_TASK) {
+ Runnable runnable;
+ try {
+ while ((runnable = engine.getDelegatedTask()) != null) {
+ log("\trunning delegated task...");
+ runnable.run();
+ }
+ } catch (ExceptionInInitializerError e) {
+ String v = System.getProperty("jdk.tls.namedGroups");
+ if (!EcAvailable || v == null) {
+ // we weren't expecting this if no EC providers
+ throw new RuntimeException("Unexpected Error :" + e);
+ }
+ if (v != null && v.contains("bug")) {
+ // OK - we were expecting this Error
+ log("got expected error for bad jdk.tls.namedGroups");
+ proceed = false;
+ return;
+ } else {
+ System.out.println("Unexpected error. " +
+ "jdk.tls.namedGroups value: " + v);
+ throw e;
+ }
+ }
+ HandshakeStatus hsStatus = engine.getHandshakeStatus();
+ if (hsStatus == HandshakeStatus.NEED_TASK) {
+ throw new Exception(
+ "handshake shouldn't need additional tasks");
+ }
+ log("\tnew HandshakeStatus: " + hsStatus);
+ }
+ }
+
+ private static byte[] hexStringToByteArray(String s) {
+ int len = s.length();
+ byte[] data = new byte[len / 2];
+ for (int i = 0; i < len; i += 2) {
+ data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ + Character.digit(s.charAt(i+1), 16));
+ }
+ return data;
+ }
+
+ private static boolean isEcAvailable() {
+ try {
+ Signature.getInstance("SHA1withECDSA");
+ Signature.getInstance("NONEwithECDSA");
+ KeyAgreement.getInstance("ECDH");
+ KeyFactory.getInstance("EC");
+ KeyPairGenerator.getInstance("EC");
+ AlgorithmParameters.getInstance("EC");
+ } catch (Exception e) {
+ log("EC not available. Received: " + e);
+ return false;
+ }
+ return true;
+ }
+
+ public static void main(String args[]) throws Exception {
+ SSLEngine ssle = createSSLEngine(keyFilename, trustFilename);
+ runTest(ssle);
+ System.out.println("Test Passed.");
+ }
+
+ /*
+ * Create an initialized SSLContext to use for this test.
+ */
+ static private SSLEngine createSSLEngine(String keyFile, String trustFile)
+ throws Exception {
+
+ SSLEngine ssle;
+
+ KeyStore ks = KeyStore.getInstance("JKS");
+ KeyStore ts = KeyStore.getInstance("JKS");
+
+ char[] passphrase = "passphrase".toCharArray();
+
+ ks.load(new FileInputStream(keyFile), passphrase);
+ ts.load(new FileInputStream(trustFile), passphrase);
+
+ KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+ kmf.init(ks, passphrase);
+
+ TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+ tmf.init(ts);
+
+ SSLContext sslCtx = SSLContext.getInstance("TLS");
+
+ sslCtx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
+
+ ssle = sslCtx.createSSLEngine();
+ ssle.setUseClientMode(false);
+
+ return ssle;
+ }
+
+
+ private static void log(String str) {
+ if (debug) {
+ System.out.println(str);
+ }
+ }
+}
--- a/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/sun/security/tools/jarsigner/TimestampCheck.java Wed Jul 05 22:52:22 2017 +0200
@@ -456,7 +456,7 @@
.shouldMatch("Timestamp signature algorithm: .*key.*weak");
verify(file, "-J-Djava.security.debug=jar")
.shouldHaveExitValue(0)
- .shouldMatch("SignatureException:.*Disabled");
+ .shouldMatch("SignatureException:.*disabled");
}
static void checkHalfWeak(String file) throws Throwable {
--- a/jdk/test/sun/text/IntHashtable/Bug4170614Test.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,191 +0,0 @@
-/*
- * 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
- * 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.
- */
-
-/*
- (this test doesn't have an at-test tag because it's run by a shell
- script instead of directly by the test harness)
-*/
-
-/*
- *
- *
- * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
- * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
- *
- * Portions copyright (c) 2007 Sun Microsystems, Inc.
- * All Rights Reserved.
- *
- * The original version of this source code and documentation
- * is copyrighted and owned by Taligent, Inc., a wholly-owned
- * subsidiary of IBM. These materials are provided under terms
- * of a License Agreement between Taligent and Sun. This technology
- * is protected by multiple US and International patents.
- *
- * This notice and attribution to Taligent may not be removed.
- * Taligent is a registered trademark of Taligent, Inc.
- *
- * Permission to use, copy, modify, and distribute this software
- * and its documentation for NON-COMMERCIAL purposes and without
- * fee is hereby granted provided that this copyright notice
- * appears in all copies. Please refer to the file "copyright.html"
- * for further important copyright and licensing information.
- *
- * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
- * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
- * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
- * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
- * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
- * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
- *
- */
-package java.text;
-import sun.text.IntHashtable;
-
-
-/**
- * This class tests some internal hashCode() functions.
- * Bug #4170614 complained that we had two iternal classes that
- * break the invariant that if a.equals(b) than a.hashCode() ==
- * b.hashCode(). This is because these classes overrode equals()
- * but not hashCode(). These are both purely internal classes, and
- * the library itself doesn't actually call hashCode(), so this isn't
- * actually causing anyone problems yet. But if these classes are
- * ever exposed in the API, their hashCode() methods need to work right.
- * PatternEntry will never be exposed in the API, but IntHashtable
- * might be. This is a shell test to allow us to access classes that
- * are declared package private.
- * @author Richard Gillam
- */
-public class Bug4170614Test {
- public static void main(String[] args) throws Exception {
- testIntHashtable();
- testPatternEntry();
- }
-
-
- public static void testIntHashtable() throws Exception {
- IntHashtable fred = new IntHashtable();
- fred.put(1, 10);
- fred.put(2, 20);
- fred.put(3, 30);
-
- IntHashtable barney = new IntHashtable();
- barney.put(1, 10);
- barney.put(3, 30);
- barney.put(2, 20);
-
- IntHashtable homer = new IntHashtable();
- homer.put(3, 30);
- homer.put(1, 10);
- homer.put(7, 900);
-
- if (fred.equals(barney)) {
- System.out.println("fred.equals(barney)");
- }
- else {
- System.out.println("!fred.equals(barney)");
- }
- System.out.println("fred.hashCode() == " + fred.hashCode());
- System.out.println("barney.hashCode() == " + barney.hashCode());
-
- if (!fred.equals(barney)) {
- throw new Exception("equals() failed on two hashtables that are equal");
- }
-
- if (fred.hashCode() != barney.hashCode()) {
- throw new Exception("hashCode() failed on two hashtables that are equal");
- }
-
- System.out.println();
- if (fred.equals(homer)) {
- System.out.println("fred.equals(homer)");
- }
- else {
- System.out.println("!fred.equals(homer)");
- }
- System.out.println("fred.hashCode() == " + fred.hashCode());
- System.out.println("homer.hashCode() == " + homer.hashCode());
-
- if (fred.equals(homer)) {
- throw new Exception("equals() failed on two hashtables that are not equal");
- }
-
- if (fred.hashCode() == homer.hashCode()) {
- throw new Exception("hashCode() failed on two hashtables that are not equal");
- }
-
- System.out.println();
- System.out.println("testIntHashtable() passed.\n");
- }
-
- public static void testPatternEntry() throws Exception {
- PatternEntry fred = new PatternEntry(1,
- new StringBuffer("hello"),
- new StringBuffer("up"));
- PatternEntry barney = new PatternEntry(1,
- new StringBuffer("hello"),
- new StringBuffer("down"));
- // (equals() only considers the "chars" field, so fred and barney are equal)
- PatternEntry homer = new PatternEntry(1,
- new StringBuffer("goodbye"),
- new StringBuffer("up"));
-
- if (fred.equals(barney)) {
- System.out.println("fred.equals(barney)");
- }
- else {
- System.out.println("!fred.equals(barney)");
- }
- System.out.println("fred.hashCode() == " + fred.hashCode());
- System.out.println("barney.hashCode() == " + barney.hashCode());
-
- if (!fred.equals(barney)) {
- throw new Exception("equals() failed on two hashtables that are equal");
- }
-
- if (fred.hashCode() != barney.hashCode()) {
- throw new Exception("hashCode() failed on two hashtables that are equal");
- }
-
- System.out.println();
- if (fred.equals(homer)) {
- System.out.println("fred.equals(homer)");
- }
- else {
- System.out.println("!fred.equals(homer)");
- }
- System.out.println("fred.hashCode() == " + fred.hashCode());
- System.out.println("homer.hashCode() == " + homer.hashCode());
-
- if (fred.equals(homer)) {
- throw new Exception("equals() failed on two hashtables that are not equal");
- }
-
- if (fred.hashCode() == homer.hashCode()) {
- throw new Exception("hashCode() failed on two hashtables that are not equal");
- }
-
- System.out.println();
- System.out.println("testPatternEntry() passed.\n");
- }
-}
--- a/jdk/test/sun/text/IntHashtable/Bug4170614Test.sh Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/sun/text/IntHashtable/Bug4170614Test.sh Wed Jul 05 22:52:22 2017 +0200
@@ -60,8 +60,8 @@
TEST_JAVABASE=${TESTCLASSES}/java.base
mkdir -p ${TEST_JAVABASE}
${COMPILEJAVA}/bin/javac ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} \
- -Xmodule:java.base \
- -d ${TEST_JAVABASE} Bug4170614Test.java
+ --patch-module java.base=patch-src \
+ -d ${TEST_JAVABASE} patch-src/java/text/Bug4170614Test.java
${TESTJAVA}/bin/java ${TESTVMOPTS} --patch-module java.base=${TEST_JAVABASE} java.text.Bug4170614Test
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/text/IntHashtable/patch-src/java/text/Bug4170614Test.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,191 @@
+/*
+ * 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
+ * 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.
+ */
+
+/*
+ (this test doesn't have an at-test tag because it's run by a shell
+ script instead of directly by the test harness)
+*/
+
+/*
+ *
+ *
+ * (C) Copyright Taligent, Inc. 1996, 1997 - All Rights Reserved
+ * (C) Copyright IBM Corp. 1996 - 1998 - All Rights Reserved
+ *
+ * Portions copyright (c) 2007 Sun Microsystems, Inc.
+ * All Rights Reserved.
+ *
+ * The original version of this source code and documentation
+ * is copyrighted and owned by Taligent, Inc., a wholly-owned
+ * subsidiary of IBM. These materials are provided under terms
+ * of a License Agreement between Taligent and Sun. This technology
+ * is protected by multiple US and International patents.
+ *
+ * This notice and attribution to Taligent may not be removed.
+ * Taligent is a registered trademark of Taligent, Inc.
+ *
+ * Permission to use, copy, modify, and distribute this software
+ * and its documentation for NON-COMMERCIAL purposes and without
+ * fee is hereby granted provided that this copyright notice
+ * appears in all copies. Please refer to the file "copyright.html"
+ * for further important copyright and licensing information.
+ *
+ * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
+ * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+ * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+ * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
+ * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
+ * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
+ *
+ */
+package java.text;
+import sun.text.IntHashtable;
+
+
+/**
+ * This class tests some internal hashCode() functions.
+ * Bug #4170614 complained that we had two iternal classes that
+ * break the invariant that if a.equals(b) than a.hashCode() ==
+ * b.hashCode(). This is because these classes overrode equals()
+ * but not hashCode(). These are both purely internal classes, and
+ * the library itself doesn't actually call hashCode(), so this isn't
+ * actually causing anyone problems yet. But if these classes are
+ * ever exposed in the API, their hashCode() methods need to work right.
+ * PatternEntry will never be exposed in the API, but IntHashtable
+ * might be. This is a shell test to allow us to access classes that
+ * are declared package private.
+ * @author Richard Gillam
+ */
+public class Bug4170614Test {
+ public static void main(String[] args) throws Exception {
+ testIntHashtable();
+ testPatternEntry();
+ }
+
+
+ public static void testIntHashtable() throws Exception {
+ IntHashtable fred = new IntHashtable();
+ fred.put(1, 10);
+ fred.put(2, 20);
+ fred.put(3, 30);
+
+ IntHashtable barney = new IntHashtable();
+ barney.put(1, 10);
+ barney.put(3, 30);
+ barney.put(2, 20);
+
+ IntHashtable homer = new IntHashtable();
+ homer.put(3, 30);
+ homer.put(1, 10);
+ homer.put(7, 900);
+
+ if (fred.equals(barney)) {
+ System.out.println("fred.equals(barney)");
+ }
+ else {
+ System.out.println("!fred.equals(barney)");
+ }
+ System.out.println("fred.hashCode() == " + fred.hashCode());
+ System.out.println("barney.hashCode() == " + barney.hashCode());
+
+ if (!fred.equals(barney)) {
+ throw new Exception("equals() failed on two hashtables that are equal");
+ }
+
+ if (fred.hashCode() != barney.hashCode()) {
+ throw new Exception("hashCode() failed on two hashtables that are equal");
+ }
+
+ System.out.println();
+ if (fred.equals(homer)) {
+ System.out.println("fred.equals(homer)");
+ }
+ else {
+ System.out.println("!fred.equals(homer)");
+ }
+ System.out.println("fred.hashCode() == " + fred.hashCode());
+ System.out.println("homer.hashCode() == " + homer.hashCode());
+
+ if (fred.equals(homer)) {
+ throw new Exception("equals() failed on two hashtables that are not equal");
+ }
+
+ if (fred.hashCode() == homer.hashCode()) {
+ throw new Exception("hashCode() failed on two hashtables that are not equal");
+ }
+
+ System.out.println();
+ System.out.println("testIntHashtable() passed.\n");
+ }
+
+ public static void testPatternEntry() throws Exception {
+ PatternEntry fred = new PatternEntry(1,
+ new StringBuffer("hello"),
+ new StringBuffer("up"));
+ PatternEntry barney = new PatternEntry(1,
+ new StringBuffer("hello"),
+ new StringBuffer("down"));
+ // (equals() only considers the "chars" field, so fred and barney are equal)
+ PatternEntry homer = new PatternEntry(1,
+ new StringBuffer("goodbye"),
+ new StringBuffer("up"));
+
+ if (fred.equals(barney)) {
+ System.out.println("fred.equals(barney)");
+ }
+ else {
+ System.out.println("!fred.equals(barney)");
+ }
+ System.out.println("fred.hashCode() == " + fred.hashCode());
+ System.out.println("barney.hashCode() == " + barney.hashCode());
+
+ if (!fred.equals(barney)) {
+ throw new Exception("equals() failed on two hashtables that are equal");
+ }
+
+ if (fred.hashCode() != barney.hashCode()) {
+ throw new Exception("hashCode() failed on two hashtables that are equal");
+ }
+
+ System.out.println();
+ if (fred.equals(homer)) {
+ System.out.println("fred.equals(homer)");
+ }
+ else {
+ System.out.println("!fred.equals(homer)");
+ }
+ System.out.println("fred.hashCode() == " + fred.hashCode());
+ System.out.println("homer.hashCode() == " + homer.hashCode());
+
+ if (fred.equals(homer)) {
+ throw new Exception("equals() failed on two hashtables that are not equal");
+ }
+
+ if (fred.hashCode() == homer.hashCode()) {
+ throw new Exception("hashCode() failed on two hashtables that are not equal");
+ }
+
+ System.out.println();
+ System.out.println("testPatternEntry() passed.\n");
+ }
+}
--- a/jdk/test/tools/jar/mmrjar/Basic.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/jar/mmrjar/Basic.java Wed Jul 05 22:52:22 2017 +0200
@@ -268,7 +268,7 @@
actual = lines(outbytes);
expected = Set.of(
- "hi",
+ "module hi (module-info.class)",
"requires mandated java.base",
"contains p",
"contains p.internal"
@@ -304,7 +304,7 @@
actual = lines(outbytes);
expected = Set.of(
- "hi",
+ "module hi (module-info.class)",
"requires mandated java.base",
"contains p",
"contains p.internal",
@@ -331,7 +331,7 @@
ModuleInfoExtender mie = ModuleInfoExtender.newExtender(
new ByteArrayInputStream(mdBytes));
- mie.mainClass("foo.main");
+ mie.mainClass("p.Main");
mie.version(Version.parse("1.0"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
@@ -345,7 +345,7 @@
// different main-class
mie = ModuleInfoExtender.newExtender(new ByteArrayInputStream(mdBytes));
- mie.mainClass("foo.main2");
+ mie.mainClass("p.Main2");
mie.version(Version.parse("1.0"));
baos.reset();
mie.write(baos);
@@ -360,7 +360,7 @@
// different version
mie = ModuleInfoExtender.newExtender(new ByteArrayInputStream(mdBytes));
- mie.mainClass("foo.main");
+ mie.mainClass("p.Main");
mie.version(Version.parse("2.0"));
baos.reset();
mie.write(baos);
@@ -395,21 +395,21 @@
Files.copy(Paths.get("test7-v9", "module-info.class"),
Paths.get("test7-v10", "module-info.class"));
- int rc = jar("--create --file mmr.jar --main-class=foo.main -C test7 . --release 9 -C test7-v9 . --release 10 -C test7-v10 .");
-
-System.out.println("-----------------------");
-System.out.println( new String(errbytes.toByteArray()));
-
-
+ int rc = jar("--create --file mmr.jar --main-class=p.Main -C test7 . --release 9 -C test7-v9 . --release 10 -C test7-v10 .");
Assert.assertEquals(rc, 0);
-
- jar("-tf mmr.jar");
+ jar("-d --file=mmr.jar");
+ System.out.println("-----------------------");
+ System.out.println( new String(outbytes.toByteArray()));
+ Assert.assertEquals(lines(outbytes),
+ Set.of(
+ "module m1 (META-INF/versions/9/module-info.class)",
+ "module m1 (META-INF/versions/10/module-info.class)",
+ "requires mandated java.base",
+ "exports p",
+ "main-class p.Main"));
-System.out.println("-----------------------");
-System.out.println( new String(outbytes.toByteArray()));
-
- Optional<String> exp = Optional.of("foo.main");
+ Optional<String> exp = Optional.of("p.Main");
try (ZipFile zf = new ZipFile("mmr.jar")) {
Assert.assertTrue(zf.getEntry("module-info.class") == null);
--- a/jdk/test/tools/jar/modularJar/Basic.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/jar/modularJar/Basic.java Wed Jul 05 22:52:22 2017 +0200
@@ -46,7 +46,7 @@
/*
* @test
- * @bug 8167328 8171830
+ * @bug 8167328 8171830 8165640
* @library /lib/testlibrary
* @modules jdk.compiler
* jdk.jartool
@@ -241,11 +241,6 @@
java(mp, FOO.moduleName + "/" + FOO.mainClass)
.assertSuccess()
-.resultChecker(r -> {
- System.out.println("===================================");
- System.out.println(r.output);
- System.out.println("===================================");
-})
.resultChecker(r -> assertModuleData(r, FOO));
try (InputStream fis = Files.newInputStream(modularJar);
JarInputStream jis = new JarInputStream(fis)) {
@@ -328,7 +323,7 @@
.resultChecker(r -> assertModuleData(r, FOO));
}
- @Test
+ @Test(enabled = false)
public void partialUpdateFooMainClass() throws IOException {
Path mp = Paths.get("partialUpdateFooMainClass");
createTestDir(mp);
@@ -484,7 +479,7 @@
.resultChecker(r -> {
// Expect similar output: "bar, requires mandated foo, ...
// conceals jdk.test.foo, conceals jdk.test.foo.internal"
- Pattern p = Pattern.compile("\\s+bar\\s+requires\\s++foo");
+ Pattern p = Pattern.compile("module bar \\(module-info.class\\)\\s+requires\\s++foo");
assertTrue(p.matcher(r.output).find(),
"Expecting to find \"bar, requires foo,...\"",
"in output, but did not: [" + r.output + "]");
@@ -740,6 +735,53 @@
}
@Test
+ public void servicesCreateWithoutFailureNonRootMRMJAR() throws IOException {
+ // without a root module-info.class
+ Path mp = Paths.get("servicesCreateWithoutFailureNonRootMRMJAR");
+ createTestDir(mp);
+ Path modClasses = MODULE_CLASSES.resolve("baz");
+ Path mrjarDir = MRJAR_DIR.resolve("baz");
+ Path modularJar = mp.resolve("baz.jar");
+
+ jar("--create",
+ "--file=" + modularJar.toString(),
+ "--main-class=" + "jdk.test.baz.Baz",
+ "-m", mrjarDir.resolve("META-INF/MANIFEST.MF").toRealPath().toString(),
+ "-C", mrjarDir.toString(), "META-INF/versions/9/module-info.class",
+ "-C", modClasses.toString(), "jdk/test/baz/BazService.class",
+ "-C", modClasses.toString(), "jdk/test/baz/Baz.class",
+ "-C", modClasses.toString(), "jdk/test/baz/internal/BazServiceImpl.class")
+ .assertSuccess();
+
+
+ for (String option : new String[] {"--print-module-descriptor", "-d" }) {
+
+ jar(option,
+ "--file=" + modularJar.toString())
+ .assertSuccess()
+ .resultChecker(r ->
+ assertTrue(r.output.contains("main-class jdk.test.baz.Baz"),
+ "Expected to find ", "main-class jdk.test.baz.Baz",
+ " in [", r.output, "]"));
+
+ jarWithStdin(modularJar.toFile(), option)
+ .assertSuccess()
+ .resultChecker(r ->
+ assertTrue(r.output.contains("main-class jdk.test.baz.Baz"),
+ "Expected to find ", "main-class jdk.test.baz.Baz",
+ " in [", r.output, "]"));
+
+ }
+ // run module maain class
+ java(mp, "baz/jdk.test.baz.Baz")
+ .assertSuccess()
+ .resultChecker(r ->
+ assertTrue(r.output.contains("mainClass:jdk.test.baz.Baz"),
+ "Expected to find ", "mainClass:jdk.test.baz.Baz",
+ " in [", r.output, "]"));
+ }
+
+ @Test
public void exportCreateWithMissingPkg() throws IOException {
Path foobar = TEST_SRC.resolve("src").resolve("foobar");
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jar/modularJar/src/baz/jdk/test/baz/Baz.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.test.baz;
+
+import java.lang.module.ModuleDescriptor;
+
+public class Baz {
+ public static void main(String[] args) {
+ ModuleDescriptor md = Baz.class.getModule().getDescriptor();
+ System.out.println("nameAndVersion:" + md.toNameAndVersion());
+ md.mainClass().ifPresent(mc -> System.out.println("mainClass:" + mc));
+ }
+}
--- a/jdk/test/tools/jlink/JLinkNegativeTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/jlink/JLinkNegativeTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -250,7 +250,7 @@
String moduleName = "hacked4";
Path jmod = helper.generateDefaultJModule(moduleName).assertSuccess();
JImageGenerator.addFiles(jmod,
- new InMemoryFile("/native", new byte[0]),
+ new InMemoryFile("/lib", new byte[0]),
new InMemoryFile("/conf", new byte[0]),
new InMemoryFile("/bin", new byte[0]));
try {
@@ -274,7 +274,7 @@
helper.getJmodSrcDir(), helper.getJmodClassesDir(), moduleName2, classNames);
try (OutputStream out = Files.newOutputStream(module2.resolve("module-info.class"))) {
- ModuleInfoWriter.write(ModuleDescriptor.module(moduleName1)
+ ModuleInfoWriter.write(ModuleDescriptor.newModule(moduleName1)
.requires("java.base").build(), out);
}
@@ -332,7 +332,7 @@
helper.getJarSrcDir(), helper.getJarClassesDir(), moduleName2, classNames);
try (OutputStream out = Files.newOutputStream(module2.resolve("module-info.class"))) {
- ModuleInfoWriter.write(ModuleDescriptor.module(moduleName1)
+ ModuleInfoWriter.write(ModuleDescriptor.newModule(moduleName1)
.requires("java.base").build(), out);
}
--- a/jdk/test/tools/jlink/plugins/ExcludeVMPluginTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/jlink/plugins/ExcludeVMPluginTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -155,10 +155,10 @@
String[] winput = new String[input.length];
String[] woutput = new String[expectedOutput.length];
for (int i = 0; i < input.length; i++) {
- winput[i] = "/java.base/native" + arch + input[i];
+ winput[i] = "/java.base/lib" + arch + input[i];
}
for (int i = 0; i < expectedOutput.length; i++) {
- woutput[i] = "/java.base/native" + arch + expectedOutput[i];
+ woutput[i] = "/java.base/lib" + arch + expectedOutput[i];
}
doCheckVM(vm, winput, jvmcfg, woutput, expectdJvmCfg);
}
@@ -169,7 +169,7 @@
byte[] jvmcfgContent = jvmcfg.getBytes();
ResourcePoolManager poolMgr = new ResourcePoolManager();
poolMgr.add(
- ResourcePoolEntry.create("/java.base/native/jvm.cfg",
+ ResourcePoolEntry.create("/java.base/lib/jvm.cfg",
ResourcePoolEntry.Type.NATIVE_LIB, jvmcfgContent));
// java.base/module-info.class is used by exclude vm plugin
@@ -192,7 +192,7 @@
p.configure(config);
ResourcePool out = p.transform(poolMgr.resourcePool(), outMgr.resourcePoolBuilder());
- String newContent = new String(out.findEntry("/java.base/native/jvm.cfg").get().contentBytes());
+ String newContent = new String(out.findEntry("/java.base/lib/jvm.cfg").get().contentBytes());
if (!expectdJvmCfg.equals(newContent)) {
throw new Exception("Got content " + newContent + " expected " + expectdJvmCfg);
@@ -209,7 +209,7 @@
}
out.entries().forEach(md -> {
- if (md.path().equals("/java.base/native/jvm.cfg") ||
+ if (md.path().equals("/java.base/lib/jvm.cfg") ||
md.path().equals("/java.base/module-info.class")) {
return;
}
--- a/jdk/test/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/jlink/plugins/SystemModuleDescriptors/UserModuleTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -45,7 +45,7 @@
/**
* @test
- * @bug 8142968 8173381
+ * @bug 8142968 8173381 8174740
* @library /lib/testlibrary
* @modules jdk.compiler jdk.jlink
* @build UserModuleTest CompilerUtils jdk.testlibrary.FileUtils jdk.testlibrary.ProcessTools
--- a/jdk/test/tools/jlink/plugins/SystemModuleDescriptors/src/m1/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/jlink/plugins/SystemModuleDescriptors/src/m1/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,5 +21,9 @@
* questions.
*/
+/*
+ * m1 has an exported package and also internal package
+ */
module m1 {
+ exports p1;
}
--- a/jdk/test/tools/jmod/JmodTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/jmod/JmodTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -66,7 +66,7 @@
static final String CLASSES_PREFIX = "classes/";
static final String CMDS_PREFIX = "bin/";
- static final String LIBS_PREFIX = "native/";
+ static final String LIBS_PREFIX = "lib/";
static final String CONFIGS_PREFIX = "conf/";
@BeforeTest
--- a/jdk/test/tools/jmod/hashes/HashesTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/jmod/hashes/HashesTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -312,9 +312,7 @@
assertTrue(ht.hashes("m2") == null);
// should not override any JDK packaged modules
- ModuleFinder finder = new ModulePath(Runtime.version(),
- true,
- mpath);
+ ModuleFinder finder = ModulePath.of(Runtime.version(), true, mpath);
assertTrue(ht.hashes(finder,"jdk.compiler") == null);
assertTrue(ht.hashes(finder,"jdk.attach") == null);
}
@@ -325,9 +323,7 @@
}
private ModuleHashes hashes(String name) {
- ModuleFinder finder = new ModulePath(Runtime.version(),
- true,
- lib);
+ ModuleFinder finder = ModulePath.of(Runtime.version(), true, lib);
return hashes(finder, name);
}
--- a/jdk/test/tools/launcher/ArgsEnvVar.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/launcher/ArgsEnvVar.java Wed Jul 05 22:52:22 2017 +0200
@@ -40,7 +40,7 @@
private static File testJar = null;
private static Map<String, String> env = new HashMap<>();
- private static String JAVA_OPTIONS = "JAVA_OPTIONS";
+ private static String JDK_JAVA_OPTIONS = "JDK_JAVA_OPTIONS";
static void init() throws IOException {
if (testJar != null) {
@@ -105,7 +105,7 @@
File argFile2 = createArgFile("argFile2", List.of("-Darg.file2=TWO"));
File argFile3 = createArgFile("argFile3", List.of("-Darg.file3=THREE"));
- env.put(JAVA_OPTIONS, "@argFile1\n-Xint\r-cp @@escaped\t@argFile2");
+ env.put(JDK_JAVA_OPTIONS, "@argFile1\n-Xint\r-cp @@escaped\t@argFile2");
TestResult tr = doExec(env, javaCmd, "@argFile3", "-cp", "test.jar", "Foo", "uarg1", "@uarg2");
@@ -133,13 +133,13 @@
}
private TestResult testInEnv(List<String> options) {
- env.put(JAVA_OPTIONS, String.join(" ", options));
+ env.put(JDK_JAVA_OPTIONS, String.join(" ", options));
return doExec(env, javaCmd, "-jar", "test.jar");
}
private TestResult testInEnvAsArgFile(List<String> options) throws IOException {
File argFile = createArgFile("argFile", options);
- env.put(JAVA_OPTIONS, "@argFile");
+ env.put(JDK_JAVA_OPTIONS, "@argFile");
TestResult tr = doExec(env, javaCmd, "-jar", "test.jar");
argFile.delete();
return tr;
@@ -187,7 +187,7 @@
File argFile1 = createArgFile("arg File 1", List.of("-Xint"));
File argFile2 = createArgFile("arg File 2", List.of("-Dprop='value with spaces'"));
File argFile3 = createArgFile("arg File 3", List.of("-Xmx32m"));
- env.put(JAVA_OPTIONS, "'@arg File 1' @\"arg File 2\" @'arg File'\" 3\"");
+ env.put(JDK_JAVA_OPTIONS, "'@arg File 1' @\"arg File 2\" @'arg File'\" 3\"");
TestResult tr = doExec(env, javaCmd, "-jar", "test.jar");
List<String> options = new ArrayList<>();
@@ -204,7 +204,7 @@
@Test
public void openQuoteShouldFail() {
- env.put(JAVA_OPTIONS, "-Dprop='value missing close quote");
+ env.put(JDK_JAVA_OPTIONS, "-Dprop='value missing close quote");
TestResult tr = doExec(env, javaCmd, "-version");
tr.checkNegative();
if (!tr.testStatus) {
@@ -215,11 +215,11 @@
@Test
public void noWildcard() {
- env.put(JAVA_OPTIONS, "-cp *");
+ env.put(JDK_JAVA_OPTIONS, "-cp *");
TestResult tr = doExec(env, javaCmd, "-jar", "test.jar");
verifyOptions(List.of("-cp", "*", "-jar", "test.jar"), tr);
- env.put(JAVA_OPTIONS, "-p ?");
+ env.put(JDK_JAVA_OPTIONS, "-p ?");
tr = doExec(env, javaCmd, "-jar", "test.jar", "one", "two");
verifyOptions(List.of("-p", "?", "-jar", "test.jar", "one", "two"), tr);
}
--- a/jdk/test/tools/launcher/I18NArgTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/launcher/I18NArgTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -95,21 +95,19 @@
throw new RuntimeException("test fails");
}
- // Test via JAVA_OPTIONS
-/*
+ // Test via JDK_JAVA_OPTIONS
Map<String, String> env = new HashMap<>();
String cmd = "-Dtest.src=" + TEST_SOURCES_DIR.getAbsolutePath() +
" -Dtest.classes=" + TEST_CLASSES_DIR.getAbsolutePath() +
" -cp " + TEST_CLASSES_DIR.getAbsolutePath() +
" I18NArgTest " + unicodeStr + " " + hexValue;
- env.put("JAVA_OPTIONS", cmd);
+ env.put("JDK_JAVA_OPTIONS", cmd);
tr = doExec(env, javaCmd);
System.out.println(tr.testOutput);
if (!tr.isOK()) {
System.err.println(tr);
throw new RuntimeException("test fails");
}
-*/
}
static void testCharacters(String... args) {
--- a/jdk/test/tools/launcher/ToolsOpts.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/launcher/ToolsOpts.java Wed Jul 05 22:52:22 2017 +0200
@@ -87,11 +87,16 @@
contents.add(" }\n");
contents.add(" }\n");
contents.add("}\n");
- createFile(new File(mainJava), contents);
+ String mainJavaPath = "patch-src/com/sun/tools/javac/" + mainJava;
+ File mainJavaFile = new File(mainJavaPath.replace('/', File.separatorChar));
+ mainJavaFile.getParentFile().mkdirs();
+ createFile(mainJavaFile, contents);
// compile Main.java into directory to override classes in jdk.compiler
new File("jdk.compiler").mkdir();
- compile("-Xmodule:jdk.compiler", "-d", "jdk.compiler", mainJava);
+ compile("--patch-module", "jdk.compiler=patch-src",
+ "-d", "jdk.compiler",
+ mainJavaFile.toString());
}
static void pass(String msg) {
--- a/jdk/test/tools/launcher/modules/patch/basic/PatchTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/launcher/modules/patch/basic/PatchTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -105,22 +105,24 @@
MODS_DIR.resolve("test"));
assertTrue(compiled, "classes did not compile");
- // javac -Xmodule:$MODULE -d patches1/$MODULE patches1/$MODULE/**
+ // javac --patch-module $MODULE=patches1/$MODULE -d patches1/$MODULE patches1/$MODULE/**
// jar cf patches/$MODULE-1.jar -C patches1/$MODULE .
for (Path src : Files.newDirectoryStream(SRC1_DIR)) {
Path output = PATCHES1_DIR.resolve(src.getFileName());
String mn = src.getFileName().toString();
- compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn);
+ compiled = CompilerUtils.compile(src, output,
+ "--patch-module", mn + "=" + src.toString());
assertTrue(compiled, "classes did not compile");
JarUtils.createJarFile(PATCHES_DIR.resolve(mn + "-1.jar"), output);
}
- // javac -Xmodule:$MODULE -d patches2/$MODULE patches2/$MODULE/**
+ // javac --patch-module $MODULE=patches2/$MODULE -d patches2/$MODULE patches2/$MODULE/**
// jar cf patches/$MODULE-2.jar -C patches2/$MODULE .
for (Path src : Files.newDirectoryStream(SRC2_DIR)) {
Path output = PATCHES2_DIR.resolve(src.getFileName());
String mn = src.getFileName().toString();
- compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn);
+ compiled = CompilerUtils.compile(src, output,
+ "--patch-module", mn + "=" + src.toString());
assertTrue(compiled, "classes did not compile");
JarUtils.createJarFile(PATCHES_DIR.resolve(mn + "-2.jar"), output);
}
--- a/jdk/test/tools/launcher/modules/patch/basic/PatchTestWarningError.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/launcher/modules/patch/basic/PatchTestWarningError.java Wed Jul 05 22:52:22 2017 +0200
@@ -93,20 +93,22 @@
MODS_DIR.resolve("test"));
assertTrue(compiled, "classes did not compile");
- // javac -Xmodule:$MODULE -d patches1/$MODULE patches1/$MODULE/**
+ // javac --patch-module $MODULE=patches1/$MODULE -d patches1/$MODULE patches1/$MODULE/**
Path src = SRC1_DIR.resolve("java.base");
Path output = PATCHES1_DIR.resolve(src.getFileName());
Files.createDirectories(output);
String mn = src.getFileName().toString();
- compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn);
+ compiled = CompilerUtils.compile(src, output,
+ "--patch-module", mn + "=" + src.toString());
assertTrue(compiled, "classes did not compile");
- // javac -Xmodule:$MODULE -d patches2/$MODULE patches2/$MODULE/**
+ // javac --patch-module $MODULE=patches2/$MODULE -d patches2/$MODULE patches2/$MODULE/**
src = SRC2_DIR.resolve("java.base");
output = PATCHES2_DIR.resolve(src.getFileName());
Files.createDirectories(output);
mn = src.getFileName().toString();
- compiled = CompilerUtils.compile(src, output, "-Xmodule:" + mn);
+ compiled = CompilerUtils.compile(src, output,
+ "--patch-module", mn + "=" + src.toString());
assertTrue(compiled, "classes did not compile");
}
--- a/jdk/test/tools/launcher/modules/patch/systemmodules/PatchSystemModules.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/launcher/modules/patch/systemmodules/PatchSystemModules.java Wed Jul 05 22:52:22 2017 +0200
@@ -73,9 +73,10 @@
}
// compile patched source
+ String patchDir = PATCH_SRC_DIR.resolve(JAVA_BASE).toString();
assertTrue(CompilerUtils.compile(PATCH_SRC_DIR.resolve(JAVA_BASE),
PATCH_DIR.resolve(JAVA_BASE),
- "-Xmodule:java.base"));
+ "--patch-module", "java.base=" + patchDir));
assertTrue(CompilerUtils.compile(PATCH_SRC_DIR.resolve("m2"),
PATCH_DIR.resolve("m2")));
--- a/jdk/test/tools/launcher/modules/patch/systemmodules/src1/java.base/jdk/internal/modules/SystemModules.java Thu Feb 16 17:12:58 2017 +0000
+++ b/jdk/test/tools/launcher/modules/patch/systemmodules/src1/java.base/jdk/internal/modules/SystemModules.java Wed Jul 05 22:52:22 2017 +0200
@@ -30,6 +30,8 @@
public final class SystemModules {
public static final String[] MODULE_NAMES = new String[0];
+ public static int PACKAGES_IN_BOOT_LAYER = 1024;
+
public static boolean hasSplitPackages() {
return true;
}
--- a/langtools/.hgtags Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/.hgtags Wed Jul 05 22:52:22 2017 +0200
@@ -398,3 +398,4 @@
03f48cd283f5dd6b7153fd7e0cf2df8582b14391 jdk-9+153
6a9dd3d893b0a493a3e5d8d392815b5ee76a02d9 jdk-9+154
dfcfdb2db85f1bb434209f56ca557ea6f9830aa8 jdk-9+155
+6f91e41163bc09e9b3ec72e8d1185f39296ee5d4 jdk-9+156
--- a/langtools/make/tools/crules/MutableFieldsAnalyzer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/make/tools/crules/MutableFieldsAnalyzer.java Wed Jul 05 22:52:22 2017 +0200
@@ -102,7 +102,7 @@
ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$ModuleFinder",
"moduleFinderClass", "ofMethod");
ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$Configuration",
- "configurationClass", "resolveRequiresAndUsesMethod");
+ "configurationClass", "resolveAndBindMethod");
ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$Layer",
"layerClass", "bootMethod", "defineModulesWithOneLoaderMethod", "configurationMethod");
ignoreFields("com.sun.tools.javac.util.JDK9Wrappers$Module",
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/Element.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/Element.java Wed Jul 05 22:52:22 2017 +0200
@@ -123,6 +123,8 @@
* @see TypeElement#getSimpleName
* @see VariableElement#getSimpleName
* @see ModuleElement#getSimpleName
+ * @revised 9
+ * @spec JPMS
*/
Name getSimpleName();
@@ -158,6 +160,8 @@
*
* @return the enclosing element, or {@code null} if there is none
* @see Elements#getPackageOf
+ * @revised 9
+ * @spec JPMS
*/
Element getEnclosingElement();
@@ -193,6 +197,8 @@
* @see Elements#getAllMembers
* @jls 8.8.9 Default Constructor
* @jls 8.9 Enums
+ * @revised 9
+ * @spec JPMS
*/
List<? extends Element> getEnclosedElements();
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementKind.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementKind.java Wed Jul 05 22:52:22 2017 +0200
@@ -99,6 +99,7 @@
/**
* A module.
* @since 9
+ * @spec JPMS
*/
MODULE;
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementVisitor.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/ElementVisitor.java Wed Jul 05 22:52:22 2017 +0200
@@ -159,6 +159,7 @@
* @param p a visitor-specified parameter
* @return a visitor-specified result
* @since 9
+ * @spec JPMS
*/
default R visitModule(ModuleElement e, P p) {
return visitUnknown(e, p);
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/ModuleElement.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/ModuleElement.java Wed Jul 05 22:52:22 2017 +0200
@@ -33,6 +33,7 @@
*
* @see javax.lang.model.util.Elements#getModuleOf
* @since 9
+ * @spec JPMS
*/ // TODO: add @jls to module section
public interface ModuleElement extends Element, QualifiedNameable {
@@ -104,6 +105,7 @@
* future versions of the Java™ programming language.
*
* @since 9
+ * @spec JPMS
*/
enum DirectiveKind {
/** A "requires (static|transitive)* module-name" directive. */
@@ -122,6 +124,7 @@
* Represents a "module statement" within the declaration of this module.
*
* @since 9
+ * @spec JPMS
*
*/ // TODO: add jls to Module Statement
interface Directive {
@@ -136,6 +139,7 @@
/**
* A dependency of a module.
* @since 9
+ * @spec JPMS
*/
interface RequiresDirective extends Directive {
/**
@@ -160,6 +164,7 @@
/**
* An exported package of a module.
* @since 9
+ * @spec JPMS
*/
interface ExportsDirective extends Directive {
@@ -181,6 +186,7 @@
/**
* An opened package of a module.
* @since 9
+ * @spec JPMS
*/
interface OpensDirective extends Directive {
@@ -202,6 +208,7 @@
/**
* An implementation of a service provided by a module.
* @since 9
+ * @spec JPMS
*/
interface ProvidesDirective extends Directive {
/**
@@ -220,6 +227,7 @@
/**
* A reference to a service used by a module.
* @since 9
+ * @spec JPMS
*/
interface UsesDirective extends Directive {
/**
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/element/PackageElement.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/element/PackageElement.java Wed Jul 05 22:52:22 2017 +0200
@@ -93,6 +93,9 @@
* source version} without modules.
*
* @return the enclosing module or {@code null} if no such module exists
+ *
+ * @revised 9
+ * @spec JPMS
*/
@Override
Element getEnclosingElement();
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeKind.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/type/TypeKind.java Wed Jul 05 22:52:22 2017 +0200
@@ -157,6 +157,7 @@
* A pseudo-type corresponding to a module element.
* @see NoType
* @since 9
+ * @spec JPMS
*/
MODULE;
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor6.java Wed Jul 05 22:52:22 2017 +0200
@@ -136,6 +136,7 @@
* @return the result of {@code visitUnknown}
*
* @since 9
+ * @spec JPMS
*/
@Override
public R visitModule(ModuleElement e, P p) {
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor9.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/AbstractElementVisitor9.java Wed Jul 05 22:52:22 2017 +0200
@@ -63,6 +63,7 @@
* @see AbstractElementVisitor7
* @see AbstractElementVisitor8
* @since 9
+ * @spec JPMS
*/
@SupportedSourceVersion(RELEASE_9)
public abstract class AbstractElementVisitor9<R, P> extends AbstractElementVisitor8<R, P> {
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementFilter.java Wed Jul 05 22:52:22 2017 +0200
@@ -189,6 +189,7 @@
* @return a list of modules in {@code elements}
* @param elements the elements to filter
* @since 9
+ * @spec JPMS
*/
public static List<ModuleElement>
modulesIn(Iterable<? extends Element> elements) {
@@ -200,6 +201,7 @@
* @return a set of modules in {@code elements}
* @param elements the elements to filter
* @since 9
+ * @spec JPMS
*/
public static Set<ModuleElement>
modulesIn(Set<? extends Element> elements) {
@@ -236,6 +238,7 @@
* @return a list of {@code exports} directives in {@code directives}
* @param directives the directives to filter
* @since 9
+ * @spec JPMS
*/
public static List<ExportsDirective>
exportsIn(Iterable<? extends Directive> directives) {
@@ -258,6 +261,7 @@
* @return a list of {@code provides} directives in {@code directives}
* @param directives the directives to filter
* @since 9
+ * @spec JPMS
*/
public static List<ProvidesDirective>
providesIn(Iterable<? extends Directive> directives) {
@@ -269,6 +273,7 @@
* @return a list of {@code requires} directives in {@code directives}
* @param directives the directives to filter
* @since 9
+ * @spec JPMS
*/
public static List<RequiresDirective>
requiresIn(Iterable<? extends Directive> directives) {
@@ -280,6 +285,7 @@
* @return a list of {@code uses} directives in {@code directives}
* @param directives the directives to filter
* @since 9
+ * @spec JPMS
*/
public static List<UsesDirective>
usesIn(Iterable<? extends Directive> directives) {
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor9.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementKindVisitor9.java Wed Jul 05 22:52:22 2017 +0200
@@ -75,6 +75,7 @@
* @see ElementKindVisitor7
* @see ElementKindVisitor8
* @since 9
+ * @spec JPMS
*/
@SupportedSourceVersion(RELEASE_9)
public class ElementKindVisitor9<R, P> extends ElementKindVisitor8<R, P> {
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner9.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/ElementScanner9.java Wed Jul 05 22:52:22 2017 +0200
@@ -88,6 +88,7 @@
* @see ElementScanner7
* @see ElementScanner8
* @since 9
+ * @spec JPMS
*/
@SupportedSourceVersion(RELEASE_9)
public class ElementScanner9<R, P> extends ElementScanner8<R, P> {
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/Elements.java Wed Jul 05 22:52:22 2017 +0200
@@ -111,6 +111,7 @@
* @param name the name
* @return the named module element, or {@code null} if it cannot be found
* @since 9
+ * @spec JPMS
*/
default ModuleElement getModuleElement(CharSequence name) {
return null;
@@ -359,6 +360,7 @@
* @param type the element being examined
* @return the module of an element
* @since 9
+ * @spec JPMS
*/
default ModuleElement getModuleOf(Element type) {
return null;
--- a/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor9.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/lang/model/util/SimpleElementVisitor9.java Wed Jul 05 22:52:22 2017 +0200
@@ -71,6 +71,7 @@
* @see SimpleElementVisitor7
* @see SimpleElementVisitor8
* @since 9
+ * @spec JPMS
*/
@SupportedSourceVersion(RELEASE_9)
public class SimpleElementVisitor9<R, P> extends SimpleElementVisitor8<R, P> {
--- a/langtools/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/tools/ForwardingJavaFileManager.java Wed Jul 05 22:52:22 2017 +0200
@@ -165,22 +165,42 @@
fileManager.close();
}
+ /**
+ * @since 9
+ * @spec JPMS
+ */
public Location getLocationForModule(Location location, String moduleName) throws IOException {
return fileManager.getLocationForModule(location, moduleName);
}
+ /**
+ * @since 9
+ * @spec JPMS
+ */
public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
return fileManager.getLocationForModule(location, fo, pkgName);
}
+ /**
+ * @since 9
+ * @spec JPMS
+ */
public <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) throws IOException {
return fileManager.getServiceLoader(location, service);
}
+ /**
+ * @since 9
+ * @spec JPMS
+ */
public String inferModuleName(Location location) throws IOException {
return fileManager.inferModuleName(location);
}
+ /**
+ * @since 9
+ * @spec JPMS
+ */
public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
return fileManager.listLocationsForModules(location);
}
--- a/langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/tools/JavaFileManager.java Wed Jul 05 22:52:22 2017 +0200
@@ -165,6 +165,7 @@
*
* @return true if this location is expected to contain modules
* @since 9
+ * @spec JPMS
*/
default boolean isModuleOrientedLocation() {
return getName().matches("\\bMODULE\\b");
@@ -472,6 +473,7 @@
* @throws IllegalArgumentException if the location is neither an output location nor a
* module-oriented location
* @since 9
+ * @spec JPMS
*/ // TODO: describe failure modes
default Location getLocationForModule(Location location, String moduleName) throws IOException {
throw new UnsupportedOperationException();
@@ -499,6 +501,7 @@
* @throws IllegalArgumentException if the location is neither an output location nor a
* module-oriented location
* @since 9
+ * @spec JPMS
*/
default Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
throw new UnsupportedOperationException();
@@ -522,6 +525,7 @@
* @throws IOException if an I/O error occurred
* @throws UnsupportedOperationException if this operation if not supported by this file manager
* @since 9
+ * @spec JPMS
*/ // TODO: describe failure modes
default <S> ServiceLoader<S> getServiceLoader(Location location, Class<S> service) throws IOException {
throw new UnsupportedOperationException();
@@ -540,6 +544,7 @@
* @throws UnsupportedOperationException if this operation if not supported by this file manager
* @throws IllegalArgumentException if the location is not one known to this file manager
* @since 9
+ * @spec JPMS
*/ // TODO: describe failure modes
default String inferModuleName(Location location) throws IOException {
throw new UnsupportedOperationException();
@@ -559,6 +564,7 @@
* @throws UnsupportedOperationException if this operation if not supported by this file manager
* @throws IllegalArgumentException if the location is not a module-oriented location
* @since 9
+ * @spec JPMS
*/ // TODO: describe failure modes
default Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
throw new UnsupportedOperationException();
--- a/langtools/src/java.compiler/share/classes/javax/tools/StandardLocation.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/java.compiler/share/classes/javax/tools/StandardLocation.java Wed Jul 05 22:52:22 2017 +0200
@@ -64,6 +64,7 @@
/**
* Location to search for modules containing annotation processors.
+ * @spec JPMS
* @since 9
*/
ANNOTATION_PROCESSOR_MODULE_PATH,
@@ -82,27 +83,38 @@
/**
* Location to search for the source code of modules.
+ * @spec JPMS
* @since 9
*/
MODULE_SOURCE_PATH,
/**
* Location to search for upgradeable system modules.
+ * @spec JPMS
* @since 9
*/
UPGRADE_MODULE_PATH,
/**
* Location to search for system modules.
+ * @spec JPMS
* @since 9
*/
SYSTEM_MODULES,
/**
* Location to search for precompiled user modules.
+ * @spec JPMS
* @since 9
*/
- MODULE_PATH;
+ MODULE_PATH,
+
+ /**
+ * Location to search for module patches.
+ * @since 9
+ * @spec JPMS
+ */
+ PATCH_MODULE_PATH;
/**
* Returns a location object with the given name. The following
@@ -115,6 +127,9 @@
*
* @param name a name
* @return a location
+ *
+ * @revised 9
+ * @spec JPMS
*/
public static Location locationFor(final String name) {
if (locations.isEmpty()) {
@@ -158,6 +173,7 @@
case UPGRADE_MODULE_PATH:
case SYSTEM_MODULES:
case MODULE_PATH:
+ case PATCH_MODULE_PATH:
return true;
default:
return false;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/ClientCodeWrapper.java Wed Jul 05 22:52:22 2017 +0200
@@ -361,7 +361,7 @@
@Override @DefinedBy(Api.COMPILER)
public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
try {
- return clientJavaFileManager.getLocationForModule(location, fo, pkgName);
+ return clientJavaFileManager.getLocationForModule(location, unwrap(fo), pkgName);
} catch (ClientCodeException e) {
throw e;
} catch (RuntimeException | Error e) {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/api/JavacTrees.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -418,6 +418,7 @@
private Symbol attributeDocReference(TreePath path, DCReference ref) {
Env<AttrContext> env = getAttrContext(path);
+ if (env == null) return null;
Log.DeferredDiagnosticHandler deferredDiagnosticHandler =
new Log.DeferredDiagnosticHandler(log);
@@ -881,6 +882,7 @@
case INTERFACE:
// System.err.println("CLASS: " + ((JCClassDecl)tree).sym.getSimpleName());
env = enter.getClassEnv(((JCClassDecl)tree).sym);
+ if (env == null) return null;
break;
case METHOD:
// System.err.println("METHOD: " + ((JCMethodDecl)tree).sym.getSimpleName());
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ClassFinder.java Wed Jul 05 22:52:22 2017 +0200
@@ -553,20 +553,47 @@
Location classLocn = msym.classLocation;
Location sourceLocn = msym.sourceLocation;
+ Location patchLocn = msym.patchLocation;
+ Location patchOutLocn = msym.patchOutputLocation;
- if (wantClassFiles && (classLocn != null)) {
- fillIn(p, classLocn,
- list(classLocn,
- p,
- packageName,
- classKinds));
- }
- if (wantSourceFiles && (sourceLocn != null)) {
- fillIn(p, sourceLocn,
- list(sourceLocn,
- p,
- packageName,
- sourceKinds));
+ boolean prevPreferCurrent = preferCurrent;
+
+ try {
+ preferCurrent = false;
+ if (wantClassFiles && (patchOutLocn != null)) {
+ fillIn(p, patchOutLocn,
+ list(patchOutLocn,
+ p,
+ packageName,
+ classKinds));
+ }
+ if ((wantClassFiles || wantSourceFiles) && (patchLocn != null)) {
+ Set<JavaFileObject.Kind> combined = EnumSet.noneOf(JavaFileObject.Kind.class);
+ combined.addAll(classKinds);
+ combined.addAll(sourceKinds);
+ fillIn(p, patchLocn,
+ list(patchLocn,
+ p,
+ packageName,
+ combined));
+ }
+ preferCurrent = true;
+ if (wantClassFiles && (classLocn != null)) {
+ fillIn(p, classLocn,
+ list(classLocn,
+ p,
+ packageName,
+ classKinds));
+ }
+ if (wantSourceFiles && (sourceLocn != null)) {
+ fillIn(p, sourceLocn,
+ list(sourceLocn,
+ p,
+ packageName,
+ sourceKinds));
+ }
+ } finally {
+ preferCurrent = prevPreferCurrent;
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Directive.java Wed Jul 05 22:52:22 2017 +0200
@@ -53,8 +53,8 @@
/** Flags for RequiresDirective. */
public enum RequiresFlag {
- TRANSITIVE(0x0010),
- STATIC_PHASE(0x0020),
+ TRANSITIVE(0x0020),
+ STATIC_PHASE(0x0040),
SYNTHETIC(0x1000),
MANDATED(0x8000),
EXTRA(0x10000);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/ModuleFinder.java Wed Jul 05 22:52:22 2017 +0200
@@ -267,6 +267,7 @@
private List<ModuleSymbol> scanModulePath(ModuleSymbol toFind) {
ListBuffer<ModuleSymbol> results = new ListBuffer<>();
Map<Name, Location> namesInSet = new HashMap<>();
+ boolean multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH);
while (moduleLocationIterator.hasNext()) {
Set<Location> locns = (moduleLocationIterator.next());
namesInSet.clear();
@@ -279,10 +280,29 @@
// module has already been found, so ignore this instance
continue;
}
+ if (fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH) &&
+ msym.patchLocation == null) {
+ msym.patchLocation =
+ fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
+ msym.name.toString());
+ checkModuleInfoOnLocation(msym.patchLocation, Kind.CLASS, Kind.SOURCE);
+ if (msym.patchLocation != null &&
+ multiModuleMode &&
+ fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
+ msym.patchOutputLocation =
+ fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT,
+ msym.name.toString());
+ checkModuleInfoOnLocation(msym.patchOutputLocation, Kind.CLASS);
+ }
+ }
if (moduleLocationIterator.outer == StandardLocation.MODULE_SOURCE_PATH) {
- msym.sourceLocation = l;
- if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
- msym.classLocation = fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT, msym.name.toString());
+ if (msym.patchLocation == null) {
+ msym.sourceLocation = l;
+ if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
+ msym.classLocation =
+ fileManager.getLocationForModule(StandardLocation.CLASS_OUTPUT,
+ msym.name.toString());
+ }
}
} else {
msym.classLocation = l;
@@ -291,7 +311,8 @@
moduleLocationIterator.outer == StandardLocation.UPGRADE_MODULE_PATH) {
msym.flags_field |= Flags.SYSTEM_MODULE;
}
- if (toFind == msym || toFind == null) {
+ if (toFind == null ||
+ (toFind == msym && (msym.sourceLocation != null || msym.classLocation != null))) {
// Note: cannot return msym directly, because we must finish
// processing this set first
results.add(msym);
@@ -311,6 +332,21 @@
return results.toList();
}
+ private void checkModuleInfoOnLocation(Location location, Kind... kinds) throws IOException {
+ if (location == null)
+ return ;
+
+ for (Kind kind : kinds) {
+ JavaFileObject file = fileManager.getJavaFileForInput(location,
+ names.module_info.toString(),
+ kind);
+ if (file != null) {
+ log.error(Errors.LocnModuleInfoNotAllowedOnPatchPath(file));
+ return;
+ }
+ }
+ }
+
private void findModuleInfo(ModuleSymbol msym) {
try {
JavaFileObject src_fo = (msym.sourceLocation == null) ? null
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Wed Jul 05 22:52:22 2017 +0200
@@ -908,6 +908,8 @@
public Name version;
public JavaFileManager.Location sourceLocation;
public JavaFileManager.Location classLocation;
+ public JavaFileManager.Location patchLocation;
+ public JavaFileManager.Location patchOutputLocation;
/** All directives, in natural order. */
public List<com.sun.tools.javac.code.Directive> directives;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java Wed Jul 05 22:52:22 2017 +0200
@@ -3994,10 +3994,16 @@
rs.methodArguments(argtypes.map(checkDeferredMap)),
kindName(sym.location()),
sym.location());
- owntype = new MethodType(owntype.getParameterTypes(),
- types.erasure(owntype.getReturnType()),
- types.erasure(owntype.getThrownTypes()),
- syms.methodClass);
+ if (resultInfo.pt != Infer.anyPoly ||
+ !owntype.hasTag(METHOD) ||
+ !owntype.isPartial()) {
+ //if this is not a partially inferred method type, erase return type. Otherwise,
+ //erasure is carried out in PartiallyInferredMethodType.check().
+ owntype = new MethodType(owntype.getParameterTypes(),
+ types.erasure(owntype.getReturnType()),
+ types.erasure(owntype.getThrownTypes()),
+ syms.methodClass);
+ }
}
PolyKind pkind = (sym.type.hasTag(FORALL) &&
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Enter.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,7 @@
import javax.tools.JavaFileManager;
import com.sun.tools.javac.code.*;
+import com.sun.tools.javac.code.Kinds.KindName;
import com.sun.tools.javac.code.Kinds.KindSelector;
import com.sun.tools.javac.code.Scope.*;
import com.sun.tools.javac.code.Symbol.*;
@@ -155,6 +156,7 @@
public Env<AttrContext> getClassEnv(TypeSymbol sym) {
Env<AttrContext> localEnv = getEnv(sym);
+ if (localEnv == null) return null;
Env<AttrContext> lintEnv = localEnv;
while (lintEnv.info.lint == null)
lintEnv = lintEnv.next;
@@ -400,8 +402,14 @@
c = syms.enterClass(env.toplevel.modle, tree.name, packge);
packge.members().enterIfAbsent(c);
if ((tree.mods.flags & PUBLIC) != 0 && !classNameMatchesFileName(c, env)) {
+ KindName topElement = KindName.CLASS;
+ if ((tree.mods.flags & ENUM) != 0) {
+ topElement = KindName.ENUM;
+ } else if ((tree.mods.flags & INTERFACE) != 0) {
+ topElement = KindName.INTERFACE;
+ }
log.error(tree.pos(),
- "class.public.should.be.in.file", tree.name);
+ "class.public.should.be.in.file", topElement, tree.name);
}
} else {
if (!tree.name.isEmpty() &&
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Wed Jul 05 22:52:22 2017 +0200
@@ -319,7 +319,8 @@
* need to use it several times: with several targets.
*/
saved_undet = inferenceContext.save();
- if (allowGraphInference && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
+ boolean unchecked = warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED);
+ if (allowGraphInference && !unchecked) {
boolean shouldPropagate = shouldPropagate(getReturnType(), resultInfo, inferenceContext);
InferenceContext minContext = shouldPropagate ?
@@ -338,7 +339,10 @@
}
}
inferenceContext.solve(noWarnings);
- return inferenceContext.asInstType(this).getReturnType();
+ Type ret = inferenceContext.asInstType(this).getReturnType();
+ //inline logic from Attr.checkMethod - if unchecked conversion was required, erase
+ //return type _after_ resolution
+ return unchecked ? types.erasure(ret) : ret;
} catch (InferenceException ex) {
resultInfo.checkContext.report(null, ex.getDiagnostic());
Assert.error(); //cannot get here (the above should throw)
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Modules.java Wed Jul 05 22:52:22 2017 +0200
@@ -145,7 +145,7 @@
public final boolean multiModuleMode;
- private final String moduleOverride;
+ private final String legacyModuleOverride;
private final Name java_se;
private final Name java_;
@@ -192,7 +192,7 @@
lintOptions = options.isUnset(Option.XLINT_CUSTOM, "-" + LintCategory.OPTIONS.option);
- moduleOverride = options.get(Option.XMODULE);
+ legacyModuleOverride = options.get(Option.XMODULE);
multiModuleMode = fileManager.hasLocation(StandardLocation.MODULE_SOURCE_PATH);
ClassWriter classWriter = ClassWriter.instance(context);
@@ -366,9 +366,26 @@
JavaFileObject prev = log.useSource(tree.sourcefile);
try {
- Location locn = getModuleLocation(tree);
- if (locn != null) {
- Name name = names.fromString(fileManager.inferModuleName(locn));
+ Location msplocn = getModuleLocation(tree);
+ Location plocn = fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH) ?
+ fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
+ tree.sourcefile, getPackageName(tree)) :
+ null;
+
+ if (plocn != null) {
+ Name name = names.fromString(fileManager.inferModuleName(plocn));
+ ModuleSymbol msym = moduleFinder.findModule(name);
+ tree.modle = msym;
+ rootModules.add(msym);
+
+ if (msplocn != null) {
+ Name mspname = names.fromString(fileManager.inferModuleName(msplocn));
+ if (name != mspname) {
+ log.error(tree.pos(), Errors.FilePatchedAndMsp(name, mspname));
+ }
+ }
+ } else if (msplocn != null) {
+ Name name = names.fromString(fileManager.inferModuleName(msplocn));
ModuleSymbol msym;
JCModuleDecl decl = tree.getModuleDecl();
if (decl != null) {
@@ -383,7 +400,7 @@
msym = syms.enterModule(name);
}
if (msym.sourceLocation == null) {
- msym.sourceLocation = locn;
+ msym.sourceLocation = msplocn;
if (fileManager.hasLocation(StandardLocation.CLASS_OUTPUT)) {
msym.classLocation = fileManager.getLocationForModule(
StandardLocation.CLASS_OUTPUT, msym.name.toString());
@@ -414,7 +431,9 @@
}
defaultModule = syms.unnamedModule;
} else {
+ ModuleSymbol module = null;
if (defaultModule == null) {
+ String moduleOverride = singleModuleOverride(trees);
switch (rootModules.size()) {
case 0:
defaultModule = moduleFinder.findSingleModule();
@@ -422,38 +441,49 @@
if (moduleOverride != null) {
checkNoAllModulePath();
defaultModule = moduleFinder.findModule(names.fromString(moduleOverride));
- defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
+ if (legacyModuleOverride != null) {
+ defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
+ }
+ defaultModule.patchOutputLocation = StandardLocation.CLASS_OUTPUT;
} else {
// Question: why not do findAllModules and initVisiblePackages here?
// i.e. body of unnamedModuleCompleter
defaultModule.completer = getUnnamedModuleCompleter();
+ defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
defaultModule.classLocation = StandardLocation.CLASS_PATH;
}
} else {
- checkSpecifiedModule(trees, Errors.ModuleInfoWithXmoduleClasspath);
+ checkSpecifiedModule(trees, moduleOverride, Errors.ModuleInfoWithPatchedModuleClassoutput);
checkNoAllModulePath();
defaultModule.complete();
// Question: why not do completeModule here?
defaultModule.completer = sym -> completeModule((ModuleSymbol) sym);
+ defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
}
rootModules.add(defaultModule);
break;
case 1:
- checkSpecifiedModule(trees, Errors.ModuleInfoWithXmoduleSourcepath);
+ checkSpecifiedModule(trees, moduleOverride, Errors.ModuleInfoWithPatchedModuleSourcepath);
checkNoAllModulePath();
defaultModule = rootModules.iterator().next();
+ defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
defaultModule.classLocation = StandardLocation.CLASS_OUTPUT;
break;
default:
Assert.error("too many modules");
}
- defaultModule.sourceLocation = StandardLocation.SOURCE_PATH;
} else if (rootModules.size() == 1 && defaultModule == rootModules.iterator().next()) {
defaultModule.complete();
defaultModule.completer = sym -> completeModule((ModuleSymbol) sym);
} else {
Assert.check(rootModules.isEmpty());
- rootModules.add(defaultModule);
+ String moduleOverride = singleModuleOverride(trees);
+ if (moduleOverride != null) {
+ module = moduleFinder.findModule(names.fromString(moduleOverride));
+ } else {
+ module = defaultModule;
+ }
+ rootModules.add(module);
}
if (defaultModule != syms.unnamedModule) {
@@ -461,12 +491,56 @@
syms.unnamedModule.classLocation = StandardLocation.CLASS_PATH;
}
+ if (module == null) {
+ module = defaultModule;
+ }
+
for (JCCompilationUnit tree: trees) {
- tree.modle = defaultModule;
+ tree.modle = module;
}
}
}
+ private String singleModuleOverride(List<JCCompilationUnit> trees) {
+ if (!fileManager.hasLocation(StandardLocation.PATCH_MODULE_PATH)) {
+ return legacyModuleOverride;
+ }
+
+ Set<String> override = new LinkedHashSet<>();
+ for (JCCompilationUnit tree : trees) {
+ JavaFileObject fo = tree.sourcefile;
+
+ try {
+ Location loc =
+ fileManager.getLocationForModule(StandardLocation.PATCH_MODULE_PATH,
+ fo, getPackageName(tree));
+
+ if (loc != null) {
+ override.add(fileManager.inferModuleName(loc));
+ }
+ } catch (IOException ex) {
+ throw new Error(ex);
+ }
+ }
+
+ switch (override.size()) {
+ case 0: return legacyModuleOverride;
+ case 1: return override.iterator().next();
+ default:
+ log.error(Errors.TooManyPatchedModules(override));
+ return null;
+ }
+ }
+
+ private String getPackageName(JCCompilationUnit tree) {
+ if (tree.getModuleDecl() != null) {
+ return null;
+ } else {
+ JCPackageDecl pkg = tree.getPackage();
+ return (pkg == null) ? "" : TreeInfo.fullName(pkg.pid).toString();
+ }
+ }
+
/**
* Determine the location for the module on the module source path
* or source output directory which contains a given CompilationUnit.
@@ -478,32 +552,23 @@
* @throws IOException if there is a problem while searching for the module.
*/
private Location getModuleLocation(JCCompilationUnit tree) throws IOException {
- Name pkgName;
- if (tree.getModuleDecl() != null) {
- pkgName = null;
- } else {
- JCPackageDecl pkg = tree.getPackage();
- pkgName = (pkg == null) ? names.empty : TreeInfo.fullName(pkg.pid);
- }
-
+ String pkgName = getPackageName(tree);
JavaFileObject fo = tree.sourcefile;
- // For now, just check module source path.
- // We may want to check source path as well.
Location loc =
fileManager.getLocationForModule(StandardLocation.MODULE_SOURCE_PATH,
- fo, (pkgName == null) ? null : pkgName.toString());
+ fo, (pkgName == null) ? null : pkgName);
if (loc == null) {
Location sourceOutput = fileManager.hasLocation(StandardLocation.SOURCE_OUTPUT) ?
StandardLocation.SOURCE_OUTPUT : StandardLocation.CLASS_OUTPUT;
loc =
fileManager.getLocationForModule(sourceOutput,
- fo, (pkgName == null) ? null : pkgName.toString());
+ fo, (pkgName == null) ? null : pkgName);
}
return loc;
}
- private void checkSpecifiedModule(List<JCCompilationUnit> trees, JCDiagnostic.Error error) {
+ private void checkSpecifiedModule(List<JCCompilationUnit> trees, String moduleOverride, JCDiagnostic.Error error) {
if (moduleOverride != null) {
JavaFileObject prev = log.useSource(trees.head.sourcefile);
try {
@@ -1594,8 +1659,8 @@
}
public void newRound() {
+ allModules = null;
rootModules = null;
- allModules = null;
warnedMissing.clear();
}
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/JavacFileManager.java Wed Jul 05 22:52:22 2017 +0200
@@ -968,7 +968,7 @@
Collection<Path> paths = locations.getLocation(location);
ModuleFinder finder = ModuleFinder.of(paths.toArray(new Path[paths.size()]));
Layer bootLayer = Layer.boot();
- Configuration cf = bootLayer.configuration().resolveRequiresAndUses(ModuleFinder.of(), finder, Collections.emptySet());
+ Configuration cf = bootLayer.configuration().resolveAndBind(ModuleFinder.of(), finder, Collections.emptySet());
Layer layer = bootLayer.defineModulesWithOneLoader(cf, ClassLoader.getSystemClassLoader());
return ServiceLoaderHelper.load(layer, service);
} else {
@@ -980,7 +980,7 @@
public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
checkModuleOrientedOrOutputLocation(location);
if (!(fo instanceof PathFileObject))
- throw new IllegalArgumentException(fo.getName());
+ return null;
int depth = 1; // allow 1 for filename
if (pkgName != null && !pkgName.isEmpty()) {
depth += 1;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/file/Locations.java Wed Jul 05 22:52:22 2017 +0200
@@ -432,7 +432,7 @@
/**
* @see JavaFileManager#getLocationForModule(Location, JavaFileObject, String)
*/
- Location getLocationForModule(Path dir) {
+ Location getLocationForModule(Path dir) throws IOException {
return null;
}
@@ -545,7 +545,7 @@
l = new ModuleLocationHandler(location.getName() + "[" + name + "]",
name,
Collections.singleton(out),
- true, false);
+ true);
moduleLocations.put(name, l);
pathLocations.put(out.toAbsolutePath(), l);
}
@@ -864,29 +864,14 @@
protected final String name;
protected final String moduleName;
protected final Collection<Path> searchPath;
- protected final Collection<Path> searchPathWithOverrides;
protected final boolean output;
ModuleLocationHandler(String name, String moduleName, Collection<Path> searchPath,
- boolean output, boolean allowOverrides) {
+ boolean output) {
this.name = name;
this.moduleName = moduleName;
this.searchPath = searchPath;
this.output = output;
-
- if (allowOverrides && patchMap != null) {
- SearchPath mPatch = patchMap.get(moduleName);
- if (mPatch != null) {
- SearchPath sp = new SearchPath();
- sp.addAll(mPatch);
- sp.addAll(searchPath);
- searchPathWithOverrides = sp;
- } else {
- searchPathWithOverrides = searchPath;
- }
- } else {
- searchPathWithOverrides = searchPath;
- }
}
@Override @DefinedBy(Api.COMPILER)
@@ -909,7 +894,7 @@
// For now, we always return searchPathWithOverrides. This may differ from the
// JVM behavior if there is a module-info.class to be found in the overriding
// classes.
- return searchPathWithOverrides;
+ return searchPath;
}
@Override // defined by LocationHandler
@@ -985,6 +970,11 @@
}
private void checkValidModulePathEntry(Path p) {
+ if (!Files.exists(p)) {
+ // warning may be generated later
+ return;
+ }
+
if (Files.isDirectory(p)) {
// either an exploded module or a directory of modules
return;
@@ -1063,7 +1053,7 @@
String name = location.getName()
+ "[" + pathIndex + ":" + moduleName + "]";
ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName,
- Collections.singleton(path), false, true);
+ Collections.singleton(path), false);
return Collections.singleton(l);
} catch (ModuleNameReader.BadClassFile e) {
log.error(Errors.LocnBadModuleInfo(path));
@@ -1088,7 +1078,7 @@
String name = location.getName()
+ "[" + pathIndex + "." + (index++) + ":" + moduleName + "]";
ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName,
- Collections.singleton(modulePath), false, true);
+ Collections.singleton(modulePath), false);
result.add(l);
}
return result;
@@ -1105,7 +1095,7 @@
String name = location.getName()
+ "[" + pathIndex + ":" + moduleName + "]";
ModuleLocationHandler l = new ModuleLocationHandler(name, moduleName,
- Collections.singleton(modulePath), false, true);
+ Collections.singleton(modulePath), false);
return Collections.singleton(l);
}
@@ -1272,7 +1262,7 @@
pathLocations = new LinkedHashMap<>();
map.forEach((k, v) -> {
String name = location.getName() + "[" + k + "]";
- ModuleLocationHandler h = new ModuleLocationHandler(name, k, v, false, false);
+ ModuleLocationHandler h = new ModuleLocationHandler(name, k, v, false);
moduleLocations.put(k, h);
v.forEach(p -> pathLocations.put(normalize(p), h));
});
@@ -1412,6 +1402,7 @@
private Path systemJavaHome;
private Path modules;
private Map<String, ModuleLocationHandler> systemModules;
+ private Map<Path, Location> pathLocations;
SystemModulesLocationHandler() {
super(StandardLocation.SYSTEM_MODULES, Option.SYSTEM);
@@ -1486,6 +1477,12 @@
}
@Override
+ Location getLocationForModule(Path dir) throws IOException {
+ initSystemModules();
+ return (pathLocations == null) ? null : pathLocations.get(dir);
+ }
+
+ @Override
Iterable<Set<Location>> listLocationsForModules() throws IOException {
initSystemModules();
Set<Location> locns = new LinkedHashSet<>();
@@ -1539,18 +1536,96 @@
}
systemModules = new LinkedHashMap<>();
+ pathLocations = new LinkedHashMap<>();
try (DirectoryStream<Path> stream = Files.newDirectoryStream(modules, Files::isDirectory)) {
for (Path entry : stream) {
String moduleName = entry.getFileName().toString();
String name = location.getName() + "[" + moduleName + "]";
ModuleLocationHandler h = new ModuleLocationHandler(name, moduleName,
- Collections.singleton(entry), false, true);
+ Collections.singleton(entry), false);
systemModules.put(moduleName, h);
+ pathLocations.put(normalize(entry), h);
}
}
}
}
+ private class PatchModulesLocationHandler extends BasicLocationHandler {
+ private final Map<String, ModuleLocationHandler> moduleLocations = new HashMap<>();
+ private final Map<Path, Location> pathLocations = new HashMap<>();
+
+ PatchModulesLocationHandler() {
+ super(StandardLocation.PATCH_MODULE_PATH, Option.PATCH_MODULE);
+ }
+
+ @Override
+ boolean handleOption(Option option, String value) {
+ if (!options.contains(option)) {
+ return false;
+ }
+
+ // Allow an extended syntax for --patch-module consisting of a series
+ // of values separated by NULL characters. This is to facilitate
+ // supporting deferred file manager options on the command line.
+ // See Option.PATCH_MODULE for the code that composes these multiple
+ // values.
+ for (String v : value.split("\0")) {
+ int eq = v.indexOf('=');
+ if (eq > 0) {
+ String moduleName = v.substring(0, eq);
+ SearchPath mPatchPath = new SearchPath()
+ .addFiles(v.substring(eq + 1));
+ String name = location.getName() + "[" + moduleName + "]";
+ ModuleLocationHandler h = new ModuleLocationHandler(name, moduleName, mPatchPath, false);
+ moduleLocations.put(moduleName, h);
+ for (Path r : mPatchPath) {
+ pathLocations.put(normalize(r), h);
+ }
+ } else {
+ // Should not be able to get here;
+ // this should be caught and handled in Option.PATCH_MODULE
+ log.error(Errors.LocnInvalidArgForXpatch(value));
+ }
+ }
+
+ return true;
+ }
+
+ @Override
+ boolean isSet() {
+ return !moduleLocations.isEmpty();
+ }
+
+ @Override
+ Collection<Path> getPaths() {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ void setPaths(Iterable<? extends Path> files) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ Location getLocationForModule(String name) throws IOException {
+ return moduleLocations.get(name);
+ }
+
+ @Override
+ Location getLocationForModule(Path dir) throws IOException {
+ return (pathLocations == null) ? null : pathLocations.get(dir);
+ }
+
+ @Override
+ Iterable<Set<Location>> listLocationsForModules() throws IOException {
+ Set<Location> locns = new LinkedHashSet<>();
+ for (Location l: moduleLocations.values())
+ locns.add(l);
+ return Collections.singleton(locns);
+ }
+
+ }
+
Map<Location, LocationHandler> handlersForLocation;
Map<Option, LocationHandler> handlersForOption;
@@ -1568,6 +1643,7 @@
new OutputLocationHandler(StandardLocation.SOURCE_OUTPUT, Option.S),
new OutputLocationHandler(StandardLocation.NATIVE_HEADER_OUTPUT, Option.H),
new ModuleSourcePathLocationHandler(),
+ new PatchModulesLocationHandler(),
// TODO: should UPGRADE_MODULE_PATH be merged with SYSTEM_MODULES?
new ModulePathLocationHandler(StandardLocation.UPGRADE_MODULE_PATH, Option.UPGRADE_MODULE_PATH),
new ModulePathLocationHandler(StandardLocation.MODULE_PATH, Option.MODULE_PATH),
@@ -1582,51 +1658,9 @@
}
}
- private Map<String, SearchPath> patchMap;
-
boolean handleOption(Option option, String value) {
- switch (option) {
- case PATCH_MODULE:
- if (value == null) {
- patchMap = null;
- } else {
- // Allow an extended syntax for --patch-module consisting of a series
- // of values separated by NULL characters. This is to facilitate
- // supporting deferred file manager options on the command line.
- // See Option.PATCH_MODULE for the code that composes these multiple
- // values.
- for (String v : value.split("\0")) {
- int eq = v.indexOf('=');
- if (eq > 0) {
- String mName = v.substring(0, eq);
- SearchPath mPatchPath = new SearchPath()
- .addFiles(v.substring(eq + 1));
- boolean ok = true;
- for (Path p : mPatchPath) {
- Path mi = p.resolve("module-info.class");
- if (Files.exists(mi)) {
- log.error(Errors.LocnModuleInfoNotAllowedOnPatchPath(mi));
- ok = false;
- }
- }
- if (ok) {
- if (patchMap == null) {
- patchMap = new LinkedHashMap<>();
- }
- patchMap.put(mName, mPatchPath);
- }
- } else {
- // Should not be able to get here;
- // this should be caught and handled in Option.PATCH_MODULE
- log.error(Errors.LocnInvalidArgForXpatch(value));
- }
- }
- }
- return true;
- default:
- LocationHandler h = handlersForOption.get(option);
- return (h == null ? false : h.handleOption(option, value));
- }
+ LocationHandler h = handlersForOption.get(option);
+ return (h == null ? false : h.handleOption(option, value));
}
boolean hasLocation(Location location) {
@@ -1665,7 +1699,7 @@
return (h == null ? null : h.getLocationForModule(name));
}
- Location getLocationForModule(Location location, Path dir) {
+ Location getLocationForModule(Location location, Path dir) throws IOException {
LocationHandler h = getHandler(location);
return (h == null ? null : h.getLocationForModule(dir));
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,6 @@
import com.sun.tools.javac.code.Type.*;
import com.sun.tools.javac.jvm.Code.*;
import com.sun.tools.javac.jvm.Items.*;
-import com.sun.tools.javac.main.Option;
import com.sun.tools.javac.tree.EndPosTable;
import com.sun.tools.javac.tree.JCTree.*;
@@ -67,10 +66,9 @@
private final TreeMaker make;
private final Names names;
private final Target target;
- private Name accessDollar;
+ private final Name accessDollar;
private final Types types;
private final Lower lower;
- private final Flow flow;
private final Annotate annotate;
private final StringConcat concat;
@@ -95,7 +93,7 @@
/** Constant pool, reset by genClass.
*/
- private Pool pool;
+ private final Pool pool;
protected Gen(Context context) {
context.put(genKey, this);
@@ -113,7 +111,6 @@
methodType = new MethodType(null, null, null, syms.methodClass);
accessDollar = names.
fromString("access" + target.syntheticNameChar());
- flow = Flow.instance(context);
lower = Lower.instance(context);
Options options = Options.instance(context);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Arguments.java Wed Jul 05 22:52:22 2017 +0200
@@ -598,9 +598,6 @@
&& !fm.hasLocation(StandardLocation.CLASS_OUTPUT)) {
log.error(Errors.NoOutputDir);
}
- if (options.isSet(Option.XMODULE)) {
- log.error(Errors.XmoduleNoModuleSourcepath);
- }
}
if (fm.hasLocation(StandardLocation.ANNOTATION_PROCESSOR_MODULE_PATH) &&
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/JavaCompiler.java Wed Jul 05 22:52:22 2017 +0200
@@ -1450,6 +1450,11 @@
return;
}
+ if (!modules.multiModuleMode && env.toplevel.modle != modules.getDefaultModule()) {
+ //can only generate classfiles for a single module:
+ return;
+ }
+
if (compileStates.isDone(env, CompileState.LOWER)) {
results.addAll(desugaredEnvs.get(env));
return;
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/main/Option.java Wed Jul 05 22:52:22 2017 +0200
@@ -579,7 +579,7 @@
}
},
- XMODULE("-Xmodule:", "opt.arg.module", "opt.module", EXTENDED, BASIC) {
+ XMODULE("-Xmodule:", "opt.arg.module", "opt.module", HIDDEN, BASIC) {
@Override
public void process(OptionHelper helper, String option, String arg) throws InvalidValueException {
String prev = helper.get(XMODULE);
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties Wed Jul 05 22:52:22 2017 +0200
@@ -1246,9 +1246,9 @@
# In the following string, {0} is the name of the class in the Java source.
# It really should be used two times..
-# 0: name
+# 0: kind name, 1: name
compiler.err.class.public.should.be.in.file=\
- class {0} is public, should be declared in a file named {0}.java
+ {0} {1} is public, should be declared in a file named {1}.java
## All errors which do not refer to a particular line in the source code are
## preceded by this string.
@@ -1292,7 +1292,7 @@
compiler.warn.outdir.is.in.exploded.module=\
the output directory is within an exploded module: {0}
-# 0: path
+# 0: file object
compiler.err.locn.module-info.not.allowed.on.patch.path=\
module-info.class not allowed on patch path: {0}
@@ -2957,14 +2957,20 @@
compiler.err.module.decl.sb.in.module-info.java=\
module declarations should be in a file named module-info.java
-compiler.err.module-info.with.xmodule.sourcepath=\
- illegal combination of -Xmodule and module-info on sourcepath
-
-compiler.err.module-info.with.xmodule.classpath=\
- illegal combination of -Xmodule and module-info on classpath
-
-compiler.err.xmodule.no.module.sourcepath=\
- illegal combination of -Xmodule and --module-source-path
+compiler.err.module-info.with.patched.module.sourcepath=\
+ compiling a module patch with module-info on sourcepath
+
+compiler.err.module-info.with.patched.module.classoutput=\
+ compiling a module patch with module-info on class output
+
+# 0: set of string
+compiler.err.too.many.patched.modules=\
+ too many patched modules ({0}), use --module-source-path
+
+# 0: name, 1: name
+compiler.err.file.patched.and.msp=\
+ file accessible from both --patch-module and --module-source-path, \
+ but belongs to a different module on each path: {0}, {1}
compiler.err.processorpath.no.processormodulepath=\
illegal combination of -processorpath and --processor-module-path
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JDK9Wrappers.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/util/JDK9Wrappers.java Wed Jul 05 22:52:22 2017 +0200
@@ -272,12 +272,12 @@
init();
}
- public Configuration resolveRequiresAndUses(
+ public Configuration resolveAndBind(
ModuleFinder beforeFinder,
ModuleFinder afterFinder,
Collection<String> roots) {
try {
- Object result = resolveRequiresAndUsesMethod.invoke(theRealConfiguration,
+ Object result = resolveAndBindMethod.invoke(theRealConfiguration,
beforeFinder.theRealModuleFinder,
afterFinder.theRealModuleFinder,
roots
@@ -293,7 +293,7 @@
// -----------------------------------------------------------------------------------------
private static Class<?> configurationClass = null;
- private static Method resolveRequiresAndUsesMethod;
+ private static Method resolveAndBindMethod;
static final Class<?> getConfigurationClass() {
init();
@@ -305,7 +305,7 @@
try {
configurationClass = Class.forName("java.lang.module.Configuration", false, null);
Class<?> moduleFinderInterface = ModuleFinder.getModuleFinderClass();
- resolveRequiresAndUsesMethod = configurationClass.getDeclaredMethod("resolveRequiresAndUses",
+ resolveAndBindMethod = configurationClass.getDeclaredMethod("resolveAndBind",
moduleFinderInterface,
moduleFinderInterface,
Collection.class
--- a/langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.compiler/share/classes/jdk/internal/shellsupport/doc/JavadocHelper.java Wed Jul 05 22:52:22 2017 +0200
@@ -49,12 +49,15 @@
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.ModuleElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeKind;
import javax.lang.model.type.TypeMirror;
import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.tools.ForwardingJavaFileManager;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
@@ -542,8 +545,13 @@
if (type == null)
return null;
- String binaryName = origin.getElements().getBinaryName(type).toString();
- Pair<JavacTask, CompilationUnitTree> source = findSource(binaryName);
+ Elements elements = origin.getElements();
+ String binaryName = elements.getBinaryName(type).toString();
+ ModuleElement module = elements.getModuleOf(type);
+ String moduleName = module == null || module.isUnnamed()
+ ? null
+ : module.getQualifiedName().toString();
+ Pair<JavacTask, CompilationUnitTree> source = findSource(moduleName, binaryName);
if (source == null)
return null;
@@ -636,7 +644,8 @@
}.scan(cut, null);
}
- private Pair<JavacTask, CompilationUnitTree> findSource(String binaryName) throws IOException {
+ private Pair<JavacTask, CompilationUnitTree> findSource(String moduleName,
+ String binaryName) throws IOException {
JavaFileObject jfo = fm.getJavaFileForInput(StandardLocation.SOURCE_PATH,
binaryName,
JavaFileObject.Kind.SOURCE);
@@ -645,7 +654,10 @@
return null;
List<JavaFileObject> jfos = Arrays.asList(jfo);
- JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, baseFileManager, d -> {}, null, null, jfos);
+ JavaFileManager patchFM = moduleName != null
+ ? new PatchModuleFileManager(baseFileManager, jfo, moduleName)
+ : baseFileManager;
+ JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, patchFM, d -> {}, null, null, jfos);
Iterable<? extends CompilationUnitTree> cuts = task.parse();
task.enter();
@@ -657,6 +669,61 @@
public void close() throws IOException {
fm.close();
}
+
+ private static final class PatchModuleFileManager
+ extends ForwardingJavaFileManager<JavaFileManager> {
+
+ private final JavaFileObject file;
+ private final String moduleName;
+
+ public PatchModuleFileManager(JavaFileManager fileManager,
+ JavaFileObject file,
+ String moduleName) {
+ super(fileManager);
+ this.file = file;
+ this.moduleName = moduleName;
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
+ public Location getLocationForModule(Location location,
+ JavaFileObject fo,
+ String pkgName) throws IOException {
+ return fo == file
+ ? PATCH_LOCATION
+ : super.getLocationForModule(location, fo, pkgName);
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
+ public String inferModuleName(Location location) throws IOException {
+ return location == PATCH_LOCATION
+ ? moduleName
+ : super.inferModuleName(location);
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
+ public boolean hasLocation(Location location) {
+ return location == StandardLocation.PATCH_MODULE_PATH ||
+ super.hasLocation(location);
+ }
+
+ private static final Location PATCH_LOCATION = new Location() {
+ @Override @DefinedBy(Api.COMPILER)
+ public String getName() {
+ return "PATCH_LOCATION";
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
+ public boolean isOutputLocation() {
+ return false;
+ }
+
+ @Override @DefinedBy(Api.COMPILER)
+ public boolean isModuleOrientedLocation() {
+ return false;
+ }
+
+ };
+ }
}
}
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/main/ToolOption.java Wed Jul 05 22:52:22 2017 +0200
@@ -204,13 +204,6 @@
}
},
- XMODULE("-Xmodule:", false) {
- @Override
- public void process(Helper helper, String arg) throws InvalidValueException {
- Option.XMODULE.process(helper.getOptionHelper(), arg);
- }
- },
-
PATCH_MODULE("--patch-module", true) {
@Override
public void process(Helper helper, String arg) throws InvalidValueException {
--- a/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/com/sun/tools/javadoc/resources/javadoc.properties Wed Jul 05 22:52:22 2017 +0200
@@ -82,7 +82,6 @@
\ Specify additional modules to be considered as required by a\n\
\ given module. <other-module> may be ALL-UNNAMED to require\n\
\ the unnamed module.\n\
-\ -Xmodule:<module-name> Specify a module to which the classes being compiled belong.\n\
\ --patch-module <module>=<file>(:<file>)*\n\
\ Override or augment a module with classes and resources\n\
\ in JAR files or directories\n
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleIndexWriter.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -144,6 +144,7 @@
Content div = HtmlTree.DIV(HtmlStyle.contentContainer, table);
if (configuration.allowTag(HtmlTag.MAIN)) {
htmlTree.addContent(div);
+ body.addContent(htmlTree);
} else {
body.addContent(div);
}
@@ -183,21 +184,12 @@
protected void addOverviewHeader(Content body) {
addConfigurationTitle(body);
if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
- HtmlTree subTitleDiv = new HtmlTree(HtmlTag.DIV);
- subTitleDiv.addStyle(HtmlStyle.subTitle);
- addSummaryComment(configuration.overviewElement, subTitleDiv);
- Content div = HtmlTree.DIV(HtmlStyle.header, subTitleDiv);
- Content see = new ContentBuilder();
- see.addContent(contents.seeLabel);
- see.addContent(" ");
- Content descPara = HtmlTree.P(see);
- Content descLink = getHyperLink(getDocLink(
- SectionName.OVERVIEW_DESCRIPTION),
- contents.descriptionLabel, "", "");
- descPara.addContent(descLink);
- div.addContent(descPara);
+ HtmlTree div = new HtmlTree(HtmlTag.DIV);
+ div.addStyle(HtmlStyle.contentContainer);
+ addOverviewComment(div);
if (configuration.allowTag(HtmlTag.MAIN)) {
htmlTree.addContent(div);
+ body.addContent(htmlTree);
} else {
body.addContent(div);
}
@@ -213,29 +205,17 @@
*/
protected void addOverviewComment(Content htmltree) {
if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
- htmltree.addContent(getMarkerAnchor(SectionName.OVERVIEW_DESCRIPTION));
addInlineComment(configuration.overviewElement, htmltree);
}
}
/**
- * Adds the tag information as provided in the file specified by the
- * "-overview" option on the command line.
+ * Not required for this page.
*
* @param body the documentation tree to which the overview will be added
*/
@Override
- protected void addOverview(Content body) {
- HtmlTree div = new HtmlTree(HtmlTag.DIV);
- div.addStyle(HtmlStyle.contentContainer);
- addOverviewComment(div);
- if (configuration.allowTag(HtmlTag.MAIN)) {
- htmlTree.addContent(div);
- body.addContent(htmlTree);
- } else {
- body.addContent(div);
- }
- }
+ protected void addOverview(Content body) {}
/**
* Adds the top text (from the -top option), the upper
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/PackageIndexWriter.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -134,6 +134,7 @@
Content div = HtmlTree.DIV(HtmlStyle.contentContainer, table);
if (configuration.allowTag(HtmlTag.MAIN)) {
htmlTree.addContent(div);
+ body.addContent(htmlTree);
} else {
body.addContent(div);
}
@@ -176,21 +177,12 @@
protected void addOverviewHeader(Content body) {
addConfigurationTitle(body);
if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
- HtmlTree subTitleDiv = new HtmlTree(HtmlTag.DIV);
- subTitleDiv.addStyle(HtmlStyle.subTitle);
- addSummaryComment(configuration.overviewElement, subTitleDiv);
- Content div = HtmlTree.DIV(HtmlStyle.header, subTitleDiv);
- Content descBody = new ContentBuilder();
- descBody.addContent(contents.seeLabel);
- descBody.addContent(" ");
- Content descPara = HtmlTree.P(descBody);
- Content descLink = getHyperLink(getDocLink(
- SectionName.OVERVIEW_DESCRIPTION),
- contents.descriptionLabel, "", "");
- descPara.addContent(descLink);
- div.addContent(descPara);
+ HtmlTree div = new HtmlTree(HtmlTag.DIV);
+ div.addStyle(HtmlStyle.contentContainer);
+ addOverviewComment(div);
if (configuration.allowTag(HtmlTag.MAIN)) {
htmlTree.addContent(div);
+ body.addContent(htmlTree);
} else {
body.addContent(div);
}
@@ -206,29 +198,17 @@
*/
protected void addOverviewComment(Content htmltree) {
if (!utils.getFullBody(configuration.overviewElement).isEmpty()) {
- htmltree.addContent(getMarkerAnchor(SectionName.OVERVIEW_DESCRIPTION));
addInlineComment(configuration.overviewElement, htmltree);
}
}
/**
- * Adds the tag information as provided in the file specified by the
- * "-overview" option on the command line.
+ * Not required for this page.
*
* @param body the documentation tree to which the overview will be added
*/
@Override
- protected void addOverview(Content body) {
- HtmlTree div = new HtmlTree(HtmlTag.DIV);
- div.addStyle(HtmlStyle.contentContainer);
- addOverviewComment(div);
- if (configuration.allowTag(HtmlTag.MAIN)) {
- htmlTree.addContent(div);
- body.addContent(htmlTree);
- } else {
- body.addContent(div);
- }
- }
+ protected void addOverview(Content body) {}
/**
* Adds the top text (from the -top option), the upper
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -169,11 +169,42 @@
var tresult = new Array();
var mresult = new Array();
var tgresult = new Array();
+ var secondaryresult = new Array();
var displayCount = 0;
var exactMatcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term) + "$", "i");
camelCaseRegexp = ($.ui.autocomplete.escapeRegex(request.term)).split(/(?=[A-Z])/).join("([a-z0-9_$]*?)");
var camelCaseMatcher = new RegExp("^" + camelCaseRegexp);
secondaryMatcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
+
+ // Return the nested innermost name from the specified object
+ function nestedName(e) {
+ return e.l.substring(e.l.lastIndexOf(".") + 1);
+ }
+
+ // Sort array items by short name (as opposed to fully qualified name).
+ // Additionally, sort by the nested type name, when present,
+ // as opposed to top level short name.
+ function sortAndConcatResults(a1, a2) {
+ var sortingKey;
+ var sortArray = function(e1, e2) {
+ var l = sortingKey(e1);
+ var m = sortingKey(e2);
+ if (l < m)
+ return -1;
+ if (l > m)
+ return 1;
+ return 0;
+ };
+ sortingKey = function(e) {
+ return nestedName(e).toUpperCase();
+ };
+ a1.sort(sortArray);
+ a2.sort(sortArray);
+ a1 = a1.concat(a2);
+ a2.length = 0;
+ return a1;
+ }
+
if (moduleSearchIndex) {
var mdleCount = 0;
$.each(moduleSearchIndex, function(index, item) {
@@ -184,10 +215,11 @@
} else if (camelCaseMatcher.test(item.l)) {
result.unshift(item);
} else if (secondaryMatcher.test(item.l)) {
- result.push(item);
+ secondaryresult.push(item);
}
});
displayCount = mdleCount;
+ result = sortAndConcatResults(result, secondaryresult);
}
if (packageSearchIndex) {
var pCount = 0;
@@ -197,48 +229,51 @@
pkg = (item.m)
? (item.m + "/" + item.l)
: item.l;
- if (exactMatcher.test(item.l)) {
+ var s = nestedName(item);
+ if (exactMatcher.test(s)) {
presult.unshift(item);
pCount++;
} else if (camelCaseMatcher.test(pkg)) {
presult.unshift(item);
} else if (secondaryMatcher.test(pkg)) {
- presult.push(item);
+ secondaryresult.push(item);
}
});
- result = result.concat(presult);
+ result = result.concat(sortAndConcatResults(presult, secondaryresult));
displayCount = (pCount > displayCount) ? pCount : displayCount;
}
if (typeSearchIndex) {
var tCount = 0;
$.each(typeSearchIndex, function(index, item) {
item[category] = catTypes;
- if (exactMatcher.test(item.l)) {
+ var s = nestedName(item);
+ if (exactMatcher.test(s)) {
tresult.unshift(item);
tCount++;
- } else if (camelCaseMatcher.test(item.l)) {
+ } else if (camelCaseMatcher.test(s)) {
tresult.unshift(item);
} else if (secondaryMatcher.test(item.p + "." + item.l)) {
- tresult.push(item);
+ secondaryresult.push(item);
}
});
- result = result.concat(tresult);
+ result = result.concat(sortAndConcatResults(tresult, secondaryresult));
displayCount = (tCount > displayCount) ? tCount : displayCount;
}
if (memberSearchIndex) {
var mCount = 0;
$.each(memberSearchIndex, function(index, item) {
item[category] = catMembers;
- if (exactMatcher.test(item.l)) {
+ var s = nestedName(item);
+ if (exactMatcher.test(s)) {
mresult.unshift(item);
mCount++;
- } else if (camelCaseMatcher.test(item.l)) {
+ } else if (camelCaseMatcher.test(s)) {
mresult.unshift(item);
} else if (secondaryMatcher.test(item.c + "." + item.l)) {
- mresult.push(item);
+ secondaryresult.push(item);
}
});
- result = result.concat(mresult);
+ result = result.concat(sortAndConcatResults(mresult, secondaryresult));
displayCount = (mCount > displayCount) ? mCount : displayCount;
}
if (tagSearchIndex) {
@@ -249,10 +284,10 @@
tgresult.unshift(item);
tgCount++;
} else if (secondaryMatcher.test(item.l)) {
- tgresult.push(item);
+ secondaryresult.push(item);
}
});
- result = result.concat(tgresult);
+ result = result.concat(sortAndConcatResults(tgresult, secondaryresult));
displayCount = (tgCount > displayCount) ? tgCount : displayCount;
}
displayCount = (displayCount > 500) ? displayCount : 500;
@@ -312,4 +347,4 @@
}
}
});
-});
\ No newline at end of file
+});
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/ToolOption.java Wed Jul 05 22:52:22 2017 +0200
@@ -181,13 +181,6 @@
}
},
- XMODULE("-Xmodule:", EXTENDED, false) {
- @Override
- public void process(Helper helper, String arg) throws InvalidValueException {
- Option.XMODULE.process(helper.getOptionHelper(), arg);
- }
- },
-
PATCH_MODULE("--patch-module", EXTENDED, true) {
@Override
public void process(Helper helper, String arg) throws InvalidValueException {
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/tool/resources/javadoc.properties Wed Jul 05 22:52:22 2017 +0200
@@ -238,11 +238,6 @@
given module. <other-module> may be ALL-UNNAMED to require\n\
the unnamed module.
-main.opt.Xmodule.arg=\
- <module-name>
-main.opt.Xmodule.desc=\
- Specify a module to which the classes being compiled belong
-
main.opt.patch.module.arg=\
<module>=<file>(:<file>)*
main.opt.patch.module.desc=\
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Module_attribute.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Module_attribute.java Wed Jul 05 22:52:22 2017 +0200
@@ -38,8 +38,8 @@
* deletion without notice.</b>
*/
public class Module_attribute extends Attribute {
- public static final int ACC_TRANSITIVE = 0x10;
- public static final int ACC_STATIC_PHASE = 0x20;
+ public static final int ACC_TRANSITIVE = 0x20;
+ public static final int ACC_STATIC_PHASE = 0x40;
public static final int ACC_OPEN = 0x20;
public static final int ACC_SYNTHETIC = 0x1000;
public static final int ACC_MANDATED = 0x8000;
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsConfiguration.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsConfiguration.java Wed Jul 05 22:52:22 2017 +0200
@@ -118,7 +118,7 @@
}
this.configuration = Configuration.empty()
- .resolveRequires(finder, ModuleFinder.of(), mods);
+ .resolve(finder, ModuleFinder.of(), mods);
this.configuration.modules().stream()
.map(ResolvedModule::reference)
@@ -272,7 +272,7 @@
return nameToModule.values().stream();
} else {
return Configuration.empty()
- .resolveRequires(finder, ModuleFinder.of(), roots)
+ .resolve(finder, ModuleFinder.of(), roots)
.modules().stream()
.map(ResolvedModule::name)
.map(nameToModule::get);
@@ -422,18 +422,13 @@
}
private ModuleDescriptor dropHashes(ModuleDescriptor md) {
- ModuleDescriptor.Builder builder = ModuleDescriptor.module(md.name());
+ ModuleDescriptor.Builder builder = ModuleDescriptor.newModule(md.name());
md.requires().forEach(builder::requires);
md.exports().forEach(builder::exports);
md.opens().forEach(builder::opens);
md.provides().stream().forEach(builder::provides);
md.uses().stream().forEach(builder::uses);
-
- Set<String> concealed = new HashSet<>(md.packages());
- md.exports().stream().map(Exports::source).forEach(concealed::remove);
- md.opens().stream().map(Opens::source).forEach(concealed::remove);
- concealed.forEach(builder::contains);
-
+ builder.packages(md.packages());
return builder.build();
}
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Module.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/Module.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,8 +26,6 @@
package com.sun.tools.jdeps;
import java.lang.module.ModuleDescriptor;
-import java.lang.module.ModuleDescriptor.Exports;
-import java.lang.module.ModuleDescriptor.Opens;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
@@ -55,6 +53,7 @@
private final ModuleDescriptor descriptor;
private final Map<String, Set<String>> exports;
+ private final Map<String, Set<String>> opens;
private final boolean isSystem;
private final URI location;
@@ -63,6 +62,7 @@
this.descriptor = null;
this.location = null;
this.exports = Collections.emptyMap();
+ this.opens = Collections.emptyMap();
this.isSystem = true;
}
@@ -70,12 +70,14 @@
URI location,
ModuleDescriptor descriptor,
Map<String, Set<String>> exports,
+ Map<String, Set<String>> opens,
boolean isSystem,
ClassFileReader reader) {
super(name, location, reader);
this.descriptor = descriptor;
this.location = location;
this.exports = Collections.unmodifiableMap(exports);
+ this.opens = Collections.unmodifiableMap(opens);
this.isSystem = isSystem;
}
@@ -124,35 +126,52 @@
return descriptor.packages();
}
- /**
- * Tests if the package of the given name is exported.
- */
- public boolean isExported(String pn) {
- return exports.containsKey(pn) ? exports.get(pn).isEmpty() : false;
- }
-
public boolean isJDKUnsupported() {
return JDK_UNSUPPORTED.equals(this.name());
}
/**
- * Converts this module to a strict module with the given dependences
+ * Converts this module to a normal module with the given dependences
*
* @throws IllegalArgumentException if this module is not an automatic module
*/
- public Module toStrictModule(Map<String, Boolean> requires) {
+ public Module toNormalModule(Map<String, Boolean> requires) {
if (!isAutomatic()) {
- throw new IllegalArgumentException(name() + " already a strict module");
+ throw new IllegalArgumentException(name() + " not an automatic module");
}
- return new StrictModule(this, requires);
+ return new NormalModule(this, requires);
+ }
+
+ /**
+ * Tests if the package of the given name is exported.
+ */
+ public boolean isExported(String pn) {
+ return exports.containsKey(pn) && exports.get(pn).isEmpty();
}
/**
- * Tests if the package of the given name is qualifiedly exported
- * to the target.
+ * Tests if the package of the given name is exported to the target
+ * in a qualified fashion.
*/
public boolean isExported(String pn, String target) {
- return isExported(pn) || exports.containsKey(pn) && exports.get(pn).contains(target);
+ return isExported(pn)
+ || exports.containsKey(pn) && exports.get(pn).contains(target);
+ }
+
+ /**
+ * Tests if the package of the given name is open.
+ */
+ public boolean isOpen(String pn) {
+ return opens.containsKey(pn) && opens.get(pn).isEmpty();
+ }
+
+ /**
+ * Tests if the package of the given name is open to the target
+ * in a qualified fashion.
+ */
+ public boolean isOpen(String pn, String target) {
+ return isOpen(pn)
+ || opens.containsKey(pn) && opens.get(pn).contains(target);
}
@Override
@@ -193,19 +212,28 @@
}
Map<String, Set<String>> exports = new HashMap<>();
+ Map<String, Set<String>> opens = new HashMap<>();
- descriptor.exports().stream()
- .forEach(exp -> exports.computeIfAbsent(exp.source(), _k -> new HashSet<>())
- .addAll(exp.targets()));
-
- return new Module(name, location, descriptor, exports, isSystem, reader);
+ if (descriptor.isAutomatic()) {
+ // ModuleDescriptor::exports and opens returns an empty set
+ descriptor.packages().forEach(pn -> exports.put(pn, Collections.emptySet()));
+ descriptor.packages().forEach(pn -> opens.put(pn, Collections.emptySet()));
+ } else {
+ descriptor.exports().stream()
+ .forEach(exp -> exports.computeIfAbsent(exp.source(), _k -> new HashSet<>())
+ .addAll(exp.targets()));
+ descriptor.opens().stream()
+ .forEach(exp -> opens.computeIfAbsent(exp.source(), _k -> new HashSet<>())
+ .addAll(exp.targets()));
+ }
+ return new Module(name, location, descriptor, exports, opens, isSystem, reader);
}
}
private static class UnnamedModule extends Module {
private UnnamedModule() {
super("unnamed", null, null,
- Collections.emptyMap(),
+ Collections.emptyMap(), Collections.emptyMap(),
false, null);
}
@@ -230,19 +258,22 @@
}
}
- private static class StrictModule extends Module {
+ /**
+ * A normal module has a module-info.class
+ */
+ private static class NormalModule extends Module {
private final ModuleDescriptor md;
/**
- * Converts the given automatic module to a strict module.
+ * Converts the given automatic module to a normal module.
*
* Replace this module's dependences with the given requires and also
* declare service providers, if specified in META-INF/services configuration file
*/
- private StrictModule(Module m, Map<String, Boolean> requires) {
- super(m.name(), m.location, m.descriptor, m.exports, m.isSystem, m.reader());
+ private NormalModule(Module m, Map<String, Boolean> requires) {
+ super(m.name(), m.location, m.descriptor, m.exports, m.opens, m.isSystem, m.reader());
- ModuleDescriptor.Builder builder = ModuleDescriptor.module(m.name());
+ ModuleDescriptor.Builder builder = ModuleDescriptor.newModule(m.name());
requires.keySet().forEach(mn -> {
if (requires.get(mn).equals(Boolean.TRUE)) {
builder.requires(Set.of(ModuleDescriptor.Requires.Modifier.TRANSITIVE), mn);
@@ -250,16 +281,10 @@
builder.requires(mn);
}
});
- m.descriptor.exports().forEach(e -> builder.exports(e));
- m.descriptor.opens().forEach(o -> builder.opens(o));
- m.descriptor.uses().forEach(s -> builder.uses(s));
- m.descriptor.provides().forEach(p -> builder.provides(p));
-
- Set<String> concealed = new HashSet<>(m.descriptor.packages());
- m.descriptor.exports().stream().map(Exports::source).forEach(concealed::remove);
- m.descriptor.opens().stream().map(Opens::source).forEach(concealed::remove);
- concealed.forEach(builder::contains);
-
+ // exports all packages
+ m.descriptor.packages().forEach(builder::exports);
+ m.descriptor.uses().forEach(builder::uses);
+ m.descriptor.provides().forEach(builder::provides);
this.md = builder.build();
}
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleAnalyzer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleAnalyzer.java Wed Jul 05 22:52:22 2017 +0200
@@ -150,7 +150,7 @@
private ModuleDescriptor descriptor(Set<Module> requiresTransitive,
Set<Module> requires) {
- ModuleDescriptor.Builder builder = ModuleDescriptor.module(root.name());
+ ModuleDescriptor.Builder builder = ModuleDescriptor.newModule(root.name());
if (!root.name().equals(JAVA_BASE))
builder.requires(Set.of(MANDATED), JAVA_BASE);
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleExportsAnalyzer.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleExportsAnalyzer.java Wed Jul 05 22:52:22 2017 +0200
@@ -181,7 +181,7 @@
RootModule(String name) {
super(name);
- ModuleDescriptor.Builder builder = ModuleDescriptor.module(name);
+ ModuleDescriptor.Builder builder = ModuleDescriptor.newModule(name);
this.descriptor = builder.build();
}
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleInfoBuilder.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/ModuleInfoBuilder.java Wed Jul 05 22:52:22 2017 +0200
@@ -43,10 +43,12 @@
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.function.Function;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import static java.util.stream.Collectors.*;
@@ -60,8 +62,8 @@
final Analyzer analyzer;
// an input JAR file (loaded as an automatic module for analysis)
- // maps to an explicit module to generate module-info.java
- final Map<Module, Module> automaticToExplicitModule;
+ // maps to a normal module to generate module-info.java
+ final Map<Module, Module> automaticToNormalModule;
public ModuleInfoBuilder(JdepsConfiguration configuration,
List<String> args,
Path outputdir,
@@ -78,20 +80,20 @@
.map(fn -> Paths.get(fn))
.collect(toList());
- // automatic module to convert to explicit module
- this.automaticToExplicitModule = ModuleFinder.of(paths.toArray(new Path[0]))
+ // automatic module to convert to normal module
+ this.automaticToNormalModule = ModuleFinder.of(paths.toArray(new Path[0]))
.findAll().stream()
.map(configuration::toModule)
.collect(toMap(Function.identity(), Function.identity()));
- Optional<Module> om = automaticToExplicitModule.keySet().stream()
+ Optional<Module> om = automaticToNormalModule.keySet().stream()
.filter(m -> !m.descriptor().isAutomatic())
.findAny();
if (om.isPresent()) {
throw new UncheckedBadArgs(new BadArgs("err.genmoduleinfo.not.jarfile",
om.get().getPathName()));
}
- if (automaticToExplicitModule.isEmpty()) {
+ if (automaticToNormalModule.isEmpty()) {
throw new UncheckedBadArgs(new BadArgs("err.invalid.path", args));
}
}
@@ -115,13 +117,13 @@
Path file = outputdir.resolve(m.name()).resolve("module-info.java");
// computes requires and requires transitive
- Module explicitModule = toExplicitModule(m, apiDeps);
- if (explicitModule != null) {
- automaticToExplicitModule.put(m, explicitModule);
+ Module normalModule = toNormalModule(m, apiDeps);
+ if (normalModule != null) {
+ automaticToNormalModule.put(m, normalModule);
// generate module-info.java
System.out.format("writing to %s%n", file);
- writeModuleInfo(file, explicitModule.descriptor());
+ writeModuleInfo(file, normalModule.descriptor());
} else {
// find missing dependences
System.out.format("Missing dependence: %s not generated%n", file);
@@ -139,7 +141,7 @@
return m == NOT_FOUND || m == REMOVED_JDK_INTERNALS;
}
- private Module toExplicitModule(Module module, Set<Archive> requiresTransitive)
+ private Module toNormalModule(Module module, Set<Archive> requiresTransitive)
throws IOException
{
// done analysis
@@ -159,21 +161,21 @@
.map(Archive::getModule)
.forEach(d -> requires.putIfAbsent(d.name(), Boolean.FALSE));
- return module.toStrictModule(requires);
+ return module.toNormalModule(requires);
}
/**
* Returns the stream of resulting modules
*/
Stream<Module> modules() {
- return automaticToExplicitModule.values().stream();
+ return automaticToNormalModule.values().stream();
}
/**
* Returns the stream of resulting ModuleDescriptors
*/
public Stream<ModuleDescriptor> descriptors() {
- return automaticToExplicitModule.entrySet().stream()
+ return automaticToNormalModule.entrySet().stream()
.map(Map.Entry::getValue)
.map(Module::descriptor);
}
@@ -205,13 +207,14 @@
md.requires().stream()
.filter(req -> !req.name().equals("java.base")) // implicit requires
.sorted(Comparator.comparing(Requires::name))
- .forEach(req -> writer.format(" requires %s;%n", req));
+ .forEach(req -> writer.format(" requires %s;%n",
+ toString(req.modifiers(), req.name())));
if (!open) {
md.exports().stream()
.peek(exp -> {
- if (exp.targets().size() > 0)
- throw new InternalError(md.name() + " qualified exports: " + exp);
+ if (exp.isQualified())
+ throw new InternalError(md.name() + " qualified exports: " + exp);
})
.sorted(Comparator.comparing(Exports::source))
.forEach(exp -> writer.format(" exports %s;%n", exp.source()));
@@ -231,7 +234,16 @@
}
private Set<Module> automaticModules() {
- return automaticToExplicitModule.keySet();
+ return automaticToNormalModule.keySet();
+ }
+
+ /**
+ * Returns a string containing the given set of modifiers and label.
+ */
+ private static <M> String toString(Set<M> mods, String what) {
+ return (Stream.concat(mods.stream().map(e -> e.toString().toLowerCase(Locale.US)),
+ Stream.of(what)))
+ .collect(Collectors.joining(" "));
}
/**
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/debug/InternalDebugControl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/debug/InternalDebugControl.java Wed Jul 05 22:52:22 2017 +0200
@@ -90,6 +90,17 @@
}
/**
+ * Release a JShell instance.
+ *
+ * @param state the JShell instance
+ */
+ public static void release(JShell state) {
+ if (debugMap != null) {
+ debugMap.remove(state);
+ }
+ }
+
+ /**
* Tests if any of the specified debug flags are enabled.
*
* @param state the JShell instance
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Wed Jul 05 22:52:22 2017 +0200
@@ -310,6 +310,8 @@
int firstLine = 0;
PRINT_PAGE: while (true) {
+ in.print(lastNote.replaceAll(".", " ") + ConsoleReader.RESET_LINE);
+
int toPrint = height - 1;
while (toPrint > 0 && firstLine < lines.length) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/Feedback.java Wed Jul 05 22:52:22 2017 +0200
@@ -116,6 +116,13 @@
name, type, value, unresolved, errorLines);
}
+ public String format(String field, FormatCase fc, FormatAction fa, FormatWhen fw,
+ FormatResolve fr, FormatUnresolved fu, FormatErrors fe,
+ String name, String type, String value, String unresolved, List<String> errorLines) {
+ return mode.format(field, fc, fa, fw, fr, fu, fe,
+ name, type, value, unresolved, errorLines);
+ }
+
public String truncateVarValue(String value) {
return mode.truncateVarValue(value);
}
@@ -463,6 +470,14 @@
String format(FormatCase fc, FormatAction fa, FormatWhen fw,
FormatResolve fr, FormatUnresolved fu, FormatErrors fe,
String name, String type, String value, String unresolved, List<String> errorLines) {
+ return format("display", fc, fa, fw, fr, fu, fe,
+ name, type, value, unresolved, errorLines);
+ }
+
+ // Compute the display output given full context and values
+ String format(String field, FormatCase fc, FormatAction fa, FormatWhen fw,
+ FormatResolve fr, FormatUnresolved fu, FormatErrors fe,
+ String name, String type, String value, String unresolved, List<String> errorLines) {
// Convert the context into a bit representation used as selectors for store field formats
long bits = bits(fc, fa, fw, fr, fu, fe);
String fname = name==null? "" : name;
@@ -476,7 +491,7 @@
fname, ftype, fvalue, funresolved, "*cannot-use-errors-here*", el))
.collect(joining());
return String.format(
- format("display", bits),
+ format(field, bits),
fname, ftype, fvalue, funresolved, errors, "*cannot-use-err-here*");
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Jul 05 22:52:22 2017 +0200
@@ -36,12 +36,9 @@
import java.io.PrintStream;
import java.io.Reader;
import java.io.StringReader;
-import java.net.URL;
import java.nio.charset.Charset;
-import java.nio.file.AccessDeniedException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
-import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.text.MessageFormat;
@@ -812,6 +809,12 @@
}
}
+ /**
+ * The entry point into the JShell tool.
+ *
+ * @param args the command-line arguments
+ * @throws Exception catastrophic fatal exception
+ */
public void start(String[] args) throws Exception {
OptionParserCommandLine commandLineArgs = new OptionParserCommandLine();
options = commandLineArgs.parse(args);
@@ -842,30 +845,33 @@
hardmsg("jshell.msg.welcome", version());
}
// Be sure history is always saved so that user code isn't lost
- Runtime.getRuntime().addShutdownHook(new Thread() {
+ Thread shutdownHook = new Thread() {
@Override
public void run() {
replayableHistory.storeHistory(prefs);
}
- });
+ };
+ Runtime.getRuntime().addShutdownHook(shutdownHook);
// execute from user input
try (IOContext in = new ConsoleIOContext(this, cmdin, console)) {
- start(in);
+ while (regenerateOnDeath) {
+ if (!live) {
+ resetState();
+ }
+ run(in);
+ }
+ } finally {
+ replayableHistory.storeHistory(prefs);
+ closeState();
+ try {
+ Runtime.getRuntime().removeShutdownHook(shutdownHook);
+ } catch (Exception ex) {
+ // ignore, this probably caused by VM aready being shutdown
+ // and this is the last act anyhow
+ }
}
}
- }
-
- private void start(IOContext in) {
- try {
- while (regenerateOnDeath) {
- if (!live) {
- resetState();
- }
- run(in);
- }
- } finally {
- closeState();
- }
+ closeState();
}
private EditorSetting configEditor() {
@@ -1019,6 +1025,8 @@
live = false;
JShell oldState = state;
if (oldState != null) {
+ state = null;
+ analysis = null;
oldState.unsubscribe(shutdownSubscription); // No notification
oldState.close();
}
@@ -2006,7 +2014,6 @@
private boolean cmdExit() {
regenerateOnDeath = false;
live = false;
- replayableHistory.storeHistory(prefs);
fluffmsg("jshell.msg.goodbye");
return true;
}
@@ -2614,9 +2621,16 @@
if (stream == null) {
return false;
}
- stream.forEachOrdered(mk
- -> hard(" %s %s", mk.name(), mk.signature())
- );
+ stream.forEachOrdered(meth -> {
+ String sig = meth.signature();
+ int i = sig.lastIndexOf(")") + 1;
+ if (i <= 0) {
+ hard(" %s", meth.name());
+ } else {
+ hard(" %s %s%s", sig.substring(i), meth.name(), sig.substring(0, i));
+ }
+ printSnippetStatus(meth, true);
+ });
return true;
}
@@ -2648,6 +2662,7 @@
break;
}
hard(" %s %s", kind, ck.name());
+ printSnippetStatus(ck, true);
});
return true;
}
@@ -2837,7 +2852,8 @@
return true;
}
} else {
- new DisplayEvent(ste, false, ste.value(), diagnostics).displayDeclarationAndValue();
+ new DisplayEvent(ste, FormatWhen.PRIMARY, ste.value(), diagnostics)
+ .displayDeclarationAndValue();
}
} else {
if (diagnostics.isEmpty()) {
@@ -2851,7 +2867,8 @@
List<Diag> other = errorsOnly(diagnostics);
// display update information
- new DisplayEvent(ste, true, ste.value(), other).displayDeclarationAndValue();
+ new DisplayEvent(ste, FormatWhen.UPDATE, ste.value(), other)
+ .displayDeclarationAndValue();
}
}
return false;
@@ -2889,10 +2906,7 @@
}
//where
void printUnresolvedException(UnresolvedReferenceException ex) {
- DeclarationSnippet corralled = ex.getSnippet();
- List<Diag> otherErrors = errorsOnly(state.diagnostics(corralled).collect(toList()));
- new DisplayEvent(corralled, state.status(corralled), FormatAction.USED, true, null, otherErrors)
- .displayDeclarationAndValue();
+ printSnippetStatus(ex.getSnippet(), false);
}
//where
void printEvalException(EvalException ex) {
@@ -2934,23 +2948,38 @@
return act;
}
+ void printSnippetStatus(DeclarationSnippet sn, boolean resolve) {
+ List<Diag> otherErrors = errorsOnly(state.diagnostics(sn).collect(toList()));
+ new DisplayEvent(sn, state.status(sn), resolve, otherErrors)
+ .displayDeclarationAndValue();
+ }
+
class DisplayEvent {
private final Snippet sn;
private final FormatAction action;
- private final boolean update;
+ private final FormatWhen update;
private final String value;
private final List<String> errorLines;
private final FormatResolve resolution;
private final String unresolved;
private final FormatUnresolved unrcnt;
private final FormatErrors errcnt;
+ private final boolean resolve;
- DisplayEvent(SnippetEvent ste, boolean update, String value, List<Diag> errors) {
- this(ste.snippet(), ste.status(), toAction(ste.status(), ste.previousStatus(), ste.isSignatureChange()), update, value, errors);
+ DisplayEvent(SnippetEvent ste, FormatWhen update, String value, List<Diag> errors) {
+ this(ste.snippet(), ste.status(), false,
+ toAction(ste.status(), ste.previousStatus(), ste.isSignatureChange()),
+ update, value, errors);
}
- DisplayEvent(Snippet sn, Status status, FormatAction action, boolean update, String value, List<Diag> errors) {
+ DisplayEvent(Snippet sn, Status status, boolean resolve, List<Diag> errors) {
+ this(sn, status, resolve, FormatAction.USED, FormatWhen.UPDATE, null, errors);
+ }
+
+ private DisplayEvent(Snippet sn, Status status, boolean resolve,
+ FormatAction action, FormatWhen update, String value, List<Diag> errors) {
this.sn = sn;
+ this.resolve =resolve;
this.action = action;
this.update = update;
this.value = value;
@@ -2958,6 +2987,12 @@
for (Diag d : errors) {
displayDiagnostics(sn.source(), d, errorLines);
}
+ if (resolve) {
+ // resolve needs error lines indented
+ for (int i = 0; i < errorLines.size(); ++i) {
+ errorLines.set(i, " " + errorLines.get(i));
+ }
+ }
long unresolvedCount;
if (sn instanceof DeclarationSnippet && (status == Status.RECOVERABLE_DEFINED || status == Status.RECOVERABLE_NOT_DEFINED)) {
resolution = (status == Status.RECOVERABLE_NOT_DEFINED)
@@ -3012,10 +3047,17 @@
}
private void custom(FormatCase fcase, String name, String type) {
- String display = feedback.format(fcase, action, (update ? FormatWhen.UPDATE : FormatWhen.PRIMARY),
- resolution, unrcnt, errcnt,
- name, type, value, unresolved, errorLines);
- if (interactive()) {
+ if (resolve) {
+ String resolutionErrors = feedback.format("resolve", fcase, action, update,
+ resolution, unrcnt, errcnt,
+ name, type, value, unresolved, errorLines);
+ if (!resolutionErrors.trim().isEmpty()) {
+ hard(" %s", resolutionErrors);
+ }
+ } else if (interactive()) {
+ String display = feedback.format(fcase, action, update,
+ resolution, unrcnt, errcnt,
+ name, type, value, unresolved, errorLines);
cmdout.print(display);
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Wed Jul 05 22:52:22 2017 +0200
@@ -845,12 +845,12 @@
/set format verbose action ' update overwrote' overwrote-update \n\
/set format verbose action ' update dropped' dropped-update \n\
\n\
-/set format verbose until ', however, it cannot be instanciated or its methods invoked until' defined-class-primary \n\
+/set format verbose until ', however, it cannot be instantiated or its methods invoked until' defined-class-primary \n\
/set format verbose until ', however, its methods cannot be invoked until' defined-interface-primary \n\
/set format verbose until ', however, it cannot be used until' defined-enum,annotation-primary \n\
/set format verbose until ', however, it cannot be invoked until' defined-method-primary \n\
/set format verbose until ', however, it cannot be referenced until' notdefined-primary \n\
-/set format verbose until ' which cannot be instanciated or its methods invoked until' defined-class-update \n\
+/set format verbose until ' which cannot be instantiated or its methods invoked until' defined-class-update \n\
/set format verbose until ' whose methods cannot be invoked until' defined-interface-update \n\
/set format verbose until ' which cannot be invoked until' defined-method-update \n\
/set format verbose until ' which cannot be referenced until' notdefined-update \n\
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/DeclarationSnippet.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/DeclarationSnippet.java Wed Jul 05 22:52:22 2017 +0200
@@ -45,6 +45,8 @@
* <code>DeclarationSnippet</code> is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
+ *
+ * @since 9
*/
public abstract class DeclarationSnippet extends PersistentSnippet {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Diag.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Diag.java Wed Jul 05 22:52:22 2017 +0200
@@ -30,6 +30,8 @@
/**
* Diagnostic information for a Snippet.
+ *
+ * @since 9
* @see jdk.jshell.JShell#diagnostics(jdk.jshell.Snippet)
*/
public abstract class Diag {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ErroneousSnippet.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ErroneousSnippet.java Wed Jul 05 22:52:22 2017 +0200
@@ -34,6 +34,8 @@
* <code>ErroneousSnippet</code> is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
+ *
+ * @since 9
*/
public class ErroneousSnippet extends Snippet {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/EvalException.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/EvalException.java Wed Jul 05 22:52:22 2017 +0200
@@ -38,6 +38,8 @@
* the Snippet id and for snippets without a method name (for example an
* expression) <code>StackTraceElement.getMethodName()</code> will be the
* empty string.
+ *
+ * @since 9
*/
@SuppressWarnings("serial") // serialVersionUID intentionally omitted
public class EvalException extends JShellException {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExpressionSnippet.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ExpressionSnippet.java Wed Jul 05 22:52:22 2017 +0200
@@ -34,6 +34,8 @@
* <code>ExpressionSnippet</code> is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
+ *
+ * @since 9
* @jls 15: Expression.
*/
public class ExpressionSnippet extends Snippet {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/ImportSnippet.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/ImportSnippet.java Wed Jul 05 22:52:22 2017 +0200
@@ -34,6 +34,8 @@
* {@code ImportSnippet} is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
+ *
+ * @since 9
* @jls 8.3: importDeclaration.
*/
public class ImportSnippet extends PersistentSnippet {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -44,8 +44,10 @@
import java.util.function.BiFunction;
import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
+import javax.tools.StandardJavaFileManager;
import jdk.internal.jshell.debug.InternalDebugControl;
import jdk.jshell.Snippet.Status;
import jdk.jshell.spi.ExecutionControl.EngineTerminationException;
@@ -77,7 +79,9 @@
* <p>
* This class is not thread safe, except as noted, all access should be through
* a single thread.
+ *
* @author Robert Field
+ * @since 9
*/
public class JShell implements AutoCloseable {
@@ -92,6 +96,7 @@
final BiFunction<Snippet, Integer, String> idGenerator;
final List<String> extraRemoteVMOptions;
final List<String> extraCompilerOptions;
+ final Function<StandardJavaFileManager, StandardJavaFileManager> fileManagerMapping;
private int nextKeyIndex = 1;
@@ -115,6 +120,7 @@
this.idGenerator = b.idGenerator;
this.extraRemoteVMOptions = b.extraRemoteVMOptions;
this.extraCompilerOptions = b.extraCompilerOptions;
+ this.fileManagerMapping = b.fileManagerMapping;
try {
if (b.executionControlProvider != null) {
executionControl = b.executionControlProvider.generate(new ExecutionEnvImpl(),
@@ -171,6 +177,7 @@
ExecutionControlProvider executionControlProvider;
Map<String,String> executionControlParameters;
String executionControlSpec;
+ Function<StandardJavaFileManager, StandardJavaFileManager> fileManagerMapping;
Builder() { }
@@ -365,6 +372,28 @@
}
/**
+ * Configure the {@code FileManager} to be used by compilation and
+ * source analysis.
+ * If not set or passed null, the compiler's standard file manager will
+ * be used (identity mapping).
+ * For use in special applications where the compiler's normal file
+ * handling needs to be overridden. See the file manager APIs for more
+ * information.
+ * The file manager input enables forwarding file managers, if this
+ * is not needed, the incoming file manager can be ignored (constant
+ * function).
+ *
+ * @param mapping a function that given the compiler's standard file
+ * manager, returns a file manager to use
+ * @return the {@code Builder} instance (for use in chained
+ * initialization)
+ */
+ public Builder fileManager(Function<StandardJavaFileManager, StandardJavaFileManager> mapping) {
+ this.fileManagerMapping = mapping;
+ return this;
+ }
+
+ /**
* Builds a JShell state engine. This is the entry-point to all JShell
* functionality. This creates a remote process for execution. It is
* thus important to close the returned instance.
@@ -501,6 +530,7 @@
* @throws IllegalStateException if this {@code JShell} instance is closed.
*/
public void addToClasspath(String path) {
+ checkIfAlive();
// Compiler
taskFactory.addToClasspath(path);
// Runtime
@@ -543,17 +573,7 @@
*/
@Override
public void close() {
- if (!closed) {
- closeDown();
- try {
- executionControl().close();
- } catch (Throwable ex) {
- // don't care about exceptions on close
- }
- if (sourceCodeAnalysis != null) {
- sourceCodeAnalysis.close();
- }
- }
+ closeDown();
}
/**
@@ -826,6 +846,15 @@
} catch (Throwable thr) {
// Don't care about dying exceptions
}
+ try {
+ executionControl().close();
+ } catch (Throwable ex) {
+ // don't care about exceptions on close
+ }
+ if (sourceCodeAnalysis != null) {
+ sourceCodeAnalysis.close();
+ }
+ InternalDebugControl.release(this);
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShellException.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShellException.java Wed Jul 05 22:52:22 2017 +0200
@@ -27,6 +27,8 @@
/**
* The superclass of JShell generated exceptions
+ *
+ * @since 9
*/
@SuppressWarnings("serial") // serialVersionUID intentionally omitted
public class JShellException extends Exception {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MemoryFileManager.java Wed Jul 05 22:52:22 2017 +0200
@@ -30,8 +30,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
import java.net.URI;
import java.nio.file.FileSystems;
import java.nio.file.Files;
@@ -71,10 +69,6 @@
private final JShell proc;
- // Upcoming Jigsaw
- private Method inferModuleNameMethod = null;
- private Method listLocationsForModulesMethod = null;
-
Iterable<? extends Path> getLocationAsPaths(Location loc) {
return this.stdFileManager.getLocationAsPaths(loc);
}
@@ -165,7 +159,9 @@
}
public MemoryFileManager(StandardJavaFileManager standardManager, JShell proc) {
- this.stdFileManager = standardManager;
+ this.stdFileManager = proc.fileManagerMapping != null
+ ? proc.fileManagerMapping.apply(standardManager)
+ : standardManager;
this.proc = proc;
}
@@ -184,43 +180,6 @@
return new SourceMemoryJavaFileObject(origin, name, code);
}
- // Make compatible with Jigsaw
- public String inferModuleName(Location location) {
- try {
- if (inferModuleNameMethod == null) {
- inferModuleNameMethod = JavaFileManager.class.getDeclaredMethod("inferModuleName", Location.class);
- }
- @SuppressWarnings("unchecked")
- String result = (String) inferModuleNameMethod.invoke(stdFileManager, location);
- return result;
- } catch (NoSuchMethodException | SecurityException ex) {
- throw new InternalError("Cannot lookup JavaFileManager method", ex);
- } catch (IllegalAccessException |
- IllegalArgumentException |
- InvocationTargetException ex) {
- throw new InternalError("Cannot invoke JavaFileManager method", ex);
- }
- }
-
- // Make compatible with Jigsaw
- public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
- try {
- if (listLocationsForModulesMethod == null) {
- listLocationsForModulesMethod = JavaFileManager.class.getDeclaredMethod("listLocationsForModules", Location.class);
- }
- @SuppressWarnings("unchecked")
- Iterable<Set<Location>> result = (Iterable<Set<Location>>) listLocationsForModulesMethod.invoke(stdFileManager, location);
- return result;
- } catch (NoSuchMethodException | SecurityException ex) {
- throw new InternalError("Cannot lookup JavaFileManager method", ex);
- } catch (IllegalAccessException |
- IllegalArgumentException |
- InvocationTargetException ex) {
- throw new InternalError("Cannot invoke JavaFileManager method", ex);
- }
- }
-
-
/**
* Returns a class loader for loading plug-ins from the given location. For
* example, to load annotation processors, a compiler will request a class
@@ -580,6 +539,26 @@
", sibling: " + sibling);
}
+ @Override
+ public Location getLocationForModule(Location location, String moduleName) throws IOException {
+ return stdFileManager.getLocationForModule(location, moduleName);
+ }
+
+ @Override
+ public Location getLocationForModule(Location location, JavaFileObject fo, String pkgName) throws IOException {
+ return stdFileManager.getLocationForModule(location, fo, pkgName);
+ }
+
+ @Override
+ public String inferModuleName(Location location) throws IOException {
+ return stdFileManager.inferModuleName(location);
+ }
+
+ @Override
+ public Iterable<Set<Location>> listLocationsForModules(Location location) throws IOException {
+ return stdFileManager.listLocationsForModules(location);
+ }
+
/**
* Flushes any resources opened for output by this file manager
* directly or indirectly. Flushing a closed file manager has no
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/MethodSnippet.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/MethodSnippet.java Wed Jul 05 22:52:22 2017 +0200
@@ -35,6 +35,8 @@
* <code>MethodSnippet</code> is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
+ *
+ * @since 9
* @jls 8.4: MethodDeclaration.
*/
public class MethodSnippet extends DeclarationSnippet {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterImportSnippetWrap.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterImportSnippetWrap.java Wed Jul 05 22:52:22 2017 +0200
@@ -32,7 +32,7 @@
* The outer wrap for a set of snippets wrapped in a generated class
* @author Robert Field
*/
-public class OuterImportSnippetWrap extends OuterWrap {
+class OuterImportSnippetWrap extends OuterWrap {
private final Snippet snippet;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterSnippetsClassWrap.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterSnippetsClassWrap.java Wed Jul 05 22:52:22 2017 +0200
@@ -35,7 +35,7 @@
* The outer wrap for a set of snippets wrapped in a generated class
* @author Robert Field
*/
-public class OuterSnippetsClassWrap extends OuterWrap {
+class OuterSnippetsClassWrap extends OuterWrap {
private final String className;
private final LinkedHashMap<Wrap, Snippet> wrapToSnippet;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrapMap.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/OuterWrapMap.java Wed Jul 05 22:52:22 2017 +0200
@@ -44,7 +44,7 @@
*
* @author Robert Field
*/
-public class OuterWrapMap {
+class OuterWrapMap {
private final JShell state;
private final Map<String,OuterSnippetsClassWrap> classOuters = new HashMap<>();
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java Wed Jul 05 22:52:22 2017 +0200
@@ -34,6 +34,8 @@
* <code>PersistentSnippet</code> is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
+ *
+ * @since 9
*/
public abstract class PersistentSnippet extends Snippet {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java Wed Jul 05 22:52:22 2017 +0200
@@ -39,7 +39,9 @@
* state engine, query {@code JShell} passing the Snippet.
* <p>
* Because it is immutable, {@code Snippet} (and subclasses) is thread-safe.
+ *
* @author Robert Field
+ * @since 9
* @see jdk.jshell.JShell#status
*/
public abstract class Snippet {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java Wed Jul 05 22:52:22 2017 +0200
@@ -38,7 +38,9 @@
* {@code SnippetEvent} is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
+ *
* @author Robert Field
+ * @since 9
*/
public class SnippetEvent {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysis.java Wed Jul 05 22:52:22 2017 +0200
@@ -39,6 +39,7 @@
* etc.
* Also includes completion suggestions, as might be used in tab-completion.
*
+ * @since 9
*/
public abstract class SourceCodeAnalysis {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/StatementSnippet.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/StatementSnippet.java Wed Jul 05 22:52:22 2017 +0200
@@ -34,6 +34,8 @@
* <code>StatementSnippet</code> is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
+ *
+ * @since 9
* @jls 14.5: Statement.
*/
public class StatementSnippet extends Snippet {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypeDeclSnippet.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/TypeDeclSnippet.java Wed Jul 05 22:52:22 2017 +0200
@@ -36,6 +36,8 @@
* <code>TypeDeclSnippet</code> is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
+ *
+ * @since 9
*/
public class TypeDeclSnippet extends DeclarationSnippet {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/UnresolvedReferenceException.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/UnresolvedReferenceException.java Wed Jul 05 22:52:22 2017 +0200
@@ -36,6 +36,8 @@
* the Snippet id and for snippets without a method name (for example an
* expression) <code>StackTraceElement.getName()</code> will be the
* empty string.
+ *
+ * @since 9
*/
@SuppressWarnings("serial") // serialVersionUID intentionally omitted
public class UnresolvedReferenceException extends JShellException {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/VarSnippet.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/VarSnippet.java Wed Jul 05 22:52:22 2017 +0200
@@ -35,6 +35,8 @@
* <code>VarSnippet</code> is immutable: an access to
* any of its methods will always return the same result.
* and thus is thread-safe.
+ *
+ * @since 9
* @jls 8.3: FieldDeclaration.
*/
public class VarSnippet extends DeclarationSnippet {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DirectExecutionControl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/DirectExecutionControl.java Wed Jul 05 22:52:22 2017 +0200
@@ -39,6 +39,7 @@
*
* @author Robert Field
* @author Jan Lahoda
+ * @since 9
*/
public class DirectExecutionControl implements ExecutionControl {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/FailOverExecutionControlProvider.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/FailOverExecutionControlProvider.java Wed Jul 05 22:52:22 2017 +0200
@@ -37,6 +37,8 @@
/**
* Tries other providers in sequence until one works.
+ *
+ * @since 9
*/
public class FailOverExecutionControlProvider implements ExecutionControlProvider{
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiDefaultExecutionControl.java Wed Jul 05 22:52:22 2017 +0200
@@ -33,6 +33,7 @@
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -60,6 +61,7 @@
*
* @author Robert Field
* @author Jan Lahoda
+ * @since 9
*/
public class JdiDefaultExecutionControl extends JdiExecutionControl {
@@ -97,7 +99,8 @@
// Set-up the JDI connection
JdiInitiator jdii = new JdiInitiator(port,
- env.extraRemoteVMOptions(), remoteAgent, isLaunch, host, timeout);
+ env.extraRemoteVMOptions(), remoteAgent, isLaunch, host,
+ timeout, Collections.emptyMap());
VirtualMachine vm = jdii.vm();
Process process = jdii.process();
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiExecutionControl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiExecutionControl.java Wed Jul 05 22:52:22 2017 +0200
@@ -37,7 +37,9 @@
import static java.util.stream.Collectors.toMap;
/**
- * Abstract JDI implementation of {@link jdk.jshell.spi.ExecutionControl}
+ * Abstract JDI implementation of {@link jdk.jshell.spi.ExecutionControl}.
+ *
+ * @since 9
*/
public abstract class JdiExecutionControl extends StreamingExecutionControl implements ExecutionControl {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiExecutionControlProvider.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiExecutionControlProvider.java Wed Jul 05 22:52:22 2017 +0200
@@ -35,7 +35,9 @@
/**
* A provider of remote JDI-controlled execution engines.
+ *
* @author Robert Field
+ * @since 9
*/
public class JdiExecutionControlProvider implements ExecutionControlProvider {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/JdiInitiator.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016,2017 Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -47,6 +47,8 @@
/**
* Sets up a JDI connection, providing the resulting JDI {@link VirtualMachine}
* and the {@link Process} the remote agent is running in.
+ *
+ * @since 9
*/
public class JdiInitiator {
@@ -66,16 +68,20 @@
* Start the remote agent and establish a JDI connection to it.
*
* @param port the socket port for (non-JDI) commands
- * @param remoteVMOptions any user requested VM options
+ * @param remoteVMOptions any user requested VM command-line options
* @param remoteAgent full class name of remote agent to launch
* @param isLaunch does JDI do the launch? That is, LaunchingConnector,
* otherwise we start explicitly and use ListeningConnector
* @param host explicit hostname to use, if null use discovered
* hostname, applies to listening only (!isLaunch)
- * @param timeout the start-up time-out in milliseconds
+ * @param timeout the start-up time-out in milliseconds. If zero or negative,
+ * will not wait thus will timeout immediately if not already started.
+ * @param customConnectorArgs custom arguments passed to the connector.
+ * These are JDI com.sun.jdi.connect.Connector arguments.
*/
public JdiInitiator(int port, List<String> remoteVMOptions, String remoteAgent,
- boolean isLaunch, String host, int timeout) {
+ boolean isLaunch, String host, int timeout,
+ Map<String, String> customConnectorArgs) {
this.remoteAgent = remoteAgent;
this.connectTimeout = (int) (timeout * CONNECT_TIMEOUT_FACTOR);
String connectorName
@@ -96,6 +102,7 @@
argumentName2Value.put("localAddress", host);
}
}
+ argumentName2Value.putAll(customConnectorArgs);
this.connectorArgs = mergeConnectorArgs(connector, argumentName2Value);
this.vm = isLaunch
? launchTarget()
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/LoaderDelegate.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/LoaderDelegate.java Wed Jul 05 22:52:22 2017 +0200
@@ -34,6 +34,8 @@
* This interface specifies the loading specific subset of
* {@link jdk.jshell.spi.ExecutionControl}. For use in encapsulating the
* {@link java.lang.ClassLoader} implementation.
+ *
+ * @since 9
*/
public interface LoaderDelegate {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/LocalExecutionControl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/LocalExecutionControl.java Wed Jul 05 22:52:22 2017 +0200
@@ -33,6 +33,7 @@
* in the same JVM as the JShell-core.
*
* @author Grigory Ptashko
+ * @since 9
*/
public class LocalExecutionControl extends DirectExecutionControl {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/LocalExecutionControlProvider.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/LocalExecutionControlProvider.java Wed Jul 05 22:52:22 2017 +0200
@@ -32,7 +32,9 @@
/**
* A provider of execution engines which run in the same process as JShell.
+ *
* @author Robert Field
+ * @since 9
*/
public class LocalExecutionControlProvider implements ExecutionControlProvider{
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/RemoteExecutionControl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/RemoteExecutionControl.java Wed Jul 05 22:52:22 2017 +0200
@@ -45,6 +45,7 @@
*
* @author Jan Lahoda
* @author Robert Field
+ * @since 9
*/
public class RemoteExecutionControl extends DirectExecutionControl implements ExecutionControl {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/StreamingExecutionControl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/StreamingExecutionControl.java Wed Jul 05 22:52:22 2017 +0200
@@ -37,6 +37,7 @@
* execution takes place.
*
* @author Robert Field
+ * @since 9
*/
public class StreamingExecutionControl implements ExecutionControl {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/Util.java Wed Jul 05 22:52:22 2017 +0200
@@ -53,6 +53,7 @@
*
* @author Jan Lahoda
* @author Robert Field
+ * @since 9
*/
public class Util {
@@ -60,7 +61,7 @@
private static final int TAG_CLOSED = 1;
private static final int TAG_EXCEPTION = 2;
- // never instanciated
+ // never instantiated
private Util() {}
/**
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/package-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/execution/package-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -30,5 +30,7 @@
* Also, provides related communication utilities.
* This package may be used to define alternative execution engines.
* The default JShell execution engine is included.
+ *
+ * @since 9
*/
package jdk.jshell.execution;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -140,6 +140,8 @@
* provide source boundary and completeness analysis to address cases like
* those. <code>SourceCodeAnalysis</code> also provides suggested completions
* of input, as might be used in tab-completion.
+ *
+ * @since 9
*/
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/ExecutionControl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/ExecutionControl.java Wed Jul 05 22:52:22 2017 +0200
@@ -45,6 +45,8 @@
* <p>
* Methods defined in this interface should only be called by the core JShell
* implementation.
+ *
+ * @since 9
*/
public interface ExecutionControl extends AutoCloseable {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/ExecutionControlProvider.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/ExecutionControlProvider.java Wed Jul 05 22:52:22 2017 +0200
@@ -33,7 +33,9 @@
* evaluate Snippets. Alternate execution engines can be created by
* implementing this interface, then configuring JShell with the provider or
* the providers name and parameter specifier.
+ *
* @author Robert Field
+ * @since 9
*/
public interface ExecutionControlProvider {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/ExecutionEnv.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/ExecutionEnv.java Wed Jul 05 22:52:22 2017 +0200
@@ -36,6 +36,7 @@
* This interface is designed to provide the access to core JShell functionality
* needed to implement ExecutionControl.
*
+ * @since 9
* @see ExecutionControl
*/
public interface ExecutionEnv {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/SPIResolutionException.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/SPIResolutionException.java Wed Jul 05 22:52:22 2017 +0200
@@ -33,6 +33,8 @@
* <p>
* This exception is seen by the execution engine, but not seen by
* the end user nor through the JShell API.
+ *
+ * @since 9
*/
@SuppressWarnings("serial") // serialVersionUID intentionally omitted
public class SPIResolutionException extends RuntimeException {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/package-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/spi/package-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -66,6 +66,7 @@
* <li>failover:1(jdi),2(jdi:launch(true),timeout(3000)),3(local)</li>
* </ul>
*
+ * @since 9
* @see jdk.jshell.execution for execution implementation support
*/
package jdk.jshell.spi;
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/tool/JavaShellToolBuilder.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/tool/JavaShellToolBuilder.java Wed Jul 05 22:52:22 2017 +0200
@@ -40,6 +40,8 @@
* configuration methods have sensible defaults which will be used if they are
* not called.. After zero or more calls to configuration methods, the tool is
* launched with a call to {@link #run(java.lang.String...) }.
+ *
+ * @since 9
*/
public interface JavaShellToolBuilder {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/tool/package-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/tool/package-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -47,6 +47,8 @@
* .run("--feedback", "silent", "MyStart");
* }
* </pre>
+ *
+ * @since 9
*/
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/tool/resources/PRINTING.jsh Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/tool/resources/PRINTING.jsh Wed Jul 05 22:52:22 2017 +0200
@@ -17,5 +17,5 @@
void println(char s[]) { System.out.println(s); }
void println(String s) { System.out.println(s); }
void println(Object obj) { System.out.println(obj); }
-void printf(Locale l, String format, Object... args) { System.out.printf(l, format, args); }
+void printf(java.util.Locale l, String format, Object... args) { System.out.printf(l, format, args); }
void printf(String format, Object... args) { System.out.printf(format, args); }
--- a/langtools/src/jdk.jshell/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/src/jdk.jshell/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -51,6 +51,8 @@
* independent, operate at different levels, and do not share functionality or
* definitions.
* </p>
+ *
+ * @since 9
*/
module jdk.jshell {
requires transitive java.compiler;
--- a/langtools/test/ProblemList.txt Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/ProblemList.txt Wed Jul 05 22:52:22 2017 +0200
@@ -36,7 +36,7 @@
#
# jshell
-jdk/jshell/UserJdiUserRemoteTest.java 8173204 linux-all
+jdk/jshell/UserJdiUserRemoteTest.java 8173079 linux-all
jdk/jshell/UserInputTest.java 8169536 generic-all
###########################################################################
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testOverview/TestOverview.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8173302
+ * @summary make sure the overview-summary and module-summary pages don't
+ * don't have the See link, and the overview is copied correctly.
+ * @library ../lib
+ * @modules jdk.javadoc/jdk.javadoc.internal.tool
+ * @build JavadocTester
+ * @run main TestOverview
+ */
+
+public class TestOverview extends JavadocTester {
+
+ public static void main(String... args) throws Exception {
+ TestOverview tester = new TestOverview();
+ tester.runTests();
+ }
+
+ @Test
+ void test1() {
+ javadoc("-d", "out-1",
+ "-doctitle", "Document Title",
+ "-windowtitle", "Window Title",
+ "-overview", testSrc("overview.html"),
+ "-sourcepath", testSrc("src"),
+ "p1", "p2");
+ checkExit(Exit.OK);
+ checkOutput("overview-summary.html", true,
+ "<div class=\"header\">\n"
+ + "<h1 class=\"title\">Document Title</h1>\n"
+ + "</div>\n"
+ + "<div class=\"contentContainer\">\n"
+ + "<div class=\"block\">This is line1. This is line 2.</div>\n"
+ + "</div>\n"
+ + "<div class=\"contentContainer\">"
+ );
+ }
+
+ @Test
+ void test2() {
+ javadoc("-d", "out-2",
+ "-doctitle", "Document Title",
+ "-windowtitle", "Window Title",
+ "-overview", testSrc("overview.html"),
+ "-sourcepath", testSrc("msrc"),
+ "p1", "p2");
+ checkExit(Exit.OK);
+ checkOutput("overview-summary.html", true,
+ "<div class=\"header\">\n"
+ + "<h1 class=\"title\">Document Title</h1>\n"
+ + "</div>\n"
+ + "<div class=\"contentContainer\">\n"
+ + "<div class=\"block\">This is line1. This is line 2.</div>\n"
+ + "</div>\n"
+ + "<div class=\"contentContainer\">"
+ );
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testOverview/msrc/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 module acme.
+ */
+module acme {
+ exports p1;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testOverview/msrc/p1/C.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p1;
+
+public class C {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testOverview/msrc/p2/C2.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p2;
+
+public class C2 {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testOverview/overview.html Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,6 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html>
+<body bgcolor="white">
+ This is line1. This is line 2.
+</body>
+</html>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testOverview/src/p1/C.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p1;
+
+public class C {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testOverview/src/p2/C2.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p2;
+
+public class C2 {}
--- a/langtools/test/jdk/javadoc/doclet/testSearch/TestSearch.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/jdk/javadoc/doclet/testSearch/TestSearch.java Wed Jul 05 22:52:22 2017 +0200
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8141492 8071982 8141636 8147890 8166175
+ * @bug 8141492 8071982 8141636 8147890 8166175 8168965
* @summary Test the search feature of javadoc.
* @author bpatel
* @library ../lib
@@ -486,6 +486,9 @@
checkOutput("search.js", true,
"camelCaseRegexp = ($.ui.autocomplete.escapeRegex(request.term)).split(/(?=[A-Z])/).join(\"([a-z0-9_$]*?)\");",
"var camelCaseMatcher = new RegExp(\"^\" + camelCaseRegexp);",
- "camelCaseMatcher.test(item.l)");
+ "camelCaseMatcher.test(item.l)",
+ "var secondaryresult = new Array();",
+ "function nestedName(e) {",
+ "function sortAndConcatResults(a1, a2) {");
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/jdk/jshell/FileManagerTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,114 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8173845
+ * @summary test custom file managers
+ * @build KullaTesting TestingInputStream
+ * @run testng FileManagerTest
+ */
+
+
+import java.io.File;
+import java.io.IOException;
+
+import java.util.Set;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.StandardJavaFileManager;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class FileManagerTest extends KullaTesting {
+
+ boolean encountered;
+
+ class MyFileManager extends ForwardingJavaFileManager<StandardJavaFileManager>
+ implements StandardJavaFileManager {
+
+ protected MyFileManager(StandardJavaFileManager fileManager) {
+ super(fileManager);
+ }
+
+ @Override
+ public Iterable<JavaFileObject> list(Location location,
+ String packageName,
+ Set<Kind> kinds,
+ boolean recurse)
+ throws IOException {
+ //System.out.printf("list(%s, %s, %s, %b)\n",
+ // location, packageName, kinds, recurse);
+ if (packageName.equals("java.lang.reflect")) {
+ encountered = true;
+ }
+ return fileManager.list(location, packageName, kinds, recurse);
+ }
+
+ @Override
+ public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
+ return fileManager.getJavaFileObjectsFromFiles(files);
+ }
+
+ @Override
+ public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
+ return fileManager.getJavaFileObjects(files);
+ }
+
+ @Override
+ public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
+ return fileManager.getJavaFileObjectsFromStrings(names);
+ }
+
+ @Override
+ public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
+ return fileManager.getJavaFileObjects(names);
+ }
+
+ @Override
+ public void setLocation(Location location, Iterable<? extends File> files) throws IOException {
+ fileManager.setLocation(location, files);
+ }
+
+ @Override
+ public Iterable<? extends File> getLocation(Location location) {
+ return fileManager.getLocation(location);
+ }
+
+ }
+
+ @BeforeMethod
+ @Override
+ public void setUp() {
+ setUp(b -> b.fileManager(fm -> new MyFileManager(fm)));
+ }
+
+ public void testSnippetMemberAssignment() {
+ assertEval("java.lang.reflect.Array.get(new String[1], 0) == null");
+ assertTrue(encountered, "java.lang.reflect not encountered");
+ }
+
+}
--- a/langtools/test/jdk/jshell/JavadocTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/jdk/jshell/JavadocTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8131019 8169561
+ * @bug 8131019 8169561 8174245
* @summary Test Javadoc
* @library /tools/lib
* @modules jdk.compiler/com.sun.tools.javac.api
@@ -107,4 +107,51 @@
addToClasspath(compiler.getClassDir());
}
+ public void testCollectionsMin() {
+ prepareJavaUtilZip();
+ assertJavadoc("java.util.Collections.min(|",
+ "T java.util.Collections.<T>min(java.util.Collection<? extends T> coll, java.util.Comparator<? super T> comp)\n" +
+ " min comparator\n",
+ "T java.util.Collections.<T extends Object & Comparable<? super T>>min(java.util.Collection<? extends T> coll)\n" +
+ " min comparable\n");
+ }
+
+ private void prepareJavaUtilZip() {
+ String clazz =
+ "package java.util;\n" +
+ "/**Top level." +
+ " */\n" +
+ "public class Collections {\n" +
+ " /**\n" +
+ " * min comparable\n" +
+ " */\n" +
+ " public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {" +
+ " return null;\n" +
+ " }\n" +
+ " /**\n" +
+ " * min comparator\n" +
+ " */\n" +
+ " public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {\n" +
+ " return null;\n" +
+ " }\n" +
+ "}\n";
+
+ Path srcZip = Paths.get("src.zip");
+
+ try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(srcZip))) {
+ out.putNextEntry(new JarEntry("java/util/Collections.java"));
+ out.write(clazz.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);
+ }
+ }
+
}
--- a/langtools/test/jdk/jshell/KullaTesting.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/jdk/jshell/KullaTesting.java Wed Jul 05 22:52:22 2017 +0200
@@ -213,7 +213,7 @@
ModuleFinder finder = ModuleFinder.of(modPath);
Layer parent = Layer.boot();
Configuration cf = parent.configuration()
- .resolveRequires(finder, ModuleFinder.of(), Set.of(moduleName));
+ .resolve(finder, ModuleFinder.of(), Set.of(moduleName));
ClassLoader scl = ClassLoader.getSystemClassLoader();
Layer layer = parent.defineModulesWithOneLoader(cf, scl);
ClassLoader loader = layer.findLoader(moduleName);
--- a/langtools/test/jdk/jshell/MyExecutionControl.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/jdk/jshell/MyExecutionControl.java Wed Jul 05 22:52:22 2017 +0200
@@ -29,6 +29,7 @@
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -78,7 +79,7 @@
+ System.getProperty("path.separator")
+ System.getProperty("user.dir"));
JdiInitiator jdii = new JdiInitiator(port,
- opts, REMOTE_AGENT, true, null, TIMEOUT);
+ opts, REMOTE_AGENT, true, null, TIMEOUT, Collections.emptyMap());
VirtualMachine vm = jdii.vm();
Process process = jdii.process();
--- a/langtools/test/jdk/jshell/ReplToolTesting.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/jdk/jshell/ReplToolTesting.java Wed Jul 05 22:52:22 2017 +0200
@@ -72,27 +72,27 @@
final static List<String> START_UP_CMD_METHOD = Stream.<String>of()
.collect(toList());
final static List<String> PRINTING_CMD_METHOD = Stream.of(
- "| print (boolean)void",
- "| print (char)void",
- "| print (int)void",
- "| print (long)void",
- "| print (float)void",
- "| print (double)void",
- "| print (char s[])void",
- "| print (String)void",
- "| print (Object)void",
- "| println ()void",
- "| println (boolean)void",
- "| println (char)void",
- "| println (int)void",
- "| println (long)void",
- "| println (float)void",
- "| println (double)void",
- "| println (char s[])void",
- "| println (String)void",
- "| println (Object)void",
- "| printf (Locale,String,Object...)void",
- "| printf (String,Object...)void")
+ "| void print(boolean)",
+ "| void print(char)",
+ "| void print(int)",
+ "| void print(long)",
+ "| void print(float)",
+ "| void print(double)",
+ "| void print(char s[])",
+ "| void print(String)",
+ "| void print(Object)",
+ "| void println()",
+ "| void println(boolean)",
+ "| void println(char)",
+ "| void println(int)",
+ "| void println(long)",
+ "| void println(float)",
+ "| void println(double)",
+ "| void println(char s[])",
+ "| void println(String)",
+ "| void println(Object)",
+ "| void printf(java.util.Locale,String,Object...)",
+ "| void printf(String,Object...)")
.collect(toList());
final static List<String> START_UP = Collections.unmodifiableList(
Stream.concat(START_UP_IMPORTS.stream(), START_UP_METHODS.stream())
@@ -152,6 +152,7 @@
return s -> {
List<String> lines = Stream.of(s.split("\n"))
.filter(l -> !l.isEmpty())
+ .filter(l -> !l.startsWith("| ")) // error/unresolved info
.collect(Collectors.toList());
assertEquals(lines.size(), set.size(), message + " : expected: " + set.keySet() + "\ngot:\n" + lines);
for (String line : lines) {
@@ -664,7 +665,12 @@
@Override
public String toString() {
- return String.format("%s %s", name, signature);
+ int i = signature.lastIndexOf(")") + 1;
+ if (i <= 0) {
+ return String.format("%s", name);
+ } else {
+ return String.format("%s %s%s", signature.substring(i), name, signature.substring(0, i));
+ }
}
}
--- a/langtools/test/jdk/jshell/ToolReloadTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/jdk/jshell/ToolReloadTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -92,8 +92,8 @@
test(false, new String[]{"--no-startup"},
a -> assertVariable(a, "int", "a"),
a -> dropVariable(a, "/dr 1", "int a = 0", "| dropped variable a"),
- a -> assertMethod(a, "int b() { return 0; }", "()I", "b"),
- a -> dropMethod(a, "/drop b", "b ()I", "| dropped method b()"),
+ a -> assertMethod(a, "int b() { return 0; }", "()int", "b"),
+ a -> dropMethod(a, "/drop b", "int b()", "| dropped method b()"),
a -> assertClass(a, "class A {}", "class", "A"),
a -> dropClass(a, "/dr A", "class A", "| dropped class A"),
a -> assertCommand(a, "/reload",
@@ -115,8 +115,8 @@
test(false, new String[]{"--no-startup"},
a -> assertVariable(a, "int", "a"),
a -> dropVariable(a, "/dr 1", "int a = 0", "| dropped variable a"),
- a -> assertMethod(a, "int b() { return 0; }", "()I", "b"),
- a -> dropMethod(a, "/drop b", "b ()I", "| dropped method b()"),
+ a -> assertMethod(a, "int b() { return 0; }", "()int", "b"),
+ a -> dropMethod(a, "/drop b", "int b()", "| dropped method b()"),
a -> assertClass(a, "class A {}", "class", "A"),
a -> dropClass(a, "/dr A", "class A", "| dropped class A"),
a -> assertCommand(a, "/reload -quiet",
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848
+ * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128 8154513 8170015 8170368 8172102 8172103 8165405 8173073 8173848 8174041 8173916 8174028 8174262
* @summary Simple jshell tool tests
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -238,8 +238,8 @@
test(false, new String[]{"--no-startup"},
a -> assertVariable(a, "int", "a"),
a -> dropVariable(a, "/drop 1", "int a = 0", "| dropped variable a"),
- a -> assertMethod(a, "int b() { return 0; }", "()I", "b"),
- a -> dropMethod(a, "/drop 2", "b ()I", "| dropped method b()"),
+ a -> assertMethod(a, "int b() { return 0; }", "()int", "b"),
+ a -> dropMethod(a, "/drop 2", "int b()", "| dropped method b()"),
a -> assertClass(a, "class A {}", "class", "A"),
a -> dropClass(a, "/drop 3", "class A", "| dropped class A"),
a -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
@@ -255,8 +255,8 @@
test(false, new String[]{"--no-startup"},
a -> assertVariable(a, "int", "a"),
a -> dropVariable(a, "/drop a", "int a = 0", "| dropped variable a"),
- a -> assertMethod(a, "int b() { return 0; }", "()I", "b"),
- a -> dropMethod(a, "/drop b", "b ()I", "| dropped method b()"),
+ a -> assertMethod(a, "int b() { return 0; }", "()int", "b"),
+ a -> dropMethod(a, "/drop b", "int b()", "| dropped method b()"),
a -> assertClass(a, "class A {}", "class", "A"),
a -> dropClass(a, "/drop A", "class A", "| dropped class A"),
a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
@@ -466,10 +466,50 @@
a -> assertCommandCheckOutput(a, "/methods print println printf",
s -> checkLineToList(s, printingMethodList)),
a -> assertCommandOutputStartsWith(a, "/methods g",
- "| g ()void"),
+ "| void g()"),
a -> assertCommandOutputStartsWith(a, "/methods f",
- "| f ()int\n" +
- "| f (int)void")
+ "| int f()\n" +
+ "| void f(int)")
+ );
+ }
+
+ @Test
+ public void testMethodsWithErrors() {
+ test(new String[]{"--no-startup"},
+ a -> assertCommand(a, "double m(int x) { return x; }",
+ "| created method m(int)"),
+ a -> assertCommand(a, "GARBAGE junk() { return TRASH; }",
+ "| created method junk(), however, it cannot be referenced until class GARBAGE, and variable TRASH are declared"),
+ a -> assertCommand(a, "int w = 5;",
+ "w ==> 5"),
+ a -> assertCommand(a, "int tyer() { return w; }",
+ "| created method tyer()"),
+ a -> assertCommand(a, "String w = \"hi\";",
+ "w ==> \"hi\""),
+ a -> assertCommand(a, "/methods",
+ "| double m(int)\n" +
+ "| GARBAGE junk()\n" +
+ "| which cannot be referenced until class GARBAGE, and variable TRASH are declared\n" +
+ "| int tyer()\n" +
+ "| which cannot be invoked until this error is corrected: \n" +
+ "| incompatible types: java.lang.String cannot be converted to int\n" +
+ "| int tyer() { return w; }\n" +
+ "| ^\n")
+ );
+ }
+
+ @Test
+ public void testTypesWithErrors() {
+ test(new String[]{"--no-startup"},
+ a -> assertCommand(a, "class C extends NONE { int x; }",
+ "| created class C, however, it cannot be referenced until class NONE is declared"),
+ a -> assertCommand(a, "class D { void m() { System.out.println(nada); } }",
+ "| created class D, however, it cannot be instantiated or its methods invoked until variable nada is declared"),
+ a -> assertCommand(a, "/types",
+ "| class C\n" +
+ "| which cannot be referenced until class NONE is declared\n" +
+ "| class D\n" +
+ "| which cannot be instantiated or its methods invoked until variable nada is declared\n")
);
}
--- a/langtools/test/tools/javac/6627362/T6627362.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/6627362/T6627362.java Wed Jul 05 22:52:22 2017 +0200
@@ -68,9 +68,9 @@
// compile and disassemble E.java, using modified Object.java,
// check for reference to System.arraycopy
File x = new File(testSrc, "x");
- String[] jcArgs = { "-d", ".", "-Xmodule:java.base",
+ String[] jcArgs = { "-d", ".", "--patch-module", "java.base=" + x.getAbsolutePath(),
new File(x, "E.java").getPath(),
- new File(x, "Object.java").getPath()};
+ new File(new File(new File(x, "java"), "lang"), "Object.java").getPath()};
compile(jcArgs);
String[] jpArgs = { "-classpath", ".", "-c", "E" };
--- a/langtools/test/tools/javac/6627362/x/Object.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
- * 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 java.lang;
-
-/*
- * Object, without clone()
- */
-public class Object {
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/6627362/x/java/lang/Object.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
+ * 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 java.lang;
+
+/*
+ * Object, without clone()
+ */
+public class Object {
+}
--- a/langtools/test/tools/javac/T4093617/T4093617.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/T4093617/T4093617.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,6 @@
* @bug 4093617
* @summary Object has no superclass
* @author Peter von der Ah\u00e9
- * @compile/module=java.base/fail/ref=T4093617.out -XDrawDiagnostics Object.java
+ * @compile/module=java.base/fail/ref=T4093617.out -XDrawDiagnostics java/lang/Object.java
*/
--- a/langtools/test/tools/javac/T4093617/java.base/Object.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-/*
- * /nodynamiccopyright/
- * See ../T4093617.java
- */
-
-package java.lang;
-
-class Object {
- Object() { super(); }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T4093617/java.base/java/lang/Object.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,10 @@
+/*
+ * /nodynamiccopyright/
+ * See ../T4093617.java
+ */
+
+package java.lang;
+
+class Object {
+ Object() { super(); }
+}
--- a/langtools/test/tools/javac/T6234077.out Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/T6234077.out Wed Jul 05 22:52:22 2017 +0200
@@ -1,2 +1,2 @@
-T6234077.java:7:8: compiler.err.class.public.should.be.in.file: Foo
+T6234077.java:7:8: compiler.err.class.public.should.be.in.file: kindname.class, Foo
1 error
--- a/langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/T8003967/DetectMutableStaticFields.java Wed Jul 05 22:52:22 2017 +0200
@@ -107,7 +107,7 @@
// by reflective lookup, to avoid explicit references that are not available
// when running javac on JDK 8.
ignore("com/sun/tools/javac/util/JDK9Wrappers$Configuration",
- "resolveRequiresAndUsesMethod", "configurationClass");
+ "resolveAndBindMethod", "configurationClass");
ignore("com/sun/tools/javac/util/JDK9Wrappers$Layer",
"bootMethod", "defineModulesWithOneLoaderMethod", "configurationMethod", "layerClass");
ignore("com/sun/tools/javac/util/JDK9Wrappers$Module",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8173955/MessageForClassTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,8 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8174027
+ * @summary error message should adapt to the corresponding top level element
+ * @compile/fail/ref=MessageForClassTest.out -XDrawDiagnostics MessageForClassTest.java
+ */
+
+public class MessageForClassTest_ {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8173955/MessageForClassTest.out Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,2 @@
+MessageForClassTest.java:8:8: compiler.err.class.public.should.be.in.file: kindname.class, MessageForClassTest_
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8173955/MessageForEnumTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,8 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8174027
+ * @summary error message should adapt to the corresponding top level element
+ * @compile/fail/ref=MessageForEnumTest.out -XDrawDiagnostics MessageForEnumTest.java
+ */
+
+public enum MessageForEnumTest_ {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8173955/MessageForEnumTest.out Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,2 @@
+MessageForEnumTest.java:8:8: compiler.err.class.public.should.be.in.file: kindname.enum, MessageForEnumTest_
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8173955/MessageForInterfaceTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,8 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8174027
+ * @summary error message should adapt to the corresponding top level element
+ * @compile/fail/ref=MessageForInterfaceTest.out -XDrawDiagnostics MessageForInterfaceTest.java
+ */
+
+public interface MessageForInterfaceTest_ {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/T8173955/MessageForInterfaceTest.out Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,2 @@
+MessageForInterfaceTest.java:8:8: compiler.err.class.public.should.be.in.file: kindname.interface, MessageForInterfaceTest_
+1 error
--- a/langtools/test/tools/javac/diags/Example.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/diags/Example.java Wed Jul 05 22:52:22 2017 +0200
@@ -63,6 +63,7 @@
procFiles = new ArrayList<File>();
srcPathFiles = new ArrayList<File>();
moduleSourcePathFiles = new ArrayList<File>();
+ patchModulePathFiles = new ArrayList<File>();
modulePathFiles = new ArrayList<File>();
classPathFiles = new ArrayList<File>();
additionalFiles = new ArrayList<File>();
@@ -88,6 +89,9 @@
} else if (files == srcFiles && c.getName().equals("modulesourcepath")) {
moduleSourcePathDir = c;
findFiles(c, moduleSourcePathFiles);
+ } else if (files == srcFiles && c.getName().equals("patchmodule")) {
+ patchModulePathDir = c;
+ findFiles(c, patchModulePathFiles);
} else if (files == srcFiles && c.getName().equals("additional")) {
additionalFilesDir = c;
findFiles(c, additionalFiles);
@@ -272,6 +276,16 @@
files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
}
+ if (patchModulePathDir != null) {
+ for (File mod : patchModulePathDir.listFiles()) {
+ opts.add("--patch-module");
+ opts.add(mod.getName() + "=" + mod.getPath());
+ }
+ files = new ArrayList<>();
+ files.addAll(patchModulePathFiles);
+ files.addAll(nonEmptySrcFiles); // srcFiles containing declarations
+ }
+
if (additionalFiles.size() > 0) {
List<String> sOpts = Arrays.asList("-d", classesDir.getPath());
new Jsr199Compiler(verbose).run(null, null, false, sOpts, additionalFiles);
@@ -343,9 +357,11 @@
List<File> procFiles;
File srcPathDir;
File moduleSourcePathDir;
+ File patchModulePathDir;
File additionalFilesDir;
List<File> srcPathFiles;
List<File> moduleSourcePathFiles;
+ List<File> patchModulePathFiles;
List<File> modulePathFiles;
List<File> classPathFiles;
List<File> additionalFiles;
--- a/langtools/test/tools/javac/diags/examples.not-yet.txt Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/diags/examples.not-yet.txt Wed Jul 05 22:52:22 2017 +0200
@@ -5,6 +5,7 @@
compiler.err.cant.read.file # (apt.JavaCompiler?)
compiler.err.cant.select.static.class.from.param.type
compiler.err.dc.unterminated.string # cannot happen
+compiler.err.file.patched.and.msp # needs the same dir on --module-source-path and --patch-module
compiler.err.illegal.char.for.encoding
compiler.err.invalid.repeatable.annotation # should not happen
compiler.err.invalid.repeatable.annotation.invalid.value # "can't" happen
--- a/langtools/test/tools/javac/diags/examples/IllegalArgumentForOption/IllegalArgumentForOption.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/diags/examples/IllegalArgumentForOption/IllegalArgumentForOption.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,7 +22,7 @@
*/
// key: compiler.err.illegal.argument.for.option
-// options: --module-path doesNotExist
+// options: --module-source-path=abc*def
// run: simple
class X {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleClassoutput/ModuleInfoWithPatchedModuleClassoutput.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+// key: compiler.err.module-info.with.patched.module.classoutput
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleClassoutput/additional/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module mod {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleClassoutput/patchmodule/java.compiler/javax/lang/model/element/Extra.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 javax.lang.model.element;
+
+public interface Extra {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleSourcepath/ModuleInfoWithPatchedModule.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+// key: compiler.err.module-info.with.patched.module.sourcepath
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleSourcepath/patchmodule/java.compiler/javax/lang/model/element/Extra.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 javax.lang.model.element;
+
+public interface Extra {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/ModuleInfoWithPatchedModuleSourcepath/patchmodule/java.compiler/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+module java.compiler {}
--- a/langtools/test/tools/javac/diags/examples/ModuleInfoWithXModuleSourcePath/Extra.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +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.
- *
- * 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.
- */
-
-// key: compiler.err.module-info.with.xmodule.sourcepath
-// options: -Xmodule:java.compiler
-
-package javax.lang.model.element;
-
-public interface Extra {}
--- a/langtools/test/tools/javac/diags/examples/ModuleInfoWithXModuleSourcePath/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-module java.compiler {}
--- a/langtools/test/tools/javac/diags/examples/ModuleInfoWithXmoduleClasspath/ModuleInfoWithXmoduleClasspath.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +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.
- *
- * 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.
- */
-
-// key: compiler.err.module-info.with.xmodule.classpath
-// options: -Xmodule:java.compiler
-
-package javax.lang.model.element;
-
-public interface ModuleInfoWithXModuleClasspath {}
--- a/langtools/test/tools/javac/diags/examples/ModuleInfoWithXmoduleClasspath/additional/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +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.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-module mod {}
--- a/langtools/test/tools/javac/diags/examples/NoSuperclass.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2010, 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.
- */
-
-// key: compiler.err.no.superclass
-// options: -Xmodule:java.base
-
-package java.lang;
-
-class Object {
- public Object() {
- super();
- }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NoSuperclass/NoSuperclass.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+// key: compiler.err.no.superclass
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/NoSuperclass/patchmodule/java.base/java/lang/Object.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2010, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 java.lang;
+
+class Object {
+ public Object() {
+ super();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TooManyPatchedModules/TooManyPatchedModules.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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.
+ */
+
+// key: compiler.err.too.many.patched.modules
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TooManyPatchedModules/patchmodule/java.compiler/p/C.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p;
+
+class C {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/diags/examples/TooManyPatchedModules/patchmodule/jdk.compiler/p/C.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 p;
+
+class C {}
--- a/langtools/test/tools/javac/diags/examples/XModuleWithModulePath/XModuleWithModulePath.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +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.
- *
- * 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.
- */
-
-// key: compiler.err.xmodule.no.module.sourcepath
-// options: -Xmodule:java.compiler --module-source-path src
-
-class XModuleWithModulePath {}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/doclint/NPEDuplicateClassNamesTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8174073
+ * @summary NPE caused by link reference to class
+ * @modules jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.main
+ * @library /tools/lib
+ * @build toolbox.JavacTask toolbox.TestRunner toolbox.ToolBox
+ * @run main NPEDuplicateClassNamesTest
+ */
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+import toolbox.JavacTask;
+import toolbox.Task;
+import toolbox.TestRunner;
+import toolbox.ToolBox;
+
+public class NPEDuplicateClassNamesTest extends TestRunner {
+
+ public static void main(String... args) throws Exception {
+ NPEDuplicateClassNamesTest t = new NPEDuplicateClassNamesTest();
+ t.runTests();
+ }
+
+ private final ToolBox tb = new ToolBox();
+ private final String class1 =
+ "package com;\n" +
+ "/***/\n" +
+ "public class MyClass {}";
+ private final String class2 =
+ "package com;\n" +
+ "/**\n" +
+ " * The following link tag causes a NullPointerException: {@link Requirements}. \n" +
+ " */\n" +
+ "public class MyClass {}";
+
+ NPEDuplicateClassNamesTest() throws IOException {
+ super(System.err);
+ }
+
+ @Test
+ public void testDuplicateClassNames() throws IOException {
+ Path src = Paths.get("src");
+ Path one = src.resolve("one");
+ Path two = src.resolve("two");
+ Path classes = Paths.get("classes");
+ Files.createDirectories(classes);
+ tb.writeJavaFiles(one, class1);
+ tb.writeJavaFiles(two, class2);
+
+ List<String> expected = Arrays.asList(
+ "MyClass.java:5:8: compiler.err.duplicate.class: com.MyClass",
+ "MyClass.java:3:65: compiler.err.proc.messager: reference not found",
+ "2 errors");
+ List<String> output = new JavacTask(tb)
+ .outdir(classes)
+ .options("-XDrawDiagnostics", "-Xdoclint:all", "-XDdev")
+ .files(tb.findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ if (!Objects.equals(output, expected)) {
+ throw new IllegalStateException("incorrect output; actual=" + output + "; expected=" + expected);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8174249/T8174249a.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
+ * @bug 8174249
+ * @summary Regression in generic method unchecked calls
+ * @compile T8174249a.java
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+class T8174249a {
+ static <T> T foo(Class<T> c, Collection<? super T> baz) {
+return null;
+ }
+
+ static void bar(String c) { }
+
+ void test() {
+ // this works
+ bar(foo(String.class, new ArrayList<String>()));
+
+ // this works with a warning
+ String s = foo(String.class, new ArrayList());
+ bar(s);
+
+ // this causes an error on JDK9 but should work
+ bar(foo(String.class, new ArrayList()));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8174249/T8174249b.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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
+ * @bug 8174249
+ * @summary Regression in generic method unchecked calls
+ * @compile T8174249b.java
+ */
+
+import java.util.*;
+
+class T8174249b {
+
+ static void cs(Collection<String> cs) {}
+
+ void test1(Collection c) {
+ cs(rawCollection((Class)null));
+ Collection<String> cs1 = rawCollection((Class)null);
+ }
+
+ void test2(Collection c) {
+ cs(rawCollection2((Class)null));
+ Collection<String> cs2 = rawCollection2((Class)null);
+ }
+
+ void test3(Collection c) {
+ cs(rawCollection3((Class)null));
+ Collection<String> cs3 = rawCollection2((Class)null);
+ }
+
+ Collection<Integer> rawCollection(Class<String> cs) { return null; }
+
+ <Z> Collection<Integer> rawCollection2(Class<Z> cs) { return null; }
+
+ <Z> Collection<Z> rawCollection3(Class<Z> cs) { return null; }
+}
--- a/langtools/test/tools/javac/lib/combo/ComboTask.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/lib/combo/ComboTask.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,9 +25,9 @@
import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.util.JavacTask;
-import com.sun.source.util.TaskEvent.Kind;
import com.sun.source.util.TaskListener;
import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.List;
import combo.ComboParameter.Resolver;
@@ -36,11 +36,18 @@
import javax.tools.DiagnosticListener;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
+
import java.io.IOException;
import java.io.Writer;
import java.net.URI;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.HashMap;
import java.util.Map;
+import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
@@ -184,6 +191,28 @@
}
/**
+ * Parse, analyze, perform code generation for the sources associated with this task and finally
+ * executes them
+ */
+ public <Z> Optional<Z> execute(Function<ExecutionTask, Z> executionFunc) throws IOException {
+ Result<Iterable<? extends JavaFileObject>> generationResult = generate();
+ Iterable<? extends JavaFileObject> jfoIterable = generationResult.get();
+ if (generationResult.hasErrors()) {
+ // we have nothing else to do
+ return Optional.empty();
+ }
+ java.util.List<URL> urlList = new ArrayList<>();
+ for (JavaFileObject jfo : jfoIterable) {
+ String urlStr = jfo.toUri().toURL().toString();
+ urlStr = urlStr.substring(0, urlStr.length() - jfo.getName().length());
+ urlList.add(new URL(urlStr));
+ }
+ return Optional.of(
+ executionFunc.apply(
+ new ExecutionTask(new URLClassLoader(urlList.toArray(new URL[urlList.size()])))));
+ }
+
+ /**
* Fork a new compilation task; if possible the compilation context from previous executions is
* retained (see comments in ReusableContext as to when it's safe to do so); otherwise a brand
* new context is created.
@@ -215,6 +244,80 @@
}
/**
+ * This class represents an execution task. It allows the execution of one or more classes previously
+ * added to a given class loader. This class uses reflection to execute any given static public method
+ * in any given class. It's not restricted to the execution of the {@code main} method
+ */
+ public class ExecutionTask {
+ private ClassLoader classLoader;
+ private String methodName = "main";
+ private Class<?>[] parameterTypes = new Class<?>[]{String[].class};
+ private Object[] args = new String[0];
+ private Consumer<Throwable> handler;
+ private Class<?> c;
+
+ private ExecutionTask(ClassLoader classLoader) {
+ this.classLoader = classLoader;
+ }
+
+ /**
+ * Set the name of the class to be loaded.
+ */
+ public ExecutionTask withClass(String className) {
+ Assert.check(className != null, "class name value is null, impossible to proceed");
+ try {
+ c = classLoader.loadClass(className);
+ } catch (Throwable t) {
+ throw new IllegalStateException(t);
+ }
+ return this;
+ }
+
+ /**
+ * Set the name of the method to be executed along with the parameter types to
+ * reflectively obtain the method.
+ */
+ public ExecutionTask withMethod(String methodName, Class<?>... parameterTypes) {
+ this.methodName = methodName;
+ this.parameterTypes = parameterTypes;
+ return this;
+ }
+
+ /**
+ * Set the arguments to be passed to the method.
+ */
+ public ExecutionTask withArguments(Object... args) {
+ this.args = args;
+ return this;
+ }
+
+ /**
+ * Set a handler to handle any exception thrown.
+ */
+ public ExecutionTask withHandler(Consumer<Throwable> handler) {
+ this.handler = handler;
+ return this;
+ }
+
+ /**
+ * Executes the given method in the given class. Returns true if the execution was
+ * successful, false otherwise.
+ */
+ public Object run() {
+ try {
+ java.lang.reflect.Method meth = c.getMethod(methodName, parameterTypes);
+ meth.invoke(null, (Object)args);
+ return true;
+ } catch (Throwable t) {
+ if (handler != null) {
+ handler.accept(t);
+ }
+ return false;
+ }
+ }
+ }
+
+ /**
* This class is used to help clients accessing the results of a given compilation task.
* Contains several helper methods to inspect diagnostics generated during the task execution.
*/
--- a/langtools/test/tools/javac/meth/BadPolySig.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,12 +0,0 @@
-/*
- * @test
- * @bug 8168774
- * @summary Polymorhic signature method check crashes javac
- * @compile -Xmodule:java.base BadPolySig.java
- */
-
-package java.lang.invoke;
-
-class MethodHandle {
- native Object m();
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/meth/BadPolySig/BadPolySig.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 8168774
+ * @summary Polymorhic signature method check crashes javac
+ * @modules jdk.compiler
+ * @compile/module=java.base java/lang/invoke/MethodHandle.java
+ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/meth/BadPolySig/java.base/java/lang/invoke/MethodHandle.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
+ * 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 java.lang.invoke;
+
+class MethodHandle {
+ native Object m();
+}
--- a/langtools/test/tools/javac/modules/AddLimitMods.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/modules/AddLimitMods.java Wed Jul 05 22:52:22 2017 +0200
@@ -293,7 +293,7 @@
}
actual = new JavacTask(tb)
- .options("-Xmodule:java.base",
+ .options("--patch-module", "java.base=" + cpSrc.toString(),
"-XDrawDiagnostics",
"--add-modules", "ALL-MODULE-PATH")
.outdir(cpOut)
--- a/langtools/test/tools/javac/modules/AddReadsTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/modules/AddReadsTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -217,7 +217,7 @@
new JavacTask(tb)
.options("--class-path", jar.toString(),
"--add-reads", "java.base=ALL-UNNAMED",
- "-Xmodule:java.base")
+ "--patch-module", "java.base=" + src)
.outdir(classes)
.files(src.resolve("impl").resolve("Impl.java"))
.run()
@@ -237,7 +237,7 @@
new JavacTask(tb)
.options("--add-modules", "java.desktop",
"--add-reads", "java.base=java.desktop",
- "-Xmodule:java.base")
+ "--patch-module", "java.base=" + src)
.outdir(classes)
.files(findJavaFiles(src))
.run()
@@ -304,7 +304,7 @@
new JavacTask(tb)
.options("--add-reads", "m1x=ALL-UNNAMED",
- "-Xmodule:m1x",
+ "--patch-module", "m1x=" + unnamedSrc,
"--module-path", classes.toString())
.outdir(unnamedClasses)
.files(findJavaFiles(unnamedSrc))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/modules/CompileModulePatchTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,694 @@
+/*
+ * 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
+ * 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 8173777
+ * @summary tests for multi-module mode compilation
+ * @library /tools/lib
+ * @modules
+ * jdk.compiler/com.sun.tools.javac.api
+ * jdk.compiler/com.sun.tools.javac.code
+ * jdk.compiler/com.sun.tools.javac.main
+ * jdk.compiler/com.sun.tools.javac.processing
+ * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
+ * @run main CompileModulePatchTest
+ */
+
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.ModuleElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.util.Elements;
+
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.processing.JavacProcessingEnvironment;
+import toolbox.JavacTask;
+import toolbox.ModuleBuilder;
+import toolbox.Task;
+import toolbox.Task.Expect;
+
+public class CompileModulePatchTest extends ModuleTestBase {
+
+ public static void main(String... args) throws Exception {
+ new CompileModulePatchTest().runTests();
+ }
+
+ @Test
+ public void testCorrectModulePatch(Path base) throws Exception {
+ //note: avoiding use of java.base, as that gets special handling on some places:
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ String log = new JavacTask(tb)
+ .options("--patch-module", "java.compiler=" + src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+
+ if (!log.isEmpty())
+ throw new Exception("expected output not found: " + log);
+ }
+
+ @Test
+ public void testCorrectModulePatchMultiModule(Path base) throws Exception {
+ //note: avoiding use of java.base, as that gets special handling on some places:
+ Path src = base.resolve("src");
+ Path m1 = src.resolve("m1");
+ tb.writeJavaFiles(m1, "package javax.lang.model.element; public interface Extra extends Element { }");
+ Path m2 = src.resolve("m2");
+ tb.writeJavaFiles(m2, "package com.sun.source.tree; public interface Extra extends Tree { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ String log = new JavacTask(tb)
+ .options("--patch-module", "java.compiler=" + m1.toString(),
+ "--patch-module", "jdk.compiler=" + m2.toString(),
+ "--module-source-path", "dummy")
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+
+ if (!log.isEmpty())
+ throw new Exception("expected output not found: " + log);
+
+ checkFileExists(classes, "java.compiler/javax/lang/model/element/Extra.class");
+ checkFileExists(classes, "jdk.compiler/com/sun/source/tree/Extra.class");
+ }
+
+ @Test
+ public void testCorrectModulePatchMultiModule2(Path base) throws Exception {
+ //note: avoiding use of java.base, as that gets special handling on some places:
+ Path src = base.resolve("src");
+ Path m1 = src.resolve("m1");
+ tb.writeJavaFiles(m1,
+ "package javax.lang.model.element; public interface Extra extends Element { }");
+ Path m2 = src.resolve("m2");
+ tb.writeJavaFiles(m2,
+ "package com.sun.source.tree; public interface Extra extends Tree { }");
+ Path msp = base.resolve("msp");
+ Path m3 = msp.resolve("m3x");
+ tb.writeJavaFiles(m3,
+ "module m3x { }",
+ "package m3; public class Test { }");
+ Path m4 = msp.resolve("m4x");
+ tb.writeJavaFiles(m4,
+ "module m4x { }",
+ "package m4; public class Test { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ String log = new JavacTask(tb)
+ .options("--patch-module", "java.compiler=" + m1.toString(),
+ "--patch-module", "jdk.compiler=" + m2.toString(),
+ "--module-source-path", msp.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src, msp))
+ .run()
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+
+ if (!log.isEmpty())
+ throw new Exception("expected output not found: " + log);
+
+ checkFileExists(classes, "java.compiler/javax/lang/model/element/Extra.class");
+ checkFileExists(classes, "jdk.compiler/com/sun/source/tree/Extra.class");
+ checkFileExists(classes, "m3x/m3/Test.class");
+ checkFileExists(classes, "m4x/m4/Test.class");
+ }
+
+ @Test
+ public void testPatchModuleModuleSourcePathConflict(Path base) throws Exception {
+ //note: avoiding use of java.base, as that gets special handling on some places:
+ Path src = base.resolve("src");
+ Path m1 = src.resolve("m1x");
+ tb.writeJavaFiles(m1,
+ "module m1x { }",
+ "package m1; public class Test { }");
+ Path m2 = src.resolve("m2x");
+ tb.writeJavaFiles(m2,
+ "module m2x { }",
+ "package m2; public class Test { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("--patch-module", "m1x=" + m2.toString(),
+ "--module-source-path", src.toString(),
+ "-XDrawDiagnostics")
+ .outdir(classes)
+ .files(findJavaFiles(src.resolve("m1x").resolve("m1"),
+ src.resolve("m2x").resolve("m2")))
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expectedOut = Arrays.asList(
+ "Test.java:1:1: compiler.err.file.patched.and.msp: m1x, m2x",
+ "1 error"
+ );
+
+ if (!expectedOut.equals(log))
+ throw new Exception("expected output not found: " + log);
+ }
+
+ @Test
+ public void testSourcePath(Path base) throws Exception {
+ //note: avoiding use of java.base, as that gets special handling on some places:
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, Other { }");
+ Path srcPath = base.resolve("src-path");
+ tb.writeJavaFiles(srcPath, "package javax.lang.model.element; interface Other { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("--patch-module", "java.compiler=" + src.toString(),
+ "-sourcepath", srcPath.toString(),
+ "-XDrawDiagnostics")
+ .outdir(classes)
+ .files(src.resolve("javax/lang/model/element/Extra.java"))
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expectedOut = Arrays.asList(
+ "Extra.java:1:75: compiler.err.cant.resolve: kindname.class, Other, , ",
+ "1 error"
+ );
+
+ if (!expectedOut.equals(log))
+ throw new Exception("expected output not found: " + log);
+ }
+
+ @Test
+ public void testClassPath(Path base) throws Exception {
+ Path cpSrc = base.resolve("cpSrc");
+ tb.writeJavaFiles(cpSrc, "package p; public interface Other { }");
+ Path cpClasses = base.resolve("cpClasses");
+ tb.createDirectories(cpClasses);
+
+ String cpLog = new JavacTask(tb)
+ .outdir(cpClasses)
+ .files(findJavaFiles(cpSrc))
+ .run()
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+
+ if (!cpLog.isEmpty())
+ throw new Exception("expected output not found: " + cpLog);
+
+ Path src = base.resolve("src");
+ //note: avoiding use of java.base, as that gets special handling on some places:
+ tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, p.Other { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log = new JavacTask(tb)
+ .options("--patch-module", "java.compiler=" + src.toString(),
+ "--class-path", cpClasses.toString(),
+ "-XDrawDiagnostics")
+ .outdir(classes)
+ .files(src.resolve("javax/lang/model/element/Extra.java"))
+ .run(Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expectedOut = Arrays.asList(
+ "Extra.java:1:76: compiler.err.doesnt.exist: p",
+ "1 error"
+ );
+
+ if (!expectedOut.equals(log))
+ throw new Exception("expected output not found: " + log);
+ }
+
+ @Test
+ public void testNoModuleInfoOnSourcePath(Path base) throws Exception {
+ //note: avoiding use of java.base, as that gets special handling on some places:
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src,
+ "module java.compiler {}",
+ "package javax.lang.model.element; public interface Extra { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ List<String> log;
+ List<String> expected;
+
+ log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--patch-module", "java.compiler=" + src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.patched.module.sourcepath",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found: " + log);
+
+ //multi-module mode:
+ log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--patch-module", "java.compiler=" + src.toString(),
+ "--module-source-path", "dummy")
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList("- compiler.err.locn.module-info.not.allowed.on.patch.path: module-info.java",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found: " + log);
+ }
+
+ @Test
+ public void testNoModuleInfoInClassOutput(Path base) throws Exception {
+ //note: avoiding use of java.base, as that gets special handling on some places:
+ Path srcMod = base.resolve("src-mod");
+ tb.writeJavaFiles(srcMod,
+ "module mod {}");
+ Path classes = base.resolve("classes").resolve("java.compiler");
+ tb.createDirectories(classes);
+
+ String logMod = new JavacTask(tb)
+ .options()
+ .outdir(classes)
+ .files(findJavaFiles(srcMod))
+ .run()
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+
+ if (!logMod.isEmpty())
+ throw new Exception("unexpected output found: " + logMod);
+
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src,
+ "package javax.lang.model.element; public interface Extra { }");
+ tb.createDirectories(classes);
+
+ List<String> log;
+ List<String> expected;
+
+ log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--patch-module", "java.compiler=" + src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.patched.module.classoutput",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found: " + log);
+
+ log = new JavacTask(tb)
+ .options("-XDrawDiagnostics",
+ "--patch-module", "java.compiler=" + src.toString(),
+ "--module-source-path", "dummy")
+ .outdir(classes.getParent())
+ .files(findJavaFiles(src))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ expected = Arrays.asList("- compiler.err.locn.module-info.not.allowed.on.patch.path: module-info.class",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found: " + log);
+ }
+
+ @Test
+ public void testWithModulePath(Path base) throws Exception {
+ Path modSrc = base.resolve("modSrc");
+ Path modules = base.resolve("modules");
+ new ModuleBuilder(tb, "m1")
+ .classes("package pkg1; public interface E { }")
+ .build(modSrc, modules);
+
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src, "package p; interface A extends pkg1.E { }");
+
+ new JavacTask(tb, Task.Mode.CMDLINE)
+ .options("--module-path", modules.toString(),
+ "--patch-module", "m1=" + src.toString())
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+
+ //checks module bounds still exist
+ new ModuleBuilder(tb, "m2")
+ .classes("package pkg2; public interface D { }")
+ .build(modSrc, modules);
+
+ Path src2 = base.resolve("src2");
+ tb.writeJavaFiles(src2, "package p; interface A extends pkg2.D { }");
+
+ List<String> log = new JavacTask(tb, Task.Mode.CMDLINE)
+ .options("-XDrawDiagnostics",
+ "--module-path", modules.toString(),
+ "--patch-module", "m1=" + src2.toString())
+ .files(findJavaFiles(src2))
+ .run(Task.Expect.FAIL)
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT);
+
+ List<String> expected = Arrays.asList("A.java:1:32: compiler.err.package.not.visible: pkg2, (compiler.misc.not.def.access.does.not.read: m1, pkg2, m2)",
+ "1 error");
+
+ if (!expected.equals(log))
+ throw new Exception("expected output not found: " + log);
+ }
+
+ @Test
+ public void testWithUpgradeModulePath(Path base) throws Exception {
+ Path modSrc = base.resolve("modSrc");
+ Path modules = base.resolve("modules");
+ new ModuleBuilder(tb, "m1")
+ .classes("package pkg1; public interface E { }")
+ .build(modSrc, modules);
+
+ Path upgrSrc = base.resolve("upgradeSrc");
+ Path upgrade = base.resolve("upgrade");
+ new ModuleBuilder(tb, "m1")
+ .classes("package pkg1; public interface D { }")
+ .build(upgrSrc, upgrade);
+
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src, "package p; interface A extends pkg1.D { }");
+
+ new JavacTask(tb, Task.Mode.CMDLINE)
+ .options("--module-path", modules.toString(),
+ "--upgrade-module-path", upgrade.toString(),
+ "--patch-module", "m1=" + src.toString())
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+ }
+
+ @Test
+ public void testUnnamedIsolation(Path base) throws Exception {
+ //note: avoiding use of java.base, as that gets special handling on some places:
+ Path sourcePath = base.resolve("source-path");
+ tb.writeJavaFiles(sourcePath, "package src; public class Src {}");
+
+ Path classPathSrc = base.resolve("class-path-src");
+ tb.writeJavaFiles(classPathSrc, "package cp; public class CP { }");
+ Path classPath = base.resolve("classPath");
+ tb.createDirectories(classPath);
+
+ String cpLog = new JavacTask(tb)
+ .outdir(classPath)
+ .files(findJavaFiles(classPathSrc))
+ .run()
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+
+ if (!cpLog.isEmpty())
+ throw new Exception("expected output not found: " + cpLog);
+
+ Path modulePathSrc = base.resolve("module-path-src");
+ tb.writeJavaFiles(modulePathSrc,
+ "module m {}",
+ "package m; public class M {}");
+ Path modulePath = base.resolve("modulePath");
+ tb.createDirectories(modulePath.resolve("m"));
+
+ String modLog = new JavacTask(tb)
+ .outdir(modulePath.resolve("m"))
+ .files(findJavaFiles(modulePathSrc))
+ .run()
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+
+ if (!modLog.isEmpty())
+ throw new Exception("expected output not found: " + modLog);
+
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src, "package m; public class Extra { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ String log = new JavacTask(tb)
+ .options("--patch-module", "m=" + sourcePath.toString(),
+ "--class-path", classPath.toString(),
+ "--source-path", sourcePath.toString(),
+ "--module-path", modulePath.toString(),
+ "--processor-path", System.getProperty("test.classes"),
+ "-XDaccessInternalAPI=true",
+ "-processor", CheckModuleContentProcessing.class.getName())
+ .outdir(classes)
+ .files(findJavaFiles(sourcePath))
+ .run()
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+
+ if (!log.isEmpty())
+ throw new Exception("expected output not found: " + log);
+ }
+
+ @SupportedAnnotationTypes("*")
+ public static final class CheckModuleContentProcessing extends AbstractProcessor {
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ Symtab syms = Symtab.instance(((JavacProcessingEnvironment) processingEnv).getContext());
+ Elements elements = processingEnv.getElementUtils();
+ ModuleElement unnamedModule = syms.unnamedModule;
+ ModuleElement mModule = elements.getModuleElement("m");
+
+ assertNonNull("mModule found", mModule);
+ assertNonNull("src.Src from m", elements.getTypeElement(mModule, "src.Src"));
+ assertNull("cp.CP not from m", elements.getTypeElement(mModule, "cp.CP"));
+ assertNull("src.Src not from unnamed", elements.getTypeElement(unnamedModule, "src.Src"));
+ assertNonNull("cp.CP from unnamed", elements.getTypeElement(unnamedModule, "cp.CP"));
+
+ return false;
+ }
+
+ @Override
+ public SourceVersion getSupportedSourceVersion() {
+ return SourceVersion.latest();
+ }
+
+ private static void assertNonNull(String msg, Object val) {
+ if (val == null) {
+ throw new AssertionError(msg);
+ }
+ }
+
+ private static void assertNull(String msg, Object val) {
+ if (val != null) {
+ throw new AssertionError(msg);
+ }
+ }
+ }
+
+ @Test
+ public void testSingleModeIncremental(Path base) throws Exception {
+ //note: avoiding use of java.base, as that gets special handling on some places:
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src,
+ "package javax.lang.model.element; public interface Extra extends Element { }",
+ "package javax.lang.model.element; public interface Extra2 extends Extra { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ Thread.sleep(2000); //ensure newer timestamps on classfiles:
+
+ new JavacTask(tb)
+ .options("--patch-module", "java.compiler=" + src.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+
+ List<String> log = new JavacTask(tb)
+ .options("--patch-module", "java.compiler=" + src.toString(),
+ "-verbose")
+ .outdir(classes)
+ .files(findJavaFiles(src.resolve("javax/lang/model/element/Extra2.java"
+ .replace("/", src.getFileSystem().getSeparator()))))
+ .run()
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT)
+ .stream()
+ .filter(l -> l.contains("parsing"))
+ .collect(Collectors.toList());
+
+ boolean parsesExtra2 = log.stream()
+ .anyMatch(l -> l.contains("Extra2.java"));
+ boolean parsesExtra = log.stream()
+ .anyMatch(l -> l.contains("Extra.java"));
+
+ if (!parsesExtra2 || parsesExtra) {
+ throw new AssertionError("Unexpected output: " + log);
+ }
+ }
+
+ @Test
+ public void testComplexMSPAndPatch(Path base) throws Exception {
+ //note: avoiding use of java.base, as that gets special handling on some places:
+ Path src1 = base.resolve("src1");
+ Path src1ma = src1.resolve("ma");
+ tb.writeJavaFiles(src1ma,
+ "module ma { exports ma; }",
+ "package ma; public class C1 { public static void method() { } }",
+ "package ma.impl; public class C2 { }");
+ Path src1mb = src1.resolve("mb");
+ tb.writeJavaFiles(src1mb,
+ "module mb { requires ma; }",
+ "package mb.impl; public class C2 { public static void method() { } }");
+ Path src1mc = src1.resolve("mc");
+ tb.writeJavaFiles(src1mc,
+ "module mc { }");
+ Path classes1 = base.resolve("classes1");
+ tb.createDirectories(classes1);
+ tb.cleanDirectory(classes1);
+
+ new JavacTask(tb)
+ .options("--module-source-path", src1.toString())
+ .files(findJavaFiles(src1))
+ .outdir(classes1)
+ .run()
+ .writeAll();
+
+ //patching:
+ Path src2 = base.resolve("src2");
+ Path src2ma = src2.resolve("ma");
+ tb.writeJavaFiles(src2ma,
+ "package ma.impl; public class C2 { public static void extra() { ma.C1.method(); } }",
+ "package ma.impl; public class C3 { public void test() { C2.extra(); } }");
+ Path src2mb = src2.resolve("mb");
+ tb.writeJavaFiles(src2mb,
+ "package mb.impl; public class C3 { public void test() { C2.method(); ma.C1.method(); ma.impl.C2.extra(); } }");
+ Path src2mc = src2.resolve("mc");
+ tb.writeJavaFiles(src2mc,
+ "package mc.impl; public class C2 { public static void test() { } }",
+ //will require --add-reads ma:
+ "package mc.impl; public class C3 { public static void test() { ma.impl.C2.extra(); } }");
+ Path src2mt = src2.resolve("mt");
+ tb.writeJavaFiles(src2mt,
+ "module mt { requires ma; requires mb; }",
+ "package mt.impl; public class C2 { public static void test() { mb.impl.C2.method(); ma.impl.C2.extra(); } }",
+ "package mt.impl; public class C3 { public static void test() { C2.test(); mc.impl.C2.test(); } }");
+ Path classes2 = base.resolve("classes2");
+ tb.createDirectories(classes2);
+ tb.cleanDirectory(classes2);
+
+ Thread.sleep(2000); //ensure newer timestamps on classfiles:
+
+ new JavacTask(tb)
+ .options("--module-path", classes1.toString(),
+ "--patch-module", "ma=" + src2ma.toString(),
+ "--patch-module", "mb=" + src2mb.toString(),
+ "--add-exports", "ma/ma.impl=mb",
+ "--patch-module", "mc=" + src2mc.toString(),
+ "--add-reads", "mc=ma",
+ "--add-exports", "ma/ma.impl=mc",
+ "--add-exports", "ma/ma.impl=mt",
+ "--add-exports", "mb/mb.impl=mt",
+ "--add-exports", "mc/mc.impl=mt",
+ "--add-reads", "mt=mc",
+ "--module-source-path", src2.toString())
+ .outdir(classes2)
+ .files(findJavaFiles(src2))
+ .run()
+ .writeAll();
+
+ //incremental compilation (C2 mustn't be compiled, C3 must):
+ tb.writeJavaFiles(src2ma,
+ "package ma.impl; public class C3 { public void test() { ma.C1.method(); C2.extra(); } }");
+ tb.writeJavaFiles(src2mt,
+ "package mt.impl; public class C3 { public static void test() { mc.impl.C2.test(); C2.test(); } }");
+
+ List<String> log = new JavacTask(tb)
+ .options("--module-path", classes1.toString(),
+ "--patch-module", "ma=" + src2ma.toString(),
+ "--patch-module", "mb=" + src2mb.toString(),
+ "--add-exports", "ma/ma.impl=mb",
+ "--patch-module", "mc=" + src2mc.toString(),
+ "--add-reads", "mc=ma",
+ "--add-exports", "ma/ma.impl=mc",
+ "--add-exports", "ma/ma.impl=mt",
+ "--add-exports", "mb/mb.impl=mt",
+ "--add-exports", "mc/mc.impl=mt",
+ "--add-reads", "mt=mc",
+ "--module-source-path", src2.toString(),
+ "--add-modules", "mc",
+ "-verbose")
+ .outdir(classes2)
+ .files(src2ma.resolve("ma").resolve("impl").resolve("C3.java"),
+ src2mt.resolve("mt").resolve("impl").resolve("C3.java"))
+ .run()
+ .writeAll()
+ .getOutputLines(Task.OutputKind.DIRECT)
+ .stream()
+ .filter(l -> l.contains("parsing"))
+ .collect(Collectors.toList());
+
+ boolean parsesC3 = log.stream()
+ .anyMatch(l -> l.contains("C3.java"));
+ boolean parsesC2 = log.stream()
+ .anyMatch(l -> l.contains("C2.java"));
+
+ if (!parsesC3 || parsesC2) {
+ throw new AssertionError("Unexpected output: " + log);
+ }
+ }
+
+ private void checkFileExists(Path dir, String path) {
+ Path toCheck = dir.resolve(path.replace("/", dir.getFileSystem().getSeparator()));
+
+ if (!Files.exists(toCheck)) {
+ throw new AssertionError(toCheck.toString() + " does not exist!");
+ }
+ }
+}
--- a/langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/modules/InheritRuntimeEnvironmentTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -177,7 +177,7 @@
Files.createDirectories(patch);
new JavacTask(tb)
- .options("-Xmodule:java.base")
+ .options("--patch-module", "java.base=" + patchSrc.toString())
.outdir(patch)
.sourcepath(patchSrc)
.files(findJavaFiles(patchSrc))
--- a/langtools/test/tools/javac/modules/ModuleInfoTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/modules/ModuleInfoTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -94,7 +94,7 @@
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- if (!log.contains("module-info.java:1:8: compiler.err.class.public.should.be.in.file: C"))
+ if (!log.contains("module-info.java:1:8: compiler.err.class.public.should.be.in.file: kindname.class, C"))
throw new Exception("expected output not found");
}
--- a/langtools/test/tools/javac/modules/ModulePathTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/modules/ModulePathTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved.
* 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 8142968 8174104
* @summary tests for --module-path
* @library /tools/lib
* @modules
@@ -57,7 +58,7 @@
}
@Test
- public void testNotExistsOnPath(Path base) throws Exception {
+ public void testNotExistsOnPath_noWarn(Path base) throws Exception {
Path src = base.resolve("src");
tb.writeJavaFiles(src, "class C { }");
@@ -65,11 +66,29 @@
.options("-XDrawDiagnostics",
"--module-path", "doesNotExist")
.files(findJavaFiles(src))
- .run(Task.Expect.FAIL)
+ .run(Task.Expect.SUCCESS)
.writeAll()
.getOutput(Task.OutputKind.DIRECT);
- if (!log.contains("- compiler.err.illegal.argument.for.option: --module-path, doesNotExist"))
+ if (!log.isEmpty())
+ throw new Exception("unexpected output");
+ }
+
+ @Test
+ public void testNotExistsOnPath_warn(Path base) throws Exception {
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src, "class C { }");
+
+ String log = new JavacTask(tb, Task.Mode.CMDLINE)
+ .options("-XDrawDiagnostics",
+ "-Xlint:path",
+ "--module-path", "doesNotExist")
+ .files(findJavaFiles(src))
+ .run(Task.Expect.SUCCESS)
+ .writeAll()
+ .getOutput(Task.OutputKind.DIRECT);
+
+ if (!log.contains("- compiler.warn.path.element.not.found: doesNotExist"))
throw new Exception("expected output not found");
}
--- a/langtools/test/tools/javac/modules/PatchModulesTest.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/modules/PatchModulesTest.java Wed Jul 05 22:52:22 2017 +0200
@@ -28,7 +28,7 @@
* @library /tools/lib
* @modules
* jdk.compiler/com.sun.tools.javac.api
- * jdk.compiler/com.sun.tools.javac.file:+open
+ * jdk.compiler/com.sun.tools.javac.file
* jdk.compiler/com.sun.tools.javac.main
* @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
* @run main PatchModulesTest
@@ -38,21 +38,26 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.lang.reflect.Field;
+import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.AbstractMap.SimpleEntry;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+import javax.tools.JavaFileManager.Location;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.StandardLocation;
import com.sun.source.util.JavacTask;
import com.sun.tools.javac.api.JavacTool;
-import com.sun.tools.javac.file.BaseFileManager;
import com.sun.tools.javac.file.JavacFileManager;
-import com.sun.tools.javac.file.Locations;
import static java.util.Arrays.asList;
@@ -115,21 +120,29 @@
void test(List<String> patches, boolean expectOK, String expect) throws Exception {
JavacTool tool = (JavacTool) ToolProvider.getSystemJavaCompiler();
StringWriter sw = new StringWriter();
- try (PrintWriter pw = new PrintWriter(sw)) {
- JavacFileManager fm = tool.getStandardFileManager(null, null, null);
+ try (PrintWriter pw = new PrintWriter(sw);
+ JavacFileManager fm = tool.getStandardFileManager(null, null, null)) {
List<String> opts = patches.stream()
.map(p -> "--patch-module=" + p.replace(":", PS))
.collect(Collectors.toList());
Iterable<? extends JavaFileObject> files = fm.getJavaFileObjects("C.java");
JavacTask task = tool.getTask(pw, fm, null, opts, null, files);
- Field locationsField = BaseFileManager.class.getDeclaredField("locations");
- locationsField.setAccessible(true);
- Object locations = locationsField.get(fm);
+ Map<String, List<Location>> mod2Location =
+ StreamSupport.stream(fm.listLocationsForModules(StandardLocation.PATCH_MODULE_PATH)
+ .spliterator(),
+ false)
+ .flatMap(sl -> sl.stream())
+ .collect(Collectors.groupingBy(l -> fm.inferModuleName(l)));
- Field patchMapField = Locations.class.getDeclaredField("patchMap");
- patchMapField.setAccessible(true);
- Map<?,?> patchMap = (Map<?,?>) patchMapField.get(locations);
+ Map<String, List<String>> patchMap = mod2Location.entrySet()
+ .stream()
+ .map(e -> new SimpleEntry<>(e.getKey(), e.getValue().get(0)))
+ .map(e -> new SimpleEntry<>(e.getKey(), locationPaths(fm, e.getValue())))
+ .collect(Collectors.toMap(Entry :: getKey,
+ Entry :: getValue,
+ (v1, v2) -> {throw new IllegalStateException();},
+ TreeMap::new));
String found = patchMap.toString();
if (!found.equals(expect)) {
@@ -150,5 +163,34 @@
}
}
}
+
+ static List<String> locationPaths(StandardJavaFileManager fm, Location loc) {
+ return StreamSupport.stream(fm.getLocationAsPaths(loc).spliterator(), false)
+ .map(p -> p.toString())
+ .collect(Collectors.toList());
+ }
+
+ @Test
+ public void testPatchWithSource(Path base) throws Exception {
+ Path patch = base.resolve("patch");
+ tb.writeJavaFiles(patch, "package javax.lang.model.element; public interface Extra { }");
+ Path src = base.resolve("src");
+ tb.writeJavaFiles(src,
+ "module m { requires java.compiler; }",
+ "package test; public interface Test extends javax.lang.model.element.Extra { }");
+ Path classes = base.resolve("classes");
+ tb.createDirectories(classes);
+
+ new toolbox.JavacTask(tb)
+ .options("--patch-module", "java.compiler=" + patch.toString())
+ .outdir(classes)
+ .files(findJavaFiles(src))
+ .run()
+ .writeAll();
+
+ if (Files.exists(classes.resolve("javax"))) {
+ throw new AssertionError();
+ }
+ }
}
--- a/langtools/test/tools/javac/modules/XModuleTest.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,422 +0,0 @@
-/*
- * 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
- * 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
- * @summary tests for multi-module mode compilation
- * @library /tools/lib
- * @modules
- * jdk.compiler/com.sun.tools.javac.api
- * jdk.compiler/com.sun.tools.javac.code
- * jdk.compiler/com.sun.tools.javac.main
- * jdk.compiler/com.sun.tools.javac.processing
- * @build toolbox.ToolBox toolbox.JavacTask toolbox.ModuleBuilder ModuleTestBase
- * @run main XModuleTest
- */
-
-import java.nio.file.Path;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Set;
-
-import javax.annotation.processing.AbstractProcessor;
-import javax.annotation.processing.RoundEnvironment;
-import javax.annotation.processing.SupportedAnnotationTypes;
-import javax.lang.model.SourceVersion;
-import javax.lang.model.element.ModuleElement;
-import javax.lang.model.element.TypeElement;
-import javax.lang.model.util.Elements;
-
-import com.sun.tools.javac.code.Symtab;
-import com.sun.tools.javac.processing.JavacProcessingEnvironment;
-import toolbox.JavacTask;
-import toolbox.ModuleBuilder;
-import toolbox.Task;
-import toolbox.Task.Expect;
-
-public class XModuleTest extends ModuleTestBase {
-
- public static void main(String... args) throws Exception {
- new XModuleTest().runTests();
- }
-
- @Test
- public void testCorrectXModule(Path base) throws Exception {
- //note: avoiding use of java.base, as that gets special handling on some places:
- Path src = base.resolve("src");
- tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
- Path classes = base.resolve("classes");
- tb.createDirectories(classes);
-
- String log = new JavacTask(tb)
- .options("-Xmodule:java.compiler")
- .outdir(classes)
- .files(findJavaFiles(src))
- .run()
- .writeAll()
- .getOutput(Task.OutputKind.DIRECT);
-
- if (!log.isEmpty())
- throw new Exception("expected output not found: " + log);
- }
-
- @Test
- public void testSourcePath(Path base) throws Exception {
- //note: avoiding use of java.base, as that gets special handling on some places:
- Path src = base.resolve("src");
- tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, Other { }", "package javax.lang.model.element; interface Other { }");
- Path classes = base.resolve("classes");
- tb.createDirectories(classes);
-
- String log = new JavacTask(tb)
- .options("-Xmodule:java.compiler", "-sourcepath", src.toString())
- .outdir(classes)
- .files(src.resolve("javax/lang/model/element/Extra.java"))
- .run()
- .writeAll()
- .getOutput(Task.OutputKind.DIRECT);
-
- if (!log.isEmpty())
- throw new Exception("expected output not found: " + log);
- }
-
- @Test
- public void testClassPath(Path base) throws Exception {
- Path cpSrc = base.resolve("cpSrc");
- tb.writeJavaFiles(cpSrc, "package p; public interface Other { }");
- Path cpClasses = base.resolve("cpClasses");
- tb.createDirectories(cpClasses);
-
- String cpLog = new JavacTask(tb)
- .outdir(cpClasses)
- .files(findJavaFiles(cpSrc))
- .run()
- .writeAll()
- .getOutput(Task.OutputKind.DIRECT);
-
- if (!cpLog.isEmpty())
- throw new Exception("expected output not found: " + cpLog);
-
- Path src = base.resolve("src");
- //note: avoiding use of java.base, as that gets special handling on some places:
- tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element, p.Other { }");
- Path classes = base.resolve("classes");
- tb.createDirectories(classes);
-
- List<String> log = new JavacTask(tb)
- .options("-Xmodule:java.compiler",
- "--class-path", cpClasses.toString(),
- "-XDrawDiagnostics")
- .outdir(classes)
- .files(src.resolve("javax/lang/model/element/Extra.java"))
- .run(Expect.FAIL)
- .writeAll()
- .getOutputLines(Task.OutputKind.DIRECT);
-
- List<String> expectedOut = Arrays.asList(
- "Extra.java:1:76: compiler.err.doesnt.exist: p",
- "1 error"
- );
-
- if (!expectedOut.equals(log))
- throw new Exception("expected output not found: " + log);
- }
-
- @Test
- public void testNoModuleInfoOnSourcePath(Path base) throws Exception {
- //note: avoiding use of java.base, as that gets special handling on some places:
- Path src = base.resolve("src");
- tb.writeJavaFiles(src,
- "module java.compiler {}",
- "package javax.lang.model.element; public interface Extra { }");
- Path classes = base.resolve("classes");
- tb.createDirectories(classes);
-
- List<String> log = new JavacTask(tb)
- .options("-XDrawDiagnostics", "-Xmodule:java.compiler")
- .outdir(classes)
- .files(findJavaFiles(src))
- .run(Task.Expect.FAIL)
- .writeAll()
- .getOutputLines(Task.OutputKind.DIRECT);
-
- List<String> expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.xmodule.sourcepath",
- "1 error");
-
- if (!expected.equals(log))
- throw new Exception("expected output not found: " + log);
- }
-
- @Test
- public void testNoModuleInfoInClassOutput(Path base) throws Exception {
- //note: avoiding use of java.base, as that gets special handling on some places:
- Path srcMod = base.resolve("src-mod");
- tb.writeJavaFiles(srcMod,
- "module mod {}");
- Path classes = base.resolve("classes");
- tb.createDirectories(classes);
-
- String logMod = new JavacTask(tb)
- .options()
- .outdir(classes)
- .files(findJavaFiles(srcMod))
- .run()
- .writeAll()
- .getOutput(Task.OutputKind.DIRECT);
-
- if (!logMod.isEmpty())
- throw new Exception("unexpected output found: " + logMod);
-
- Path src = base.resolve("src");
- tb.writeJavaFiles(src,
- "package javax.lang.model.element; public interface Extra { }");
- tb.createDirectories(classes);
-
- List<String> log = new JavacTask(tb)
- .options("-XDrawDiagnostics", "-Xmodule:java.compiler")
- .outdir(classes)
- .files(findJavaFiles(src))
- .run(Task.Expect.FAIL)
- .writeAll()
- .getOutputLines(Task.OutputKind.DIRECT);
-
- List<String> expected = Arrays.asList("Extra.java:1:1: compiler.err.module-info.with.xmodule.classpath",
- "1 error");
-
- if (!expected.equals(log))
- throw new Exception("expected output not found: " + log);
- }
-
- @Test
- public void testModuleSourcePathXModule(Path base) throws Exception {
- //note: avoiding use of java.base, as that gets special handling on some places:
- Path src = base.resolve("src");
- tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
- Path classes = base.resolve("classes");
- tb.createDirectories(classes);
-
- List<String> log = new JavacTask(tb)
- .options("-XDrawDiagnostics", "-Xmodule:java.compiler", "--module-source-path", src.toString())
- .outdir(classes)
- .files(findJavaFiles(src))
- .run(Task.Expect.FAIL)
- .writeAll()
- .getOutputLines(Task.OutputKind.DIRECT);
-
- List<String> expected = Arrays.asList("- compiler.err.xmodule.no.module.sourcepath");
-
- if (!expected.equals(log))
- throw new Exception("expected output not found: " + log);
- }
-
- @Test
- public void testXModuleTooMany(Path base) throws Exception {
- //note: avoiding use of java.base, as that gets special handling on some places:
- Path src = base.resolve("src");
- tb.writeJavaFiles(src, "package javax.lang.model.element; public interface Extra extends Element { }");
- Path classes = base.resolve("classes");
- tb.createDirectories(classes);
-
- List<String> log = new JavacTask(tb, Task.Mode.CMDLINE)
- .options("-XDrawDiagnostics", "-Xmodule:java.compiler", "-Xmodule:java.compiler")
- .outdir(classes)
- .files(findJavaFiles(src))
- .run(Task.Expect.FAIL)
- .writeAll()
- .getOutputLines(Task.OutputKind.DIRECT);
-
- List<String> expected = Arrays.asList("javac: option -Xmodule: can only be specified once",
- "Usage: javac <options> <source files>",
- "use --help for a list of possible options");
-
- if (!expected.equals(log))
- throw new Exception("expected output not found: " + log);
- }
-
- @Test
- public void testWithModulePath(Path base) throws Exception {
- Path modSrc = base.resolve("modSrc");
- Path modules = base.resolve("modules");
- new ModuleBuilder(tb, "m1")
- .classes("package pkg1; public interface E { }")
- .build(modSrc, modules);
-
- Path src = base.resolve("src");
- tb.writeJavaFiles(src, "package p; interface A extends pkg1.E { }");
-
- new JavacTask(tb, Task.Mode.CMDLINE)
- .options("--module-path", modules.toString(),
- "-Xmodule:m1")
- .files(findJavaFiles(src))
- .run()
- .writeAll();
-
- //checks module bounds still exist
- new ModuleBuilder(tb, "m2")
- .classes("package pkg2; public interface D { }")
- .build(modSrc, modules);
-
- Path src2 = base.resolve("src2");
- tb.writeJavaFiles(src2, "package p; interface A extends pkg2.D { }");
-
- List<String> log = new JavacTask(tb, Task.Mode.CMDLINE)
- .options("-XDrawDiagnostics",
- "--module-path", modules.toString(),
- "-Xmodule:m1")
- .files(findJavaFiles(src2))
- .run(Task.Expect.FAIL)
- .writeAll()
- .getOutputLines(Task.OutputKind.DIRECT);
-
- List<String> expected = Arrays.asList("A.java:1:32: compiler.err.package.not.visible: pkg2, (compiler.misc.not.def.access.does.not.read: m1, pkg2, m2)",
- "1 error");
-
- if (!expected.equals(log))
- throw new Exception("expected output not found: " + log);
- }
-
- @Test
- public void testWithUpgradeModulePath(Path base) throws Exception {
- Path modSrc = base.resolve("modSrc");
- Path modules = base.resolve("modules");
- new ModuleBuilder(tb, "m1")
- .classes("package pkg1; public interface E { }")
- .build(modSrc, modules);
-
- Path upgrSrc = base.resolve("upgradeSrc");
- Path upgrade = base.resolve("upgrade");
- new ModuleBuilder(tb, "m1")
- .classes("package pkg1; public interface D { }")
- .build(upgrSrc, upgrade);
-
- Path src = base.resolve("src");
- tb.writeJavaFiles(src, "package p; interface A extends pkg1.D { }");
-
- new JavacTask(tb, Task.Mode.CMDLINE)
- .options("--module-path", modules.toString(),
- "--upgrade-module-path", upgrade.toString(),
- "-Xmodule:m1")
- .files(findJavaFiles(src))
- .run()
- .writeAll();
- }
-
- @Test
- public void testUnnamedIsolation(Path base) throws Exception {
- //note: avoiding use of java.base, as that gets special handling on some places:
- Path sourcePath = base.resolve("source-path");
- tb.writeJavaFiles(sourcePath, "package src; public class Src {}");
-
- Path classPathSrc = base.resolve("class-path-src");
- tb.writeJavaFiles(classPathSrc, "package cp; public class CP { }");
- Path classPath = base.resolve("classPath");
- tb.createDirectories(classPath);
-
- String cpLog = new JavacTask(tb)
- .outdir(classPath)
- .files(findJavaFiles(classPathSrc))
- .run()
- .writeAll()
- .getOutput(Task.OutputKind.DIRECT);
-
- if (!cpLog.isEmpty())
- throw new Exception("expected output not found: " + cpLog);
-
- Path modulePathSrc = base.resolve("module-path-src");
- tb.writeJavaFiles(modulePathSrc,
- "module m {}",
- "package m; public class M {}");
- Path modulePath = base.resolve("modulePath");
- tb.createDirectories(modulePath.resolve("m"));
-
- String modLog = new JavacTask(tb)
- .outdir(modulePath.resolve("m"))
- .files(findJavaFiles(modulePathSrc))
- .run()
- .writeAll()
- .getOutput(Task.OutputKind.DIRECT);
-
- if (!modLog.isEmpty())
- throw new Exception("expected output not found: " + modLog);
-
- Path src = base.resolve("src");
- tb.writeJavaFiles(src, "package m; public class Extra { }");
- Path classes = base.resolve("classes");
- tb.createDirectories(classes);
-
- String log = new JavacTask(tb)
- .options("-Xmodule:m",
- "--class-path", classPath.toString(),
- "--source-path", sourcePath.toString(),
- "--module-path", modulePath.toString(),
- "--processor-path", System.getProperty("test.classes"),
- "-XDaccessInternalAPI=true",
- "-processor", CheckModuleContentProcessing.class.getName())
- .outdir(classes)
- .files(findJavaFiles(sourcePath))
- .run()
- .writeAll()
- .getOutput(Task.OutputKind.DIRECT);
-
- if (!log.isEmpty())
- throw new Exception("expected output not found: " + log);
- }
-
- @SupportedAnnotationTypes("*")
- public static final class CheckModuleContentProcessing extends AbstractProcessor {
-
- @Override
- public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
- Symtab syms = Symtab.instance(((JavacProcessingEnvironment) processingEnv).getContext());
- Elements elements = processingEnv.getElementUtils();
- ModuleElement unnamedModule = syms.unnamedModule;
- ModuleElement mModule = elements.getModuleElement("m");
-
- assertNonNull("mModule found", mModule);
- assertNonNull("src.Src from m", elements.getTypeElement(mModule, "src.Src"));
- assertNull("cp.CP not from m", elements.getTypeElement(mModule, "cp.CP"));
- assertNull("src.Src not from unnamed", elements.getTypeElement(unnamedModule, "src.Src"));
- assertNonNull("cp.CP from unnamed", elements.getTypeElement(unnamedModule, "cp.CP"));
-
- return false;
- }
-
- @Override
- public SourceVersion getSupportedSourceVersion() {
- return SourceVersion.latest();
- }
-
- private static void assertNonNull(String msg, Object val) {
- if (val == null) {
- throw new AssertionError(msg);
- }
- }
-
- private static void assertNull(String msg, Object val) {
- if (val != null) {
- throw new AssertionError(msg);
- }
- }
- }
-
-}
--- a/langtools/test/tools/javac/redefineObject/Object1-test.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/redefineObject/Object1-test.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,6 @@
* @summary java.lang.Object can't be redefined without crashing javac
* @author gafter
*
- * @compile/module=java.base/fail/ref=Object1.out -XDrawDiagnostics Object1.java
+ * @compile/module=java.base/fail/ref=Object1.out -XDrawDiagnostics java/lang/Object1.java
*/
--- a/langtools/test/tools/javac/redefineObject/Object2-test.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/redefineObject/Object2-test.java Wed Jul 05 22:52:22 2017 +0200
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
* 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,5 +27,5 @@
* @summary java.lang.Object can't be redefined without crashing javac
* @author gafter
*
- * @compile/module=java.base/fail/ref=Object2.out -XDrawDiagnostics Object2.java
+ * @compile/module=java.base/fail/ref=Object2.out -XDrawDiagnostics java/lang/Object2.java
*/
--- a/langtools/test/tools/javac/redefineObject/java.base/Object1.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-/*
- * /nodynamiccopyright/
- * See ../Object1-test.java
- */
-
-package java.lang;
-class Object extends Throwable {
- public final native Class getClass();
- public native int hashCode();
- public native boolean equals(Object obj);
- protected native Object clone() throws CloneNotSupportedException;
- public native String toString();
- public final native void notify();
- public final native void notifyAll();
- public final native void wait(long timeout) throws InterruptedException;
- public native final void wait(long timeout, int nanos) throws InterruptedException;
- public native final void wait() throws InterruptedException;
- protected void finalize() throws Throwable { }
-}
--- a/langtools/test/tools/javac/redefineObject/java.base/Object2.java Thu Feb 16 17:12:58 2017 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-/*
- * /nodynamiccopyright/
- * See ../Object2-test.java
- */
-
-package java.lang;
-class Object implements Cloneable {
- public final native Class getClass();
- public native int hashCode();
- public native boolean equals(Object obj);
- public native Object clone() throws CloneNotSupportedException;
- public native String toString();
- public final native void notify();
- public final native void notifyAll();
- public final native void wait(long timeout) throws InterruptedException;
- public native final void wait(long timeout, int nanos) throws InterruptedException;
- public native final void wait() throws InterruptedException;
- protected void finalize() throws Throwable { }
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/redefineObject/java.base/java/lang/Object1.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,19 @@
+/*
+ * /nodynamiccopyright/
+ * See ../Object1-test.java
+ */
+
+package java.lang;
+class Object extends Throwable {
+ public final native Class getClass();
+ public native int hashCode();
+ public native boolean equals(Object obj);
+ protected native Object clone() throws CloneNotSupportedException;
+ public native String toString();
+ public final native void notify();
+ public final native void notifyAll();
+ public final native void wait(long timeout) throws InterruptedException;
+ public native final void wait(long timeout, int nanos) throws InterruptedException;
+ public native final void wait() throws InterruptedException;
+ protected void finalize() throws Throwable { }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/redefineObject/java.base/java/lang/Object2.java Wed Jul 05 22:52:22 2017 +0200
@@ -0,0 +1,19 @@
+/*
+ * /nodynamiccopyright/
+ * See ../Object2-test.java
+ */
+
+package java.lang;
+class Object implements Cloneable {
+ public final native Class getClass();
+ public native int hashCode();
+ public native boolean equals(Object obj);
+ public native Object clone() throws CloneNotSupportedException;
+ public native String toString();
+ public final native void notify();
+ public final native void notifyAll();
+ public final native void wait(long timeout) throws InterruptedException;
+ public native final void wait(long timeout, int nanos) throws InterruptedException;
+ public native final void wait() throws InterruptedException;
+ protected void finalize() throws Throwable { }
+}
--- a/langtools/test/tools/javac/synthesize/Main.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/javac/synthesize/Main.java Wed Jul 05 22:52:22 2017 +0200
@@ -92,12 +92,17 @@
File empty = new File("empty");
empty.mkdirs();
+ // files to compile are in a separate directory from test to avoid
+ // confusing jtreg
+ File src = new File(testSrc, "src");
+
List<String> args = new ArrayList<String>();
args.add("-classpath");
args.add("empty");
if (stdBootClassPath) {
- args.add("-Xmodule:java.base");
+ args.add("--patch-module");
+ args.add("java.base=" + testSrc.getAbsolutePath());
} else {
args.add("--system");
args.add("none");
@@ -108,9 +113,6 @@
args.add("-d");
args.add(".");
- // files to compile are in a separate directory from test to avoid
- // confusing jtreg
- File src = new File(testSrc, "src");
for (String f: files)
args.add(new File(src, f).getPath());
--- a/langtools/test/tools/jdeps/jdkinternals/RemovedJDKInternals.java Thu Feb 16 17:12:58 2017 +0000
+++ b/langtools/test/tools/jdeps/jdkinternals/RemovedJDKInternals.java Wed Jul 05 22:52:22 2017 +0200
@@ -63,7 +63,7 @@
Path sunMiscSrc = Paths.get(TEST_SRC, "patches", JDK_UNSUPPORTED);
Path patchDir = PATCHES_DIR.resolve(JDK_UNSUPPORTED);
assertTrue(CompilerUtils.compile(sunMiscSrc, patchDir,
- "-Xmodule:" + JDK_UNSUPPORTED));
+ "--patch-module", JDK_UNSUPPORTED + "=" + sunMiscSrc.toString()));
// compile com.sun.image.codec.jpeg types
Path codecSrc = Paths.get(TEST_SRC, "patches", "java.desktop");
--- a/make/CompileJavaModules.gmk Thu Feb 16 17:12:58 2017 +0000
+++ b/make/CompileJavaModules.gmk Wed Jul 05 22:52:22 2017 +0200
@@ -85,7 +85,7 @@
################################################################################
-java.compiler_ADD_JAVAC_FLAGS := -Xdoclint:all/protected,-reference '-Xdoclint/package:java.*,javax.*'
+java.compiler_ADD_JAVAC_FLAGS := -Xdoclint:all/protected '-Xdoclint/package:java.*,javax.*'
################################################################################
@@ -247,7 +247,7 @@
################################################################################
-java.management.rmi_ADD_JAVAC_FLAGS := -Xdoclint:all/protected,-reference '-Xdoclint/package:javax.*'
+java.management.rmi_ADD_JAVAC_FLAGS := -Xdoclint:all/protected '-Xdoclint/package:javax.*'
################################################################################
--- a/make/GenerateLinkOptData.gmk Thu Feb 16 17:12:58 2017 +0000
+++ b/make/GenerateLinkOptData.gmk Wed Jul 05 22:52:22 2017 +0200
@@ -49,7 +49,7 @@
LINK_OPT_DIR := $(SUPPORT_OUTPUTDIR)/link_opt
CLASSLIST_FILE := $(LINK_OPT_DIR)/classlist
-JLI_TRACE_FILE := $(LINK_OPT_DIR)/jli_trace.out
+JLI_TRACE_FILE := $(LINK_OPT_DIR)/default_jli_trace.txt
# If an external buildjdk has been supplied, we don't build a separate interim
# image, so just use the external build jdk instead.
@@ -83,6 +83,14 @@
TARGETS += $(COPY_CLASSLIST)
+# Copy the default_jli_trace.txt file into jdk.jlink
+$(eval $(call SetupCopyFiles, COPY_JLI_TRACE, \
+ FILES := $(JLI_TRACE_FILE), \
+ DEST := $(JDK_OUTPUTDIR)/modules/jdk.jlink/jdk/tools/jlink/internal/plugins, \
+))
+
+TARGETS += $(COPY_JLI_TRACE)
+
################################################################################
all: $(TARGETS)
--- a/make/Images.gmk Thu Feb 16 17:12:58 2017 +0000
+++ b/make/Images.gmk Wed Jul 05 22:52:22 2017 +0200
@@ -105,7 +105,7 @@
JLINK_JLI_CLASSES :=
ifeq ($(ENABLE_GENERATE_CLASSLIST), true)
JLINK_ORDER_RESOURCES += @$(SUPPORT_OUTPUTDIR)/link_opt/classlist
- JLINK_JLI_CLASSES := --generate-jli-classes=@$(SUPPORT_OUTPUTDIR)/link_opt/jli_trace.out
+ JLINK_JLI_CLASSES := --generate-jli-classes=@$(SUPPORT_OUTPUTDIR)/link_opt/default_jli_trace.txt
endif
JLINK_ORDER_RESOURCES += \
/java.base/java/** \
--- a/make/Init.gmk Thu Feb 16 17:12:58 2017 +0000
+++ b/make/Init.gmk Wed Jul 05 22:52:22 2017 +0200
@@ -66,7 +66,7 @@
ifeq ($(CALLED_SPEC_TARGETS), )
ONLY_GLOBAL_TARGETS := true
endif
- ifneq ($(findstring qp, $(MAKEFLAGS)),)
+ ifeq ($(findstring p, $(MAKEFLAGS))$(findstring q, $(MAKEFLAGS)), pq)
ONLY_GLOBAL_TARGETS := true
endif
--- a/make/Javadoc.gmk Thu Feb 16 17:12:58 2017 +0000
+++ b/make/Javadoc.gmk Wed Jul 05 22:52:22 2017 +0200
@@ -314,7 +314,7 @@
$1_INDEX_FILE := $$(JAVADOC_OUTPUTDIR)/$$($1_OUTPUT_DIRNAME)/index.html
# Rule for actually running javadoc
- $$($1_INDEX_FILE): $(BUILD_TOOLS_JDK) $$($1_VARDEPS_FILE) $$($1_PACKAGE_DEPS) $$($1_DEPS)
+ $$($1_INDEX_FILE): $$(BUILD_TOOLS_JDK) $$($1_VARDEPS_FILE) $$($1_PACKAGE_DEPS) $$($1_DEPS)
$$(call LogWarn, Generating Javadoc from $$(words $$($1_PACKAGES)) package(s) for $$($1_OUTPUT_DIRNAME))
$$(call MakeDir, $$(@D))
ifneq ($$($1_PACKAGES_FILE), )
@@ -743,7 +743,7 @@
################################################################################
-docs-javadoc: $(BUILD_TOOLS_JDK) $(TARGETS)
+docs-javadoc: $(TARGETS)
docs-copy: $(COPY_TARGETS)
--- a/make/Main.gmk Thu Feb 16 17:12:58 2017 +0000
+++ b/make/Main.gmk Wed Jul 05 22:52:22 2017 +0200
@@ -654,8 +654,7 @@
# When creating a BUILDJDK, we don't need to add hashes to java.base, thus
# we don't need to depend on all other jmods
ifneq ($(CREATING_BUILDJDK), true)
- java.base-jmod: jrtfs-jar $(filter-out java.base-jmod \
- $(addsuffix -jmod, $(call FindAllUpgradeableModules)), $(JMOD_TARGETS))
+ java.base-jmod: jrtfs-jar $(filter-out java.base-jmod, $(JMOD_TARGETS))
endif
# Building java.base-jmod requires all of hotspot to be built.
@@ -728,7 +727,7 @@
generate-link-opt-data: buildtools-jdk
# The generated classlist needs to go into java.base-jmod.
- java.base-jmod jdk-image jre-image: generate-link-opt-data
+ java.base-jmod jdk.jlink-jmod jdk-image jre-image: generate-link-opt-data
endif
release-file: create-source-revision-tracker
--- a/make/common/Modules.gmk Thu Feb 16 17:12:58 2017 +0000
+++ b/make/common/Modules.gmk Wed Jul 05 22:52:22 2017 +0200
@@ -107,7 +107,6 @@
jdk.charsets \
jdk.crypto.ec \
jdk.crypto.cryptoki \
- jdk.desktop \
jdk.dynalink \
jdk.jsobject \
jdk.localedata \
@@ -115,6 +114,7 @@
jdk.scripting.nashorn \
jdk.security.auth \
jdk.security.jgss \
+ jdk.vm.compiler \
jdk.xml.dom \
jdk.zipfs \
#
--- a/nashorn/.hgtags Thu Feb 16 17:12:58 2017 +0000
+++ b/nashorn/.hgtags Wed Jul 05 22:52:22 2017 +0200
@@ -389,3 +389,4 @@
19aaaf2d02b7d6986538cd9a8c46901ecb50eebf jdk-9+153
a84b49cfee63716975535abae2865ffef4dd6474 jdk-9+154
f9bb37a817b3cd3b758a60f3c68258a6554eb382 jdk-9+155
+d577398d31111be4bdaa08008247cf4242eaea94 jdk-9+156
--- a/nashorn/src/jdk.dynalink/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/nashorn/src/jdk.dynalink/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -216,6 +216,8 @@
* language runtime B gets passed to code from language runtime A, the linker
* from B will get a chance to link the call site in A when it encounters the
* object from B.
+ *
+ * @since 9
*/
module jdk.dynalink {
requires java.logging;
--- a/nashorn/src/jdk.scripting.nashorn.shell/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn.shell/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -25,6 +25,8 @@
/**
* Nashorn shell module
+ *
+ * @since 9
*/
module jdk.scripting.nashorn.shell {
requires java.desktop;
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Thu Feb 16 17:12:58 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Wed Jul 05 22:52:22 2017 +0200
@@ -1372,7 +1372,7 @@
};
final Configuration cf = parent.configuration()
- .resolveRequires(finder, ModuleFinder.of(), Set.of(mn));
+ .resolve(finder, ModuleFinder.of(), Set.of(mn));
final PrivilegedAction<Layer> pa = () -> parent.defineModules(cf, name -> loader);
final Layer layer = AccessController.doPrivileged(pa, GET_LOADER_ACC_CTXT);
@@ -1798,7 +1798,7 @@
final Layer boot = Layer.boot();
final Configuration conf = boot.configuration().
- resolveRequires(mf, ModuleFinder.of(), rootMods);
+ resolve(mf, ModuleFinder.of(), rootMods);
final String firstMod = rootMods.iterator().next();
return boot.defineModulesWithOneLoader(conf, cl).findLoader(firstMod);
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptLoader.java Thu Feb 16 17:12:58 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptLoader.java Wed Jul 05 22:52:22 2017 +0200
@@ -26,9 +26,11 @@
package jdk.nashorn.internal.runtime;
import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Modifier;
import java.lang.reflect.Module;
import java.security.CodeSource;
import java.util.Objects;
+import java.util.Set;
/**
* Responsible for loading script generated classes.
@@ -69,12 +71,11 @@
private Module createModule(final String moduleName) {
final Module structMod = context.getStructLoader().getModule();
final ModuleDescriptor.Builder builder =
- ModuleDescriptor.module(moduleName)
- .requires("java.base")
+ ModuleDescriptor.newModule(moduleName, Set.of(Modifier.SYNTHETIC))
.requires("java.logging")
.requires(NASHORN_MODULE.getName())
.requires(structMod.getName())
- .contains(SCRIPTS_PKG);
+ .packages(Set.of(SCRIPTS_PKG));
if (Context.javaSqlFound) {
builder.requires("java.sql");
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StructureLoader.java Thu Feb 16 17:12:58 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StructureLoader.java Wed Jul 05 22:52:22 2017 +0200
@@ -31,8 +31,10 @@
import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_SINGLE_FIELD_PREFIX;
import java.lang.module.ModuleDescriptor;
+import java.lang.module.ModuleDescriptor.Modifier;
import java.lang.reflect.Module;
import java.security.ProtectionDomain;
+import java.util.Set;
import jdk.nashorn.internal.codegen.ObjectClassGenerator;
/**
@@ -62,12 +64,11 @@
}
private Module createModule(final String moduleName) {
- final ModuleDescriptor descriptor
- = ModuleDescriptor.module(moduleName)
- .requires("java.base")
- .requires(NASHORN_MODULE.getName())
- .contains(SCRIPTS_PKG)
- .build();
+ final ModuleDescriptor descriptor =
+ ModuleDescriptor.newModule(moduleName, Set.of(Modifier.SYNTHETIC))
+ .requires(NASHORN_MODULE.getName())
+ .packages(Set.of(SCRIPTS_PKG))
+ .build();
final Module mod = Context.createModuleTrusted(descriptor, this);
loadModuleManipulator();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/module-info.java Thu Feb 16 17:12:58 2017 +0000
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/module-info.java Wed Jul 05 22:52:22 2017 +0200
@@ -89,6 +89,8 @@
<h2>Other non-standard built-in objects</h2>
In addition to {@code Java}, Nashorn also exposes some other non-standard built-in objects:
{@code JSAdapter}, {@code JavaImporter}, {@code Packages}
+
+@since 9
*/
module jdk.scripting.nashorn {
requires java.logging;
--- a/test/TestCommon.gmk Thu Feb 16 17:12:58 2017 +0000
+++ b/test/TestCommon.gmk Wed Jul 05 22:52:22 2017 +0200
@@ -370,7 +370,7 @@
# Give tests access to JT_JAVA, see JDK-8141609
JTREG_BASIC_OPTIONS += -e:JDK8_HOME=${JT_JAVA}
# Set other vm and test options
-JTREG_TEST_OPTIONS = $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_OPTIONS:%=-vmoption:%) $(JAVA_VM_ARGS:%=-vmoption:%)
+JTREG_TEST_OPTIONS += $(JAVA_ARGS:%=-javaoptions:%) $(JAVA_OPTIONS:%=-vmoption:%) $(JAVA_VM_ARGS:%=-vmoption:%)
ifeq ($(IGNORE_MARKED_TESTS), true)
# Option to tell jtreg to not run tests marked with "ignore"