--- a/.hgtags Wed Oct 19 11:51:40 2016 +0300
+++ b/.hgtags Wed Oct 19 08:06:10 2016 -0700
@@ -382,3 +382,4 @@
9cb87c88ed851c0575b8ead753ea238ed5b544e9 jdk-9+137
d273dfe9a126d3bffe92072547fef2cd1361b0eb jdk-9+138
65477538bec32963dc41153d89c4417eb46c45fc jdk-9+139
+0875007901f7d364a08220b052f0c81003e9c8c5 jdk-9+140
--- a/.hgtags-top-repo Wed Oct 19 11:51:40 2016 +0300
+++ b/.hgtags-top-repo Wed Oct 19 08:06:10 2016 -0700
@@ -382,3 +382,4 @@
d7f519b004254b19e384131d9f0d0e40e31a0fd3 jdk-9+137
67c4388142bdf58aec8fefa4475faaa8a5d7380c jdk-9+138
7dcf453eacae79ee86a6bcc75fd0b546fc99b48a jdk-9+139
+a5815c6098a241d3a1df64d22b84b3524e4a77df jdk-9+140
--- a/common/autoconf/basics.m4 Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/basics.m4 Wed Oct 19 08:06:10 2016 -0700
@@ -428,9 +428,10 @@
# Call BASIC_SETUP_TOOL with AC_PATH_PROGS to locate the tool
# $1: variable to set
# $2: executable name (or list of names) to look for
+# $3: [path]
AC_DEFUN([BASIC_PATH_PROGS],
[
- BASIC_SETUP_TOOL($1, [AC_PATH_PROGS($1, $2)])
+ BASIC_SETUP_TOOL($1, [AC_PATH_PROGS($1, $2, , $3)])
])
# Call BASIC_SETUP_TOOL with AC_CHECK_TOOLS to locate the tool
@@ -444,9 +445,10 @@
# Like BASIC_PATH_PROGS but fails if no tool was found.
# $1: variable to set
# $2: executable name (or list of names) to look for
+# $3: [path]
AC_DEFUN([BASIC_REQUIRE_PROGS],
[
- BASIC_PATH_PROGS($1, $2)
+ BASIC_PATH_PROGS($1, $2, , $3)
BASIC_CHECK_NONEMPTY($1)
])
@@ -1065,7 +1067,9 @@
BASIC_PATH_PROGS(HG, hg)
BASIC_PATH_PROGS(STAT, stat)
BASIC_PATH_PROGS(TIME, time)
- BASIC_PATH_PROGS(DTRACE, dtrace)
+ # Dtrace is usually found in /usr/sbin on Solaris, but that directory may not
+ # be in the user path.
+ BASIC_PATH_PROGS(DTRACE, dtrace, $PATH:/usr/sbin)
BASIC_PATH_PROGS(PATCH, [gpatch patch])
# Check if it's GNU time
IS_GNU_TIME=`$TIME --version 2>&1 | $GREP 'GNU time'`
--- a/common/autoconf/basics_windows.m4 Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/basics_windows.m4 Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/common/autoconf/boot-jdk.m4 Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/boot-jdk.m4 Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/common/autoconf/bootcycle-spec.gmk.in Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/bootcycle-spec.gmk.in Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/common/autoconf/build-performance.m4 Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/build-performance.m4 Wed Oct 19 08:06:10 2016 -0700
@@ -168,7 +168,6 @@
[AS_HELP_STRING([--enable-ccache],
[enable using ccache to speed up recompilations @<:@disabled@:>@])])
- CCACHE=
CCACHE_STATUS=
AC_MSG_CHECKING([is ccache enabled])
if test "x$enable_ccache" = xyes; then
--- a/common/autoconf/buildjdk-spec.gmk.in Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/buildjdk-spec.gmk.in Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -156,7 +156,3 @@
JVM_VARIANT_ZERO := false
JVM_VARIANT_ZEROSHARK := false
JVM_VARIANT_CORE := false
-
-# Sneak this in via the spec.gmk file, since we don't want to mess around too much with the Hotspot make files.
-# This is needed to get the LOG setting to work properly.
-include $(SRC_ROOT)/make/common/MakeBase.gmk
--- a/common/autoconf/compare.sh.in Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/compare.sh.in Wed Oct 19 08:06:10 2016 -0700
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/common/autoconf/generated-configure.sh Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/generated-configure.sh Wed Oct 19 08:06:10 2016 -0700
@@ -3657,6 +3657,7 @@
# Call BASIC_SETUP_TOOL with AC_PATH_PROGS to locate the tool
# $1: variable to set
# $2: executable name (or list of names) to look for
+# $3: [path]
# Call BASIC_SETUP_TOOL with AC_CHECK_TOOLS to locate the tool
@@ -3667,6 +3668,7 @@
# Like BASIC_PATH_PROGS but fails if no tool was found.
# $1: variable to set
# $2: executable name (or list of names) to look for
+# $3: [path]
# Like BASIC_SETUP_TOOL but fails if no tool was found.
@@ -3733,7 +3735,7 @@
#
-# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -3792,7 +3794,7 @@
# ... then the rest
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -4403,7 +4405,7 @@
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -4498,7 +4500,7 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -4818,7 +4820,7 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -5091,7 +5093,7 @@
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1475218974
+DATE_WHEN_GENERATED=1476275292
###############################################################################
#
@@ -22769,6 +22771,8 @@
fi
+ # Dtrace is usually found in /usr/sbin on Solaris, but that directory may not
+ # be in the user path.
# Publish this variable in the help.
@@ -22791,7 +22795,8 @@
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+as_dummy="$PATH:/usr/sbin"
+for as_dir in $as_dummy
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
@@ -22849,7 +22854,8 @@
;;
*)
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+as_dummy="$PATH:/usr/sbin"
+for as_dir in $as_dummy
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
@@ -65239,7 +65245,6 @@
fi
- CCACHE=
CCACHE_STATUS=
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking is ccache enabled" >&5
$as_echo_n "checking is ccache enabled... " >&6; }
--- a/common/autoconf/jdk-version.m4 Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/jdk-version.m4 Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/common/autoconf/lib-bundled.m4 Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/lib-bundled.m4 Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/common/autoconf/source-dirs.m4 Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/source-dirs.m4 Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/common/autoconf/spec.gmk.in Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/spec.gmk.in Wed Oct 19 08:06:10 2016 -0700
@@ -175,7 +175,7 @@
VERSION_STRING := @VERSION_STRING@
# The short version string, without trailing zeroes and just PRE, if present.
VERSION_SHORT := @VERSION_SHORT@
-# The Java specification version. It usually equals to the major version number.
+# The Java specification version. It usually equals the major version number.
VERSION_SPECIFICATION := @VERSION_MAJOR@
# A GA version is defined by the PRE string being empty. Rather than testing for
# that, this variable defines it with true/false.
@@ -244,9 +244,6 @@
# Only build headless support or not
ENABLE_HEADLESS_ONLY := @ENABLE_HEADLESS_ONLY@
-# Legacy support
-USE_NEW_HOTSPOT_BUILD:=@USE_NEW_HOTSPOT_BUILD@
-
# JDK_OUTPUTDIR specifies where a working jvm is built.
# You can run $(JDK_OUTPUTDIR)/bin/java
# Though the layout of the contents of $(JDK_OUTPUTDIR) is not
--- a/common/autoconf/version-numbers Wed Oct 19 11:51:40 2016 +0300
+++ b/common/autoconf/version-numbers Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/common/bin/compare_exceptions.sh.incl Wed Oct 19 11:51:40 2016 +0300
+++ b/common/bin/compare_exceptions.sh.incl Wed Oct 19 08:06:10 2016 -0700
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/common/bin/hgforest.sh Wed Oct 19 11:51:40 2016 +0300
+++ b/common/bin/hgforest.sh Wed Oct 19 08:06:10 2016 -0700
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/common/bin/jib.sh Wed Oct 19 11:51:40 2016 +0300
+++ b/common/bin/jib.sh Wed Oct 19 08:06:10 2016 -0700
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/common/conf/jib-profiles.js Wed Oct 19 11:51:40 2016 +0300
+++ b/common/conf/jib-profiles.js Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -287,7 +287,8 @@
target_os: "solaris",
target_cpu: "x64",
dependencies: concat(common.dependencies, "devkit", "cups"),
- configure_args: concat(common.configure_args, "--with-zlib=system"),
+ configure_args: concat(common.configure_args, "--with-zlib=system",
+ "--enable-dtrace"),
default_make_targets: common.default_make_targets
},
@@ -295,7 +296,8 @@
target_os: "solaris",
target_cpu: "sparcv9",
dependencies: concat(common.dependencies, "devkit", "cups"),
- configure_args: concat(common.configure_args, "--with-zlib=system"),
+ configure_args: concat(common.configure_args, "--with-zlib=system",
+ "--enable-dtrace"),
default_make_targets: common.default_make_targets
},
--- a/corba/.hgtags Wed Oct 19 11:51:40 2016 +0300
+++ b/corba/.hgtags Wed Oct 19 08:06:10 2016 -0700
@@ -382,3 +382,4 @@
258cf18fa7fc59359b874f8743b7168dc48baf73 jdk-9+137
27bb44be32076861a0951bcefb07a1d92509a4b6 jdk-9+138
8c9da7fc5b07c606afd571c7012441b77dda83b2 jdk-9+139
+9f3fc931bc230f44f2a58d75f7f6360af98bb113 jdk-9+140
--- a/corba/make/gensrc/Gensrc-java.corba.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/corba/make/gensrc/Gensrc-java.corba.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/hotspot/.hgtags Wed Oct 19 11:51:40 2016 +0300
+++ b/hotspot/.hgtags Wed Oct 19 08:06:10 2016 -0700
@@ -542,3 +542,4 @@
dfcbf839e299e7e2bba1da69bdb347617ea4c7e8 jdk-9+137
fc0956308c7a586267c5dd35dff74f773aa9c3eb jdk-9+138
08492e67bf3226784dab3bf9ae967382ddbc1af5 jdk-9+139
+fec31089c2ef5a12dd64f401b0bf2e00f56ee0d0 jdk-9+140
--- a/hotspot/make/lib/CompileGtest.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/hotspot/make/lib/CompileGtest.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -69,7 +69,7 @@
CFLAGS := $(JVM_CFLAGS) -I$(GTEST_FRAMEWORK_SRC) \
-I$(GTEST_FRAMEWORK_SRC)/include \
$(addprefix -I,$(GTEST_TEST_SRC)), \
- CFLAGS_windows := /EHsc, \
+ CFLAGS_windows := -EHsc, \
CFLAGS_solaris := -DGTEST_HAS_EXCEPTIONS=0 -library=stlport4, \
CFLAGS_macosx := -DGTEST_OS_MAC=1, \
CFLAGS_DEBUG_SYMBOLS := $(JVM_CFLAGS_SYMBOLS), \
--- a/hotspot/src/share/vm/runtime/arguments.cpp Wed Oct 19 11:51:40 2016 +0300
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Oct 19 08:06:10 2016 -0700
@@ -422,6 +422,8 @@
{ "UseAltSigs", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ "SegmentedHeapDumpThreshold", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
{ "PrintOopAddress", JDK_Version::undefined(), JDK_Version::jdk(9), JDK_Version::jdk(10) },
+ { "PermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::jdk(10) },
+ { "MaxPermSize", JDK_Version::undefined(), JDK_Version::jdk(8), JDK_Version::jdk(10) },
#ifdef TEST_VERIFY_SPECIAL_JVM_FLAGS
{ "dep > obs", JDK_Version::jdk(9), JDK_Version::jdk(8), JDK_Version::undefined() },
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/runtime/CommandLine/PermGenFlagsTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,51 @@
+/*
+ * 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 8167446
+ * @summary Commandline options PermSize and MaxPermSize should be recognized but ignored.
+ * @library /test/lib
+ * @modules java.base/jdk.internal.misc
+ * java.management
+ * @run driver PermGenFlagsTest
+ */
+
+import jdk.test.lib.process.OutputAnalyzer;
+import jdk.test.lib.process.ProcessTools;
+
+public class PermGenFlagsTest {
+ public static void main(String[] args) throws Exception {
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder("-XX:PermSize=22k",
+ "-version");
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Ignoring option PermSize; support was removed in 8.0");
+ output.shouldHaveExitValue(0);
+
+ pb = ProcessTools.createJavaProcessBuilder("-XX:MaxPermSize=22k",
+ "-version");
+ output = new OutputAnalyzer(pb.start());
+ output.shouldContain("Ignoring option MaxPermSize; support was removed in 8.0");
+ output.shouldHaveExitValue(0);
+ }
+}
--- a/hotspot/test/runtime/modules/IgnoreModulePropertiesTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/hotspot/test/runtime/modules/IgnoreModulePropertiesTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -67,10 +67,11 @@
}
public static void main(String[] args) throws Exception {
- testOption("--add-modules", "java.sqlx", "jdk.module.addmods", "java.lang.module.ResolutionException");
+ testOption("--add-modules", "java.sqlx", "jdk.module.addmods.0", "java.lang.module.ResolutionException");
testOption("--limit-modules", "java.sqlx", "jdk.module.limitmods", "java.lang.module.ResolutionException");
- testOption("--add-reads", "xyzz=yyzd", "jdk.module.addreads.0", "java.lang.RuntimeException");
- testOption("--add-exports", "java.base/xyzz=yyzd", "jdk.module.addexports.0", "java.lang.RuntimeException");
+ testOption("--add-reads", "xyzz=yyzd", "jdk.module.addreads.0", "WARNING: Unknown module: xyzz");
+ testOption("--add-exports", "java.base/xyzz=yyzd", "jdk.module.addexports.0",
+ "WARNING: package xyzz not in java.base");
testOption("--patch-module", "=d", "jdk.module.patch.0", "IllegalArgumentException");
}
}
--- a/jaxp/.hgtags Wed Oct 19 11:51:40 2016 +0300
+++ b/jaxp/.hgtags Wed Oct 19 08:06:10 2016 -0700
@@ -382,3 +382,4 @@
a8d5fe567ae72b4931040e59dd4478363f9004f5 jdk-9+137
69c3b12ba75b2e321dee731ac545e7fbff608451 jdk-9+138
8991d71c5316bde259e6a417c1199b008ca3cdf0 jdk-9+139
+8d100cb9b04819b5bd09f33c7fd5b8628d1a456f jdk-9+140
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Wed Oct 19 08:06:10 2016 -0700
@@ -1342,6 +1342,12 @@
}
else {
SyntaxTreeNode parent = _parentStack.peek();
+ if (element.getClass().isAssignableFrom(Import.class) &&
+ parent.notTypeOf(Import.class)) {
+ ErrorMsg err = new ErrorMsg(ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+ prefix+':'+localname);
+ throw new SAXException(err.toString());
+ }
parent.addElement(element);
element.setParent(parent);
}
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/SyntaxTreeNode.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/SyntaxTreeNode.java Wed Oct 19 08:06:10 2016 -0700
@@ -524,6 +524,24 @@
}
/**
+ * Checks whether any children of this node is not of the specified type.
+ *
+ * @param type the type to be checked against
+ * @return true if there is at least one child that is not of the specified
+ * type, false otherwise.
+ */
+ public boolean notTypeOf(Class<?> type) {
+ if (_contents.size() > 0) {
+ for (SyntaxTreeNode item : _contents) {
+ if (!item.getClass().isAssignableFrom(type)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
* Return true if the node represents a simple RTF.
*
* A node is a simple RTF if all children only produce Text value.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Wed Oct 19 08:06:10 2016 -0700
@@ -274,6 +274,14 @@
"Circular import/include. Stylesheet ''{0}'' already loaded."},
/*
+ * Note to translators: "xsl:import" and "xsl:include" are keywords that
+ * should not be translated.
+ */
+ {ErrorMsg.IMPORT_PRECEDE_OTHERS_ERR,
+ "The xsl:import element children must precede all other element children of "
+ + "an xsl:stylesheet element, including any xsl:include element children."},
+
+ /*
* Note to translators: A result-tree fragment is a portion of a
* resulting XML document represented as a tree. "<xsl:sort>" is a
* keyword and should not be translated.
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java Wed Oct 19 08:06:10 2016 -0700
@@ -70,6 +70,7 @@
public static final String STRAY_ATTRIBUTE_ERR = "STRAY_ATTRIBUTE_ERR";
public static final String ILLEGAL_ATTRIBUTE_ERR = "ILLEGAL_ATTRIBUTE_ERR";
public static final String CIRCULAR_INCLUDE_ERR = "CIRCULAR_INCLUDE_ERR";
+ public static final String IMPORT_PRECEDE_OTHERS_ERR = "IMPORT_PRECEDE_OTHERS_ERR";
public static final String RESULT_TREE_SORT_ERR = "RESULT_TREE_SORT_ERR";
public static final String SYMBOLS_REDEF_ERR = "SYMBOLS_REDEF_ERR";
public static final String XSL_VERSION_ERR = "XSL_VERSION_ERR";
--- a/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/StAXStream2SAX.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jaxp/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/StAXStream2SAX.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -305,9 +305,12 @@
if (prefix == null) { // true for default namespace
prefix = "";
}
- _sax.startPrefixMapping(
- prefix,
- staxStreamReader.getNamespaceURI(i));
+ String uri = staxStreamReader.getNamespaceURI(i);
+ if (uri == null && prefix.isEmpty()) { // true for default namespace
+ uri = "";
+ }
+
+ _sax.startPrefixMapping(prefix, uri);
}
// fire startElement
--- a/jaxp/test/javax/xml/jaxp/unittest/parsers/Bug6341770.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jaxp/test/javax/xml/jaxp/unittest/parsers/Bug6341770.java Wed Oct 19 08:06:10 2016 -0700
@@ -28,6 +28,7 @@
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
+import java.nio.file.Paths;
import java.util.PropertyPermission;
import javax.xml.parsers.SAXParserFactory;
@@ -53,8 +54,14 @@
// naming a file "aux" would fail on windows.
@Test
public void testNonAsciiURI() {
+ if (!isNonAsciiSupported()) {
+ // @bug 8167478
+ // if it doesn't support non-ascii, the following test is invalid even if test is passed.
+ System.out.println("Current environment doesn't support non-ascii, exit the test.");
+ return;
+ }
try {
- File dir = new File("sko\u0159ice");
+ File dir = new File(ALPHA);
dir.delete();
dir.mkdir();
File main = new File(dir, "main.xml");
@@ -82,4 +89,18 @@
}
System.out.println("OK.");
}
+
+ private boolean isNonAsciiSupported() {
+ // Use Paths.get method to test if the path is valid in current environment
+ try {
+ Paths.get(ALPHA);
+ return true;
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ // Select alpha because it's a very common non-ascii character in different charsets.
+ // That this test can run in as many as possible environments if it's possible.
+ private static final String ALPHA = "\u03b1";
}
--- a/jaxp/test/javax/xml/jaxp/unittest/transform/StAXSourceTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/StAXSourceTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -30,7 +30,9 @@
import javax.xml.stream.XMLEventWriter;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
@@ -38,6 +40,7 @@
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stax.StAXResult;
import javax.xml.transform.stax.StAXSource;
+import javax.xml.transform.stream.StreamResult;
import org.testng.Assert;
import org.testng.annotations.Listeners;
@@ -45,6 +48,7 @@
/*
* @test
+ * @bug 8152530
* @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
* @run testng/othervm -DrunSecMngr=true transform.StAXSourceTest
* @run testng/othervm transform.StAXSourceTest
@@ -52,6 +56,33 @@
*/
@Listeners({jaxp.library.FilePolicy.class})
public class StAXSourceTest {
+ /**
+ * @bug 8152530
+ * Verifies that StAXSource handles empty namespace properly. NPE was thrown
+ * before the fix.
+ * @throws Exception if the test fails
+ */
+ @Test
+ public final void testStAXSourceWEmptyNS() throws Exception {
+ String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<EntityList>\n"
+ + " <Entity xmlns=\"\">\n"
+ + " </Entity>\n"
+ + " <Entity xmlns=\"\">\n"
+ + " </Entity>\n"
+ + "</EntityList> ";
+
+ XMLInputFactory xif = XMLInputFactory.newInstance();
+ XMLStreamReader xsr = xif.createXMLStreamReader(new StringReader(xml));
+ xsr.nextTag();
+ TransformerFactory tf = TransformerFactory.newInstance();
+ Transformer t = tf.newTransformer();
+ while (xsr.nextTag() == XMLStreamConstants.START_ELEMENT && xsr.getLocalName().equals("Entity")) {
+ StringWriter stringResult = new StringWriter();
+ t.transform(new StAXSource(xsr), new StreamResult(stringResult));
+ System.out.println("result: \n" + stringResult.toString());
+ }
+ }
@Test
public final void testStAXSource() throws XMLStreamException {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/StylesheetTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,149 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package transform;
+
+import java.io.StringReader;
+import org.xml.sax.InputSource;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.TransformerConfigurationException;
+import org.testng.annotations.Listeners;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/**
+ * @test
+ * @bug 8058152
+ * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest
+ * @run testng/othervm -DrunSecMngr=true transform.StylesheetTest
+ * @run testng/othervm transform.StylesheetTest
+ * @summary this test contains test cases for verifying stylesheet
+ */
+@Listeners(jaxp.library.FilePolicy.class)
+public class StylesheetTest {
+
+ /**
+ * @bug 8058152
+ * Verifies that an error is reported if the xsl:import element
+ * is not at the top of the stylesheet.
+ * @throws TransformerConfigurationException
+ */
+ @Test(dataProvider = "invalidImport", expectedExceptions = TransformerConfigurationException.class)
+ public void testInvalidImport(String xsl) throws TransformerConfigurationException {
+ StringReader xsl1 = new StringReader(xsl);
+ TransformerFactory factory = TransformerFactory.newInstance();
+ SAXSource xslSource = new SAXSource(new InputSource(xsl1));
+ Transformer transformer = factory.newTransformer(xslSource);
+ }
+
+ /**
+ * @bug 8058152
+ * Verifies that valid xsl:import elements are accepted
+ * @throws TransformerConfigurationException
+ */
+ @Test(dataProvider = "validImport")
+ public void testValidImport(String file) throws TransformerConfigurationException {
+ String xsl = getClass().getResource(file).getFile();
+ TransformerFactory factory = TransformerFactory.newInstance();
+ SAXSource xslSource = new SAXSource(new InputSource(xsl));
+ Transformer transformer = factory.newTransformer(xslSource);
+ }
+
+ /*
+ DataProvider: for testing with xsl:import placed incorrectly
+ Data: stylesheet
+ */
+ @DataProvider(name = "invalidImport")
+ public Object[][] getInvalid() {
+
+ return new Object[][]{
+ // xsl:import after template and include elements
+ {"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
+ + "\n"
+ + " <xsl:template match=\"content\">\n"
+ + " <html>\n"
+ + " <xsl:apply-templates/>\n"
+ + " </html>\n"
+ + " </xsl:template>\n"
+ + " \n"
+ + " <xsl:include href=\"XSLInclude_header.xsl\"/>\n"
+ + "\n"
+ + " <xsl:template match=\"content/title\">\n"
+ + " <h1>\n"
+ + " <xsl:apply-templates/>\n"
+ + " </h1>\n"
+ + " </xsl:template>\n"
+ + " \n"
+ + " <xsl:import href=\"XSLInclude_footer.xsl\"/>\n"
+ + "\n"
+ + "</xsl:stylesheet>"},
+
+ // xsl:import inside template
+ {"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
+ + "\n"
+ + " <xsl:template match=\"content\">\n"
+ + " <xsl:import href=\"XSLInclude_header.xsl\"/>"
+ + " <html>\n"
+ + " <xsl:apply-templates/>\n"
+ + " </html>\n"
+ + " </xsl:template>\n"
+ + "\n"
+ + "</xsl:stylesheet>"},
+
+ // xsl:import after xsl:include
+ {"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+ + "<xsl:stylesheet xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\" version=\"1.0\">\n"
+ + " <xsl:include href=\"XSLInclude_header.xsl\"/>\n"
+ + " <xsl:import href=\"XSLInclude_footer.xsl\"/>\n"
+ + "\n"
+ + " <xsl:template match=\"content/title\">\n"
+ + " <h1>\n"
+ + " <xsl:apply-templates/>\n"
+ + " </h1>\n"
+ + " </xsl:template>\n"
+ + "\n"
+ + "</xsl:stylesheet>"}
+ };
+ }
+
+ /*
+ DataProvider: for testing with xsl:import placed correctly
+ Data: path to stylesheet
+ */
+ @DataProvider(name = "validImport")
+ public Object[][] getValid() {
+
+ return new Object[][]{
+ // xsl:import at the top
+ {"XSLInclude_main.xsl"},
+
+ // two xsl:import elements at the top
+ {"XSLImport.xsl"}
+ };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/XSLImport.xsl Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,21 @@
+<?xml version="1.1" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:import href="XSLInclude_header.xsl"/>
+ <xsl:import href="XSLInclude_footer.xsl"/>
+
+ <xsl:template match="content">
+ <html>
+ <xsl:apply-templates/>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="content/title">
+ <h1>
+ <xsl:apply-templates/>
+ </h1>
+ </xsl:template>
+
+
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/XSLInclude_footer.xsl Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:template match="footer">
+ <dv id="footer"><xsl:apply-templates/></dv>
+ </xsl:template>
+
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/XSLInclude_header.xsl Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:template match="header">
+ <h4><xsl:apply-templates/></h4>
+ </xsl:template>
+
+</xsl:stylesheet>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jaxp/test/javax/xml/jaxp/unittest/transform/XSLInclude_main.xsl Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,20 @@
+<?xml version="1.1" encoding="UTF-8"?>
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
+
+ <xsl:import href="XSLInclude_header.xsl"/>
+
+ <xsl:template match="content">
+ <html>
+ <xsl:apply-templates/>
+ </html>
+ </xsl:template>
+
+ <xsl:template match="content/title">
+ <h1>
+ <xsl:apply-templates/>
+ </h1>
+ </xsl:template>
+
+ <xsl:include href="XSLInclude_footer.xsl"/>
+
+</xsl:stylesheet>
\ No newline at end of file
--- a/jaxws/.hgtags Wed Oct 19 11:51:40 2016 +0300
+++ b/jaxws/.hgtags Wed Oct 19 08:06:10 2016 -0700
@@ -385,3 +385,4 @@
297c16d401c534cb879809d2a746d21ca99d2954 jdk-9+137
7d3a8f52b124db26ba8425c2931b748dd9d2791b jdk-9+138
7a7aadf3c4500cc273c889aa1172d4fe3844bb6b jdk-9+139
+9004617323fe99cbe4fad48f373cb2ed4fc50aa6 jdk-9+140
--- a/jdk/src/java.base/share/classes/java/lang/Class.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/Class.java Wed Oct 19 08:06:10 2016 -0700
@@ -557,7 +557,7 @@
Class<?> caller = Reflection.getCallerClass();
if (newInstanceCallerCache != caller) {
int modifiers = tmpConstructor.getModifiers();
- Reflection.ensureMemberAccess(caller, this, null, modifiers);
+ Reflection.ensureMemberAccess(caller, this, this, modifiers);
newInstanceCallerCache = caller;
}
// Run constructor
--- a/jdk/src/java.base/share/classes/java/lang/Deprecated.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/Deprecated.java Wed Oct 19 08:06:10 2016 -0700
@@ -79,7 +79,7 @@
/**
* Returns the version in which the annotated element became deprecated.
* The version string is in the same format and namespace as the value of
- * the {@code @since} javadoc tag. The default value is the empty
+ * the {@code @since} javadoc tag. The default value is the empty
* string.
*
* @return the version string
--- a/jdk/src/java.base/share/classes/java/lang/Thread.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/Thread.java Wed Oct 19 08:06:10 2016 -0700
@@ -504,11 +504,12 @@
}
/**
- * Creates a new Thread that inherits the given AccessControlContext.
+ * Creates a new Thread that inherits the given AccessControlContext
+ * but thread-local variables are not inherited.
* This is not a public constructor.
*/
Thread(Runnable target, AccessControlContext acc) {
- init(null, target, "Thread-" + nextThreadNum(), 0, acc, true);
+ init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}
/**
--- a/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/module/SystemModuleFinder.java Wed Oct 19 08:06:10 2016 -0700
@@ -44,6 +44,8 @@
import jdk.internal.jimage.ImageLocation;
import jdk.internal.jimage.ImageReader;
import jdk.internal.jimage.ImageReaderFactory;
+import jdk.internal.misc.JavaNetUriAccess;
+import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.ModuleHashes;
import jdk.internal.module.ModuleHashes.HashSupplier;
import jdk.internal.module.SystemModules;
@@ -71,6 +73,8 @@
// ImageReader used to access all modules in the image
private static final ImageReader imageReader;
+ private static final JavaNetUriAccess jnua = SharedSecrets.getJavaNetUriAccess();
+
// the set of modules in the run-time image
private static final Set<ModuleReference> modules;
@@ -166,7 +170,8 @@
HashSupplier hash)
{
String mn = md.name();
- URI uri = URI.create("jrt:/" + mn);
+
+ URI uri = jnua.create("jrt", "/".concat(mn));
Supplier<ModuleReader> readerSupplier = new Supplier<>() {
@Override
--- a/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java Wed Oct 19 08:06:10 2016 -0700
@@ -312,22 +312,22 @@
// (See also Class.newInstance(), which uses a similar method.)
//
// A more complicated security check cache is needed for Method and Field
- // The cache can be either null (empty cache), a 2-array of {caller,target},
- // or a caller (with target implicitly equal to this.clazz).
- // In the 2-array case, the target is always different from the clazz.
+ // The cache can be either null (empty cache), a 2-array of {caller,targetClass},
+ // or a caller (with targetClass implicitly equal to memberClass).
+ // In the 2-array case, the targetClass is always different from the memberClass.
volatile Object securityCheckCache;
- void checkAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers)
+ final void checkAccess(Class<?> caller, Class<?> memberClass,
+ Class<?> targetClass, int modifiers)
throws IllegalAccessException
{
- if (caller == clazz) { // quick check
+ if (caller == memberClass) { // quick check
return; // ACCESS IS OK
}
Object cache = securityCheckCache; // read volatile
- Class<?> targetClass = clazz;
- if (obj != null
+ if (targetClass != null // instance member or constructor
&& Modifier.isProtected(modifiers)
- && ((targetClass = obj.getClass()) != clazz)) {
+ && targetClass != memberClass) {
// Must match a 2-list of { caller, targetClass }.
if (cache instanceof Class[]) {
Class<?>[] cache2 = (Class<?>[]) cache;
@@ -339,25 +339,27 @@
// subsumes range check for [0].)
}
} else if (cache == caller) {
- // Non-protected case (or obj.class == this.clazz).
+ // Non-protected case (or targetClass == memberClass or static member).
return; // ACCESS IS OK
}
// If no return, fall through to the slow path.
- slowCheckMemberAccess(caller, clazz, obj, modifiers, targetClass);
+ slowCheckMemberAccess(caller, memberClass, targetClass, modifiers);
}
// Keep all this slow stuff out of line:
- void slowCheckMemberAccess(Class<?> caller, Class<?> clazz, Object obj, int modifiers,
- Class<?> targetClass)
+ void slowCheckMemberAccess(Class<?> caller, Class<?> memberClass,
+ Class<?> targetClass, int modifiers)
throws IllegalAccessException
{
- Reflection.ensureMemberAccess(caller, clazz, obj, modifiers);
+ Reflection.ensureMemberAccess(caller, memberClass, targetClass, modifiers);
// Success: Update the cache.
- Object cache = ((targetClass == clazz)
- ? caller
- : new Class<?>[] { caller, targetClass });
+ Object cache = (targetClass != null
+ && Modifier.isProtected(modifiers)
+ && targetClass != memberClass)
+ ? new Class<?>[] { caller, targetClass }
+ : caller;
// Note: The two cache elements are not volatile,
// but they are effectively final. The Java memory model
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Constructor.java Wed Oct 19 08:06:10 2016 -0700
@@ -443,7 +443,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, null, modifiers);
+ checkAccess(caller, clazz, clazz, modifiers);
}
if ((clazz.getModifiers() & Modifier.ENUM) != 0)
throw new IllegalArgumentException("Cannot reflectively create enum objects");
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Field.java Wed Oct 19 08:06:10 2016 -0700
@@ -403,7 +403,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).get(obj);
}
@@ -437,7 +437,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getBoolean(obj);
}
@@ -471,7 +471,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getByte(obj);
}
@@ -507,7 +507,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getChar(obj);
}
@@ -543,7 +543,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getShort(obj);
}
@@ -579,7 +579,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getInt(obj);
}
@@ -615,7 +615,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getLong(obj);
}
@@ -651,7 +651,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getFloat(obj);
}
@@ -687,7 +687,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
return getFieldAccessor(obj).getDouble(obj);
}
@@ -765,7 +765,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).set(obj, value);
}
@@ -801,7 +801,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setBoolean(obj, z);
}
@@ -837,7 +837,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setByte(obj, b);
}
@@ -873,7 +873,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setChar(obj, c);
}
@@ -909,7 +909,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setShort(obj, s);
}
@@ -945,7 +945,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setInt(obj, i);
}
@@ -981,7 +981,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setLong(obj, l);
}
@@ -1017,7 +1017,7 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setFloat(obj, f);
}
@@ -1053,11 +1053,20 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, obj);
}
getFieldAccessor(obj).setDouble(obj, d);
}
+ // check access to field
+ private void checkAccess(Class<?> caller, Object obj)
+ throws IllegalAccessException
+ {
+ checkAccess(caller, clazz,
+ Modifier.isStatic(modifiers) ? null : obj.getClass(),
+ modifiers);
+ }
+
// security check is done before calling this method
private FieldAccessor getFieldAccessor(Object obj)
throws IllegalAccessException
--- a/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/lang/reflect/Method.java Wed Oct 19 08:06:10 2016 -0700
@@ -526,7 +526,9 @@
{
if (!override) {
Class<?> caller = Reflection.getCallerClass();
- checkAccess(caller, clazz, obj, modifiers);
+ checkAccess(caller, clazz,
+ Modifier.isStatic(modifiers) ? null : obj.getClass(),
+ modifiers);
}
MethodAccessor ma = methodAccessor; // read volatile
if (ma == null) {
--- a/jdk/src/java.base/share/classes/java/net/URI.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/net/URI.java Wed Oct 19 08:06:10 2016 -0700
@@ -37,6 +37,9 @@
import java.nio.charset.CodingErrorAction;
import java.nio.charset.CharacterCodingException;
import java.text.Normalizer;
+import jdk.internal.loader.URLClassPath;
+import jdk.internal.misc.JavaNetUriAccess;
+import jdk.internal.misc.SharedSecrets;
import sun.nio.cs.ThreadLocalCoders;
import java.lang.Character; // for javadoc
@@ -820,6 +823,25 @@
}
/**
+ * Constructs a simple URI consisting of only a scheme and a pre-validated
+ * path. Provides a fast-path for some internal cases.
+ */
+ URI(String scheme, String path) {
+ assert validSchemeAndPath(scheme, path);
+ this.scheme = scheme;
+ this.path = path;
+ }
+
+ private static boolean validSchemeAndPath(String scheme, String path) {
+ try {
+ URI u = new URI(scheme + ":" + path);
+ return scheme.equals(u.scheme) && path.equals(u.path);
+ } catch (URISyntaxException e) {
+ return false;
+ }
+ }
+
+ /**
* Creates a URI by parsing the given string.
*
* <p> This convenience factory method works as if by invoking the {@link
@@ -3571,5 +3593,13 @@
}
}
-
+ static {
+ SharedSecrets.setJavaNetUriAccess(
+ new JavaNetUriAccess() {
+ public URI create(String scheme, String path) {
+ return new URI(scheme, path);
+ }
+ }
+ );
+ }
}
--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Wed Oct 19 08:06:10 2016 -0700
@@ -51,8 +51,6 @@
import jdk.internal.loader.Resource;
import jdk.internal.loader.URLClassPath;
-import jdk.internal.misc.JavaNetAccess;
-import jdk.internal.misc.SharedSecrets;
import jdk.internal.perf.PerfCounter;
import sun.net.www.ParseUtil;
import sun.security.util.SecurityConstants;
@@ -767,13 +765,6 @@
}
static {
- SharedSecrets.setJavaNetAccess(
- new JavaNetAccess() {
- public URLClassPath getURLClassPath(URLClassLoader u) {
- return u.ucp;
- }
- }
- );
ClassLoader.registerAsParallelCapable();
}
}
--- a/jdk/src/java.base/share/classes/java/time/Instant.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/time/Instant.java Wed Oct 19 08:06:10 2016 -0700
@@ -610,7 +610,7 @@
* <p>
* The epoch second count is a simple incrementing count of seconds where
* second 0 is 1970-01-01T00:00:00Z.
- * The nanosecond part of the day is returned by {@code getNanosOfSecond}.
+ * The nanosecond part of the day is returned by {@link #getNano}.
*
* @return the seconds from the epoch of 1970-01-01T00:00:00Z
*/
@@ -623,7 +623,7 @@
* of the second.
* <p>
* The nanosecond-of-second value measures the total number of nanoseconds from
- * the second returned by {@code getEpochSecond}.
+ * the second returned by {@link #getEpochSecond}.
*
* @return the nanoseconds within the second, always positive, never exceeds 999,999,999
*/
--- a/jdk/src/java.base/share/classes/java/util/Date.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/java/util/Date.java Wed Oct 19 08:06:10 2016 -0700
@@ -85,12 +85,12 @@
* further information is the U.S. Naval Observatory, particularly
* the Directorate of Time at:
* <blockquote><pre>
- * <a href=http://tycho.usno.navy.mil>http://tycho.usno.navy.mil</a>
+ * <a href="http://www.usno.navy.mil">http://www.usno.navy.mil</a>
* </pre></blockquote>
* <p>
* and their definitions of "Systems of Time" at:
* <blockquote><pre>
- * <a href=http://tycho.usno.navy.mil/systime.html>http://tycho.usno.navy.mil/systime.html</a>
+ * <a href="http://www.usno.navy.mil/USNO/time/master-clock/systems-of-time">http://www.usno.navy.mil/USNO/time/master-clock/systems-of-time</a>
* </pre></blockquote>
* <p>
* In all methods of class {@code Date} that accept or return
--- a/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/jdk/internal/jmod/JmodFile.java Wed Oct 19 08:06:10 2016 -0700
@@ -71,7 +71,9 @@
NATIVE_LIBS("native"),
NATIVE_CMDS("bin"),
CLASSES("classes"),
- CONFIG("conf");
+ CONFIG("conf"),
+ HEADER_FILES("include"),
+ MAN_PAGES("man");
private final String jmodDir;
private Section(String jmodDir) {
@@ -151,6 +153,10 @@
return Section.CLASSES;
case "conf":
return Section.CONFIG;
+ case "include":
+ return Section.HEADER_FILES;
+ case "man":
+ return Section.MAN_PAGES;
default:
throw new IllegalArgumentException("invalid section: " + s);
}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetAccess.java Wed Oct 19 11:51:40 2016 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.internal.misc;
-
-import java.net.URLClassLoader;
-import jdk.internal.loader.URLClassPath;
-
-public interface JavaNetAccess {
- /**
- * return the URLClassPath belonging to the given loader
- */
- URLClassPath getURLClassPath (URLClassLoader u);
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/JavaNetUriAccess.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.internal.misc;
+
+import java.net.URI;
+
+public interface JavaNetUriAccess {
+ /**
+ * Create a URI of pre-validated scheme and path.
+ */
+ URI create(String scheme, String path);
+}
--- a/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/jdk/internal/misc/SharedSecrets.java Wed Oct 19 08:06:10 2016 -0700
@@ -53,10 +53,10 @@
private static JavaLangInvokeAccess javaLangInvokeAccess;
private static JavaLangRefAccess javaLangRefAccess;
private static JavaIOAccess javaIOAccess;
- private static JavaNetAccess javaNetAccess;
private static JavaNetInetAddressAccess javaNetInetAddressAccess;
private static JavaNetHttpCookieAccess javaNetHttpCookieAccess;
private static JavaNetSocketAccess javaNetSocketAccess;
+ private static JavaNetUriAccess javaNetUriAccess;
private static JavaNioAccess javaNioAccess;
private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess;
private static JavaIOFilePermissionAccess javaIOFilePermissionAccess;
@@ -134,14 +134,14 @@
return javaLangRefAccess;
}
- public static void setJavaNetAccess(JavaNetAccess jna) {
- javaNetAccess = jna;
+ public static void setJavaNetUriAccess(JavaNetUriAccess jnua) {
+ javaNetUriAccess = jnua;
}
- public static JavaNetAccess getJavaNetAccess() {
- if (javaNetAccess == null)
- unsafe.ensureClassInitialized(java.net.URLClassLoader.class);
- return javaNetAccess;
+ public static JavaNetUriAccess getJavaNetUriAccess() {
+ if (javaNetUriAccess == null)
+ unsafe.ensureClassInitialized(java.net.URI.class);
+ return javaNetUriAccess;
}
public static void setJavaNetInetAddressAccess(JavaNetInetAddressAccess jna) {
--- a/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/jdk/internal/reflect/Reflection.java Wed Oct 19 08:06:10 2016 -0700
@@ -84,9 +84,22 @@
public static native int getClassAccessFlags(Class<?> c);
+ /**
+ * Ensures that access to a member is granted and throws
+ * IllegalAccessException if not.
+ *
+ * @param currentClass the class performing the access
+ * @param memberClass the declaring class of the member being accessed
+ * @param targetClass the class of target object if accessing instance
+ * field or method;
+ * or the declaring class if accessing constructor;
+ * or null if accessing static field or method
+ * @param modifiers the member's access modifiers
+ * @throws IllegalAccessException if access to member is denied
+ */
public static void ensureMemberAccess(Class<?> currentClass,
Class<?> memberClass,
- Object target,
+ Class<?> targetClass,
int modifiers)
throws IllegalAccessException
{
@@ -94,18 +107,15 @@
throw new InternalError();
}
- if (!verifyMemberAccess(currentClass, memberClass, target, modifiers)) {
- throwIllegalAccessException(currentClass, memberClass, target, modifiers);
+ if (!verifyMemberAccess(currentClass, memberClass, targetClass, modifiers)) {
+ throwIllegalAccessException(currentClass, memberClass, targetClass, modifiers);
}
}
- public static boolean verifyMemberAccess(Class<?> currentClass,
- // Declaring class of field
- // or method
- Class<?> memberClass,
- // May be NULL in case of statics
- Object target,
- int modifiers)
+ private static boolean verifyMemberAccess(Class<?> currentClass,
+ Class<?> memberClass,
+ Class<?> targetClass,
+ int modifiers)
{
// Verify that currentClass can access a field, method, or
// constructor of memberClass, where that member's access bits are
@@ -162,18 +172,18 @@
return false;
}
- if (Modifier.isProtected(modifiers)) {
- // Additional test for protected members: JLS 6.6.2
- Class<?> targetClass = (target == null ? memberClass : target.getClass());
- if (targetClass != currentClass) {
- if (!gotIsSameClassPackage) {
- isSameClassPackage = isSameClassPackage(currentClass, memberClass);
- gotIsSameClassPackage = true;
- }
- if (!isSameClassPackage) {
- if (!isSubclassOf(targetClass, currentClass)) {
- return false;
- }
+ // Additional test for protected instance members
+ // and protected constructors: JLS 6.6.2
+ if (targetClass != null && Modifier.isProtected(modifiers) &&
+ targetClass != currentClass)
+ {
+ if (!gotIsSameClassPackage) {
+ isSameClassPackage = isSameClassPackage(currentClass, memberClass);
+ gotIsSameClassPackage = true;
+ }
+ if (!isSameClassPackage) {
+ if (!isSubclassOf(targetClass, currentClass)) {
+ return false;
}
}
}
--- a/jdk/src/java.base/share/classes/module-info.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/module-info.java Wed Oct 19 08:06:10 2016 -0700
@@ -171,8 +171,10 @@
jdk.jartool,
jdk.jdeps,
jdk.jlink,
+ jdk.jshell,
jdk.net,
jdk.scripting.nashorn,
+ jdk.scripting.nashorn.shell,
jdk.unsupported,
jdk.vm.ci;
exports jdk.internal.perf to
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java Wed Oct 19 08:06:10 2016 -0700
@@ -25,8 +25,11 @@
package sun.net.www.protocol.http;
+import java.util.Collections;
import java.util.Iterator;
import java.util.HashMap;
+import java.util.Set;
+
import sun.net.www.*;
import sun.security.action.GetPropertyAction;
@@ -67,8 +70,8 @@
* -Dhttp.auth.preference="scheme"
*
* which in this case, specifies that "scheme" should be used as the auth scheme when offered
- * disregarding the default prioritisation. If scheme is not offered then the default priority
- * is used.
+ * disregarding the default prioritisation. If scheme is not offered, or explicitly
+ * disabled, by {@code disabledSchemes}, then the default priority is used.
*
* Attention: when http.auth.preference is set as SPNEGO or Kerberos, it's actually "Negotiate
* with SPNEGO" or "Negotiate with Kerberos", which means the user will prefer the Negotiate
@@ -113,17 +116,32 @@
String hdrname; // Name of the header to look for
/**
- * parse a set of authentication headers and choose the preferred scheme
- * that we support for a given host
+ * Parses a set of authentication headers and chooses the preferred scheme
+ * that is supported for a given host.
*/
public AuthenticationHeader (String hdrname, MessageHeader response,
HttpCallerInfo hci, boolean dontUseNegotiate) {
+ this(hdrname, response, hci, dontUseNegotiate, Collections.emptySet());
+ }
+
+ /**
+ * Parses a set of authentication headers and chooses the preferred scheme
+ * that is supported for a given host.
+ *
+ * <p> The {@code disabledSchemes} parameter is a, possibly empty, set of
+ * authentication schemes that are disabled.
+ */
+ public AuthenticationHeader(String hdrname,
+ MessageHeader response,
+ HttpCallerInfo hci,
+ boolean dontUseNegotiate,
+ Set<String> disabledSchemes) {
this.hci = hci;
this.dontUseNegotiate = dontUseNegotiate;
- rsp = response;
+ this.rsp = response;
this.hdrname = hdrname;
- schemes = new HashMap<>();
- parse();
+ this.schemes = new HashMap<>();
+ parse(disabledSchemes);
}
public HttpCallerInfo getHttpCallerInfo() {
@@ -143,10 +161,11 @@
* then the last one will be used. The
* preferred scheme that we support will be used.
*/
- private void parse () {
+ private void parse(Set<String> disabledSchemes) {
Iterator<String> iter = rsp.multiValueIterator(hdrname);
while (iter.hasNext()) {
String raw = iter.next();
+ // HeaderParser lower cases everything, so can be used case-insensitively
HeaderParser hp = new HeaderParser(raw);
Iterator<String> keys = hp.keys();
int i, lastSchemeIndex;
@@ -156,7 +175,8 @@
if (lastSchemeIndex != -1) {
HeaderParser hpn = hp.subsequence (lastSchemeIndex, i);
String scheme = hpn.findKey(0);
- schemes.put (scheme, new SchemeMapValue (hpn, raw));
+ if (!disabledSchemes.contains(scheme))
+ schemes.put(scheme, new SchemeMapValue (hpn, raw));
}
lastSchemeIndex = i;
}
@@ -164,7 +184,8 @@
if (i > lastSchemeIndex) {
HeaderParser hpn = hp.subsequence (lastSchemeIndex, i);
String scheme = hpn.findKey(0);
- schemes.put(scheme, new SchemeMapValue (hpn, raw));
+ if (!disabledSchemes.contains(scheme))
+ schemes.put(scheme, new SchemeMapValue (hpn, raw));
}
}
--- a/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java Wed Oct 19 08:06:10 2016 -0700
@@ -25,6 +25,7 @@
package sun.net.www.protocol.http;
+import java.security.PrivilegedAction;
import java.util.Arrays;
import java.net.URL;
import java.net.URLConnection;
@@ -109,6 +110,14 @@
static final boolean validateProxy;
static final boolean validateServer;
+ /** A, possibly empty, set of authentication schemes that are disabled
+ * when proxying plain HTTP ( not HTTPS ). */
+ static final Set<String> disabledProxyingSchemes;
+
+ /** A, possibly empty, set of authentication schemes that are disabled
+ * when setting up a tunnel for HTTPS ( HTTP CONNECT ). */
+ static final Set<String> disabledTunnelingSchemes;
+
private StreamingOutputStream strOutputStream;
private static final String RETRY_MSG1 =
"cannot retry due to proxy authentication, in streaming mode";
@@ -206,6 +215,22 @@
"Via"
};
+ private static String getNetProperty(String name) {
+ PrivilegedAction<String> pa = () -> NetProperties.get(name);
+ return AccessController.doPrivileged(pa);
+ }
+
+ private static Set<String> schemesListToSet(String list) {
+ if (list == null || list.isEmpty())
+ return Collections.emptySet();
+
+ Set<String> s = new HashSet<>();
+ String[] parts = list.split("\\s*,\\s*");
+ for (String part : parts)
+ s.add(part.toLowerCase(Locale.ROOT));
+ return s;
+ }
+
static {
Properties props = GetPropertyAction.privilegedGetProperties();
maxRedirects = GetIntegerAction.privilegedGetProperty(
@@ -218,6 +243,14 @@
agent = agent + " Java/"+version;
}
userAgent = agent;
+
+ // A set of net properties to control the use of authentication schemes
+ // when proxing/tunneling.
+ String p = getNetProperty("jdk.http.auth.tunneling.disabledSchemes");
+ disabledTunnelingSchemes = schemesListToSet(p);
+ p = getNetProperty("jdk.http.auth.proxying.disabledSchemes");
+ disabledProxyingSchemes = schemesListToSet(p);
+
validateProxy = Boolean.parseBoolean(
props.getProperty("http.auth.digest.validateProxy"));
validateServer = Boolean.parseBoolean(
@@ -1575,10 +1608,13 @@
// altered in similar ways.
AuthenticationHeader authhdr = new AuthenticationHeader (
- "Proxy-Authenticate", responses,
- new HttpCallerInfo(url, http.getProxyHostUsed(),
- http.getProxyPortUsed()),
- dontUseNegotiate
+ "Proxy-Authenticate",
+ responses,
+ new HttpCallerInfo(url,
+ http.getProxyHostUsed(),
+ http.getProxyPortUsed()),
+ dontUseNegotiate,
+ disabledProxyingSchemes
);
if (!doingNTLMp2ndStage) {
@@ -2024,11 +2060,14 @@
}
}
- AuthenticationHeader authhdr = new AuthenticationHeader (
- "Proxy-Authenticate", responses,
- new HttpCallerInfo(url, http.getProxyHostUsed(),
- http.getProxyPortUsed()),
- dontUseNegotiate
+ AuthenticationHeader authhdr = new AuthenticationHeader(
+ "Proxy-Authenticate",
+ responses,
+ new HttpCallerInfo(url,
+ http.getProxyHostUsed(),
+ http.getProxyPortUsed()),
+ dontUseNegotiate,
+ disabledTunnelingSchemes
);
if (!doingNTLMp2ndStage) {
proxyAuthentication =
--- a/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/reflect/misc/ReflectUtil.java Wed Oct 19 08:06:10 2016 -0700
@@ -44,9 +44,21 @@
return Class.forName(name);
}
- /*
- * Reflection.ensureMemberAccess is overly-restrictive
- * due to a bug. We awkwardly work around it for now.
+ /**
+ * Ensures that access to a method or field is granted and throws
+ * IllegalAccessException if not. This method is not suitable for checking
+ * access to constructors.
+ *
+ * @param currentClass the class performing the access
+ * @param memberClass the declaring class of the member being accessed
+ * @param target the target object if accessing instance field or method;
+ * or null if accessing static field or method or if target
+ * object access rights will be checked later
+ * @param modifiers the member's access modifiers
+ * @throws IllegalAccessException if access to member is denied
+ * @implNote Delegates directly to
+ * {@link Reflection#ensureMemberAccess(Class, Class, Class, int)}
+ * which should be used instead.
*/
public static void ensureMemberAccess(Class<?> currentClass,
Class<?> memberClass,
@@ -54,62 +66,10 @@
int modifiers)
throws IllegalAccessException
{
- if (target == null && Modifier.isProtected(modifiers)) {
- int mods = modifiers;
- mods = mods & (~Modifier.PROTECTED);
- mods = mods | Modifier.PUBLIC;
-
- /*
- * See if we fail because of class modifiers
- */
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- mods);
- try {
- /*
- * We're still here so class access was ok.
- * Now try with default field access.
- */
- mods = mods & (~Modifier.PUBLIC);
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- mods);
- /*
- * We're still here so access is ok without
- * checking for protected.
- */
- return;
- } catch (IllegalAccessException e) {
- /*
- * Access failed but we're 'protected' so
- * if the test below succeeds then we're ok.
- */
- if (isSubclassOf(currentClass, memberClass)) {
- return;
- } else {
- throw e;
- }
- }
- } else {
- Reflection.ensureMemberAccess(currentClass,
- memberClass,
- target,
- modifiers);
- }
- }
-
- private static boolean isSubclassOf(Class<?> queryClass,
- Class<?> ofClass)
- {
- while (queryClass != null) {
- if (queryClass == ofClass) {
- return true;
- }
- queryClass = queryClass.getSuperclass();
- }
- return false;
+ Reflection.ensureMemberAccess(currentClass,
+ memberClass,
+ target == null ? null : target.getClass(),
+ modifiers);
}
/**
--- a/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/pkcs/SignerInfo.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,20 +28,38 @@
import java.io.OutputStream;
import java.io.IOException;
import java.math.BigInteger;
+import java.security.CryptoPrimitive;
+import java.security.InvalidKeyException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.PublicKey;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.Timestamp;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
-import java.security.*;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.EnumSet;
+import java.util.Set;
import sun.security.timestamp.TimestampToken;
-import sun.security.util.*;
+import sun.security.util.Debug;
+import sun.security.util.DerEncoder;
+import sun.security.util.DerInputStream;
+import sun.security.util.DerOutputStream;
+import sun.security.util.DerValue;
+import sun.security.util.DisabledAlgorithmConstraints;
+import sun.security.util.HexDumpEncoder;
+import sun.security.util.KeyUtil;
+import sun.security.util.ObjectIdentifier;
import sun.security.x509.AlgorithmId;
import sun.security.x509.X500Name;
import sun.security.x509.KeyUsageExtension;
-import sun.security.util.HexDumpEncoder;
/**
* A SignerInfo, as defined in PKCS#7's signedData type.
@@ -50,6 +68,17 @@
*/
public class SignerInfo implements DerEncoder {
+ // Digest and Signature restrictions
+ private static final Set<CryptoPrimitive> DIGEST_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.MESSAGE_DIGEST));
+
+ private static final Set<CryptoPrimitive> SIG_PRIMITIVE_SET =
+ Collections.unmodifiableSet(EnumSet.of(CryptoPrimitive.SIGNATURE));
+
+ private static final DisabledAlgorithmConstraints JAR_DISABLED_CHECK =
+ new DisabledAlgorithmConstraints(
+ DisabledAlgorithmConstraints.PROPERTY_JAR_DISABLED_ALGS);
+
BigInteger version;
X500Name issuerName;
BigInteger certificateSerialNumber;
@@ -318,6 +347,13 @@
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);
+ }
+
MessageDigest md = MessageDigest.getInstance(digestAlgname);
byte[] computedMessageDigest = md.digest(data);
@@ -349,12 +385,26 @@
String algname = AlgorithmId.makeSigAlg(
digestAlgname, encryptionAlgname);
- Signature sig = Signature.getInstance(algname);
+ // 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);
+ }
+
X509Certificate cert = getCertificate(block);
-
+ PublicKey key = cert.getPublicKey();
if (cert == null) {
return null;
}
+
+ // check if the public key is restricted
+ if (!JAR_DISABLED_CHECK.permits(SIG_PRIMITIVE_SET, key)) {
+ throw new SignatureException("Public key check failed. " +
+ "Disabled key used: " +
+ KeyUtil.getKeySize(key) + " bit " +
+ key.getAlgorithm());
+ }
+
if (cert.hasUnsupportedCriticalExtension()) {
throw new SignatureException("Certificate has unsupported "
+ "critical extension(s)");
@@ -391,11 +441,9 @@
}
}
- PublicKey key = cert.getPublicKey();
+ Signature sig = Signature.getInstance(algname);
sig.initVerify(key);
-
sig.update(dataSigned);
-
if (sig.verify(encryptedDigest)) {
return this;
}
@@ -515,9 +563,16 @@
*/
private void verifyTimestamp(TimestampToken token)
throws NoSuchAlgorithmException, SignatureException {
+ String digestAlgname = token.getHashAlgorithm().getName();
+ // check that algorithm is not restricted
+ if (!JAR_DISABLED_CHECK.permits(DIGEST_PRIMITIVE_SET, digestAlgname,
+ null)) {
+ throw new SignatureException("Timestamp token digest check failed. " +
+ "Disabled algorithm used: " + digestAlgname);
+ }
MessageDigest md =
- MessageDigest.getInstance(token.getHashAlgorithm().getName());
+ MessageDigest.getInstance(digestAlgname);
if (!Arrays.equals(token.getHashedMessage(),
md.digest(encryptedDigest))) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/AlgorithmChecker.java Wed Oct 19 08:06:10 2016 -0700
@@ -185,20 +185,22 @@
AlgorithmConstraints constraints,
Date pkixdate) {
- if (anchor == null) {
- throw new IllegalArgumentException(
- "The trust anchor cannot be null");
- }
-
- if (anchor.getTrustedCert() != null) {
- this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
- // Check for anchor certificate restrictions
- trustedMatch = checkFingerprint(anchor.getTrustedCert());
- if (trustedMatch && debug != null) {
- debug.println("trustedMatch = true");
+ if (anchor != null) {
+ if (anchor.getTrustedCert() != null) {
+ this.trustedPubKey = anchor.getTrustedCert().getPublicKey();
+ // Check for anchor certificate restrictions
+ trustedMatch = checkFingerprint(anchor.getTrustedCert());
+ if (trustedMatch && debug != null) {
+ debug.println("trustedMatch = true");
+ }
+ } else {
+ this.trustedPubKey = anchor.getCAPublicKey();
}
} else {
- this.trustedPubKey = anchor.getCAPublicKey();
+ this.trustedPubKey = null;
+ if (debug != null) {
+ debug.println("TrustAnchor is null, trustedMatch is false.");
+ }
}
this.prevPubKey = trustedPubKey;
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/ForwardBuilder.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -816,18 +816,22 @@
/**
* Verifies whether the input certificate completes the path.
- * Checks the cert against each trust anchor that was specified, in order,
- * and returns true as soon as it finds a valid anchor.
- * Returns true if the cert matches a trust anchor specified as a
- * certificate or if the cert verifies with a trust anchor that
- * was specified as a trusted {pubkey, caname} pair. Returns false if none
- * of the trust anchors are valid for this cert.
+ * First checks the cert against each trust anchor that was specified,
+ * in order, and returns true if the cert matches the trust anchor
+ * specified as a certificate or has the same key and subject of an anchor
+ * specified as a trusted {pubkey, caname} pair.
+ * If no match has been found, does a second check of the cert against
+ * anchors specified as a trusted {pubkey, caname} pair to see if the cert
+ * was issued by that anchor.
+ * Returns false if none of the trust anchors are valid for this cert.
*
* @param cert the certificate to test
* @return a boolean value indicating whether the cert completes the path.
*/
@Override
boolean isPathCompleted(X509Certificate cert) {
+ List<TrustAnchor> otherAnchors = new ArrayList<>();
+ // first, check if cert is already trusted
for (TrustAnchor anchor : trustAnchors) {
if (anchor.getTrustedCert() != null) {
if (cert.equals(anchor.getTrustedCert())) {
@@ -849,7 +853,12 @@
}
// else, it is a self-issued certificate of the anchor
}
-
+ otherAnchors.add(anchor);
+ }
+ // next, check if cert is issued by anchor specified by key/name
+ for (TrustAnchor anchor : otherAnchors) {
+ X500Principal principal = anchor.getCA();
+ PublicKey publicKey = anchor.getCAPublicKey();
// Check subject/issuer name chaining
if (principal == null ||
!principal.equals(cert.getIssuerX500Principal())) {
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSP.java Wed Oct 19 08:06:10 2016 -0700
@@ -35,6 +35,7 @@
import java.security.cert.CertPathValidatorException.BasicReason;
import java.security.cert.CRLReason;
import java.security.cert.Extension;
+import java.security.cert.TrustAnchor;
import java.security.cert.X509Certificate;
import java.util.Arrays;
import java.util.Collections;
@@ -164,6 +165,15 @@
Date date, List<Extension> extensions)
throws IOException, CertPathValidatorException
{
+ return check(cert, responderURI, null, issuerCert, responderCert, date, extensions);
+ }
+
+ public static RevocationStatus check(X509Certificate cert,
+ URI responderURI, TrustAnchor anchor, X509Certificate issuerCert,
+ X509Certificate responderCert, Date date,
+ List<Extension> extensions)
+ throws IOException, CertPathValidatorException
+ {
CertId certId = null;
try {
X509CertImpl certImpl = X509CertImpl.toImpl(cert);
@@ -173,8 +183,8 @@
("Exception while encoding OCSPRequest", e);
}
OCSPResponse ocspResponse = check(Collections.singletonList(certId),
- responderURI, new OCSPResponse.IssuerInfo(issuerCert),
- responderCert, date, extensions);
+ responderURI, new OCSPResponse.IssuerInfo(anchor, issuerCert),
+ responderCert, date, extensions);
return (RevocationStatus) ocspResponse.getSingleResponse(certId);
}
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java Wed Oct 19 08:06:10 2016 -0700
@@ -507,9 +507,8 @@
// Check algorithm constraints specified in security property
// "jdk.certpath.disabledAlgorithms".
- AlgorithmChecker algChecker = new AlgorithmChecker(
- new TrustAnchor(issuerInfo.getName(),
- issuerInfo.getPublicKey(), null));
+ AlgorithmChecker algChecker =
+ new AlgorithmChecker(issuerInfo.getAnchor(), date);
algChecker.init(false);
algChecker.check(signerCert, Collections.<String>emptySet());
@@ -982,36 +981,38 @@
/**
* Helper class that allows consumers to pass in issuer information. This
* will always consist of the issuer's name and public key, but may also
- * contain a certificate if the originating data is in that form.
+ * contain a certificate if the originating data is in that form. The
+ * trust anchor for the certificate chain will be included for certpath
+ * disabled algorithm checking.
*/
static final class IssuerInfo {
+ private final TrustAnchor anchor;
private final X509Certificate certificate;
private final X500Principal name;
private final PublicKey pubKey;
+ IssuerInfo(TrustAnchor anchor) {
+ this(anchor, (anchor != null) ? anchor.getTrustedCert() : null);
+ }
+
IssuerInfo(X509Certificate issuerCert) {
- certificate = Objects.requireNonNull(issuerCert,
- "Constructor requires non-null certificate");
- name = certificate.getSubjectX500Principal();
- pubKey = certificate.getPublicKey();
+ this(null, issuerCert);
}
- IssuerInfo(X500Principal subjectName, PublicKey key) {
- certificate = null;
- name = Objects.requireNonNull(subjectName,
- "Constructor requires non-null subject");
- pubKey = Objects.requireNonNull(key,
- "Constructor requires non-null public key");
- }
-
- IssuerInfo(TrustAnchor anchor) {
- certificate = anchor.getTrustedCert();
- if (certificate != null) {
- name = certificate.getSubjectX500Principal();
- pubKey = certificate.getPublicKey();
+ IssuerInfo(TrustAnchor anchor, X509Certificate issuerCert) {
+ if (anchor == null && issuerCert == null) {
+ throw new NullPointerException("TrustAnchor and issuerCert " +
+ "cannot be null");
+ }
+ this.anchor = anchor;
+ if (issuerCert != null) {
+ name = issuerCert.getSubjectX500Principal();
+ pubKey = issuerCert.getPublicKey();
+ certificate = issuerCert;
} else {
name = anchor.getCA();
pubKey = anchor.getCAPublicKey();
+ certificate = anchor.getTrustedCert();
}
}
@@ -1047,6 +1048,15 @@
}
/**
+ * Get the TrustAnchor for the certificate chain.
+ *
+ * @return a {@code TrustAnchor}.
+ */
+ TrustAnchor getAnchor() {
+ return anchor;
+ }
+
+ /**
* Create a string representation of this IssuerInfo.
*
* @return a {@code String} form of this IssuerInfo object.
--- a/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java Wed Oct 19 08:06:10 2016 -0700
@@ -437,7 +437,7 @@
private void updateState(X509Certificate cert)
throws CertPathValidatorException
{
- issuerInfo = new OCSPResponse.IssuerInfo(cert);
+ issuerInfo = new OCSPResponse.IssuerInfo(anchor, cert);
// Make new public key if parameters are missing
PublicKey pubKey = cert.getPublicKey();
@@ -740,8 +740,8 @@
}
response = OCSP.check(Collections.singletonList(certId),
- responderURI, issuerInfo,
- responderCert, null, ocspExtensions);
+ responderURI, issuerInfo, responderCert, params.date(),
+ ocspExtensions);
}
} catch (IOException e) {
throw new CertPathValidatorException(
--- a/jdk/src/java.base/share/classes/sun/security/util/CurveDB.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/util/CurveDB.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -664,6 +664,74 @@
0xFF70, nameSplitPattern);
*/
+ /*
+ * Brainpool curves (RFC 5639)
+ * (Twisted curves are not included)
+ */
+
+ add("brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1", P,
+ "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
+ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
+ "1E589A8595423412134FAA2DBDEC95C8D8675E58",
+ "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
+ "1667CB477A1A8EC338F94741669C976316DA6321",
+ "E95E4A5F737059DC60DF5991D45029409E60FC09",
+ 1, nameSplitPattern);
+
+ add("brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3", P,
+ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
+ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
+ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
+ "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
+ "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
+ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
+ 1, nameSplitPattern);
+
+ add("brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5", P,
+ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
+ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
+ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
+ "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
+ "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
+ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
+ 1, nameSplitPattern);
+
+ add("brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7", P,
+ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
+ "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
+ "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
+ "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
+ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
+ "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
+ 1, nameSplitPattern);
+
+ add("brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9", P,
+ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
+ "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
+ "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
+ "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
+ "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
+ "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
+ 1, nameSplitPattern);
+
+ add("brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11", P,
+ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
+ "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
+ "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
+ "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
+ "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
+ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
+ 1, nameSplitPattern);
+
+ add("brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13", P,
+ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
+ "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
+ "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
+ "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
+ "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
+ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
+ 1, nameSplitPattern);
+
specCollection = Collections.unmodifiableCollection(oidMap.values());
}
}
--- a/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/util/DisabledAlgorithmConstraints.java Wed Oct 19 08:06:10 2016 -0700
@@ -60,6 +60,10 @@
public static final String PROPERTY_TLS_DISABLED_ALGS =
"jdk.tls.disabledAlgorithms";
+ // the known security property, jdk.jar.disabledAlgorithms
+ public static final String PROPERTY_JAR_DISABLED_ALGS =
+ "jdk.jar.disabledAlgorithms";
+
private final String[] disabledAlgorithms;
private final Constraints algorithmConstraints;
@@ -73,6 +77,14 @@
this(propertyName, new AlgorithmDecomposer());
}
+ /**
+ * Initialize algorithm constraints with the specified security property
+ * for a specific usage type.
+ *
+ * @param propertyName the security property name that define the disabled
+ * algorithm constraints
+ * @param decomposer an alternate AlgorithmDecomposer.
+ */
public DisabledAlgorithmConstraints(String propertyName,
AlgorithmDecomposer decomposer) {
super(decomposer);
@@ -530,7 +542,8 @@
}
throw new CertPathValidatorException(
"Algorithm constraints check failed on certificate " +
- "anchor limits",
+ "anchor limits. " + algorithm + " used with " +
+ cp.getCertificate().getSubjectX500Principal(),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -611,8 +624,8 @@
return;
}
throw new CertPathValidatorException(
- "denyAfter constraint check failed. " +
- "Constraint date: " +
+ "denyAfter constraint check failed: " + algorithm +
+ " used with Constraint date: " +
dateFormat.format(denyAfterDate) + "; "
+ errmsg + dateFormat.format(currentDate),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
@@ -644,6 +657,7 @@
private int minSize; // the minimal available key size
private int maxSize; // the maximal available key size
private int prohibitedSize = -1; // unavailable key sizes
+ private int size;
public KeySizeConstraint(String algo, Operator operator, int length) {
algorithm = algo;
@@ -695,7 +709,9 @@
return;
}
throw new CertPathValidatorException(
- "Algorithm constraints check failed on keysize limits",
+ "Algorithm constraints check failed on keysize limits. "
+ + algorithm + " " + size + "bit key used with "
+ + cp.getCertificate().getSubjectX500Principal(),
null, null, -1, BasicReason.ALGORITHM_CONSTRAINED);
}
}
@@ -722,7 +738,7 @@
return true;
}
- int size = KeyUtil.getKeySize(key);
+ size = KeyUtil.getKeySize(key);
if (size == 0) {
return false; // we don't allow any key of size 0.
} else if (size > 0) {
--- a/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/classes/sun/security/util/SignatureFileVerifier.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,26 +25,49 @@
package sun.security.util;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.security.CodeSigner;
+import java.security.CryptoPrimitive;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.SignatureException;
import java.security.cert.CertPath;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-import java.security.*;
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-
-import sun.security.pkcs.*;
+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;
+import java.util.jar.Manifest;
import sun.security.jca.Providers;
+import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.SignerInfo;
public class SignatureFileVerifier {
/* Are we debugging ? */
private static final Debug debug = Debug.getInstance("jar");
- /* cache of CodeSigner objects */
+ 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);
+
private ArrayList<CodeSigner[]> signerCache;
private static final String ATTR_DIGEST =
@@ -199,8 +222,15 @@
/** get digest from cache */
- private MessageDigest getDigest(String algorithm)
- {
+ 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;
+ }
+
if (createdDigests == null)
createdDigests = new HashMap<>();
@@ -320,7 +350,7 @@
private boolean verifyManifestHash(Manifest sf,
ManifestDigester md,
List<Object> manifestDigests)
- throws IOException
+ throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean manifestSigned = false;
@@ -364,7 +394,7 @@
private boolean verifyManifestMainAttrs(Manifest sf,
ManifestDigester md)
- throws IOException
+ throws IOException, SignatureException
{
Attributes mattr = sf.getMainAttributes();
boolean attrsVerified = true;
@@ -430,14 +460,14 @@
private boolean verifySection(Attributes sfAttr,
String name,
ManifestDigester md)
- throws IOException
+ throws IOException, SignatureException
{
boolean oneDigestVerified = false;
ManifestDigester.Entry mde = md.get(name,block.isOldStyle());
if (mde == null) {
throw new SecurityException(
- "no manifiest section for signature file entry "+name);
+ "no manifest section for signature file entry "+name);
}
if (sfAttr != null) {
--- a/jdk/src/java.base/share/conf/net.properties Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/conf/net.properties Wed Oct 19 08:06:10 2016 -0700
@@ -72,3 +72,30 @@
# value is 10).
# http.KeepAlive.remainingData=512
# http.KeepAlive.queuedConnections=10
+
+# Authentication Scheme restrictions for HTTP and HTTPS.
+#
+# In some environments certain authentication schemes may be undesirable
+# when proxying HTTP or HTTPS. For example, "Basic" results in effectively the
+# cleartext transmission of the user's password over the physical network.
+# This section describes the mechanism for disabling authentication schemes
+# based on the scheme name. Disabled schemes will be treated as if they are not
+# supported by the implementation.
+#
+# The 'jdk.http.auth.tunneling.disabledSchemes' property lists the authentication
+# schemes that will be disabled when tunneling HTTPS over a proxy, HTTP CONNECT.
+# The 'jdk.http.auth.proxying.disabledSchemes' property lists the authentication
+# schemes that will be disabled when proxying HTTP.
+#
+# In both cases the property is a comma-separated list of, case-insensitive,
+# authentication scheme names, as defined by their relevant RFCs. An
+# implementation may, but is not required to, support common schemes whose names
+# include: 'Basic', 'Digest', 'NTLM', 'Kerberos', 'Negotiate'. A scheme that
+# is not known, or not supported, by the implementation is ignored.
+#
+# Note: This property is currently used by the JDK Reference implementation. It
+# is not guaranteed to be examined and used by other implementations.
+#
+#jdk.http.auth.proxying.disabledSchemes=
+jdk.http.auth.tunneling.disabledSchemes=Basic
+
--- a/jdk/src/java.base/share/conf/security/java.security Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/conf/security/java.security Wed Oct 19 08:06:10 2016 -0700
@@ -935,3 +935,42 @@
# Otherwise, the status is UNDECIDED.
#
#jdk.serialFilter=pattern;pattern
+
+# Algorithm restrictions for signed JAR files
+#
+# In some environments, certain algorithms or key lengths may be undesirable
+# for signed JAR validation. For example, "MD2" is generally no longer
+# considered to be a secure hash algorithm. This section describes the
+# mechanism for disabling algorithms based on algorithm name and/or key length.
+# JARs signed with any of the disabled algorithms or key sizes will be treated
+# as unsigned.
+#
+# The syntax of the disabled algorithm string is described as follows:
+# DisabledAlgorithms:
+# " DisabledAlgorithm { , DisabledAlgorithm } "
+#
+# DisabledAlgorithm:
+# AlgorithmName [Constraint]
+#
+# AlgorithmName:
+# (see below)
+#
+# Constraint:
+# KeySizeConstraint
+#
+# KeySizeConstraint:
+# keySize Operator KeyLength
+#
+# Operator:
+# <= | < | == | != | >= | >
+#
+# KeyLength:
+# Integer value of the algorithm's key length in bits
+#
+# Note: This property is currently used by the JDK Reference
+# implementation. It is not guaranteed to be examined and used by other
+# implementations.
+#
+jdk.jar.disabledAlgorithms=MD2, RSA keySize < 1024, \
+ DSA keySize < 1024
+
--- a/jdk/src/java.base/share/lib/security/default.policy Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/lib/security/default.policy Wed Oct 19 08:06:10 2016 -0700
@@ -103,7 +103,6 @@
permission java.lang.RuntimePermission
"accessClassInPackage.sun.security.*";
permission java.lang.RuntimePermission "loadLibrary.sunec";
- permission java.util.PropertyPermission "*", "read";
permission java.security.SecurityPermission "putProviderProperty.SunEC";
permission java.security.SecurityPermission "clearProviderProperties.SunEC";
permission java.security.SecurityPermission "removeProviderProperty.SunEC";
--- a/jdk/src/java.base/share/native/libverify/check_code.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/share/native/libverify/check_code.c Wed Oct 19 08:06:10 2016 -0700
@@ -1293,14 +1293,13 @@
case JVM_OPC_invokevirtual:
case JVM_OPC_invokespecial:
case JVM_OPC_invokestatic:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokeinterface: {
/* Make sure the constant pool item is the right type. */
int key = (code[offset + 1] << 8) + code[offset + 2];
const char *methodname;
jclass cb = context->class;
fullinfo_type clazz_info;
- int is_constructor, is_internal, is_invokedynamic;
+ int is_constructor, is_internal;
int kind;
switch (opcode ) {
@@ -1309,9 +1308,6 @@
? (1 << JVM_CONSTANT_Methodref)
: ((1 << JVM_CONSTANT_InterfaceMethodref) | (1 << JVM_CONSTANT_Methodref)));
break;
- case JVM_OPC_invokedynamic:
- kind = 1 << JVM_CONSTANT_NameAndType;
- break;
case JVM_OPC_invokeinterface:
kind = 1 << JVM_CONSTANT_InterfaceMethodref;
break;
@@ -1319,7 +1315,6 @@
kind = 1 << JVM_CONSTANT_Methodref;
}
- is_invokedynamic = opcode == JVM_OPC_invokedynamic;
/* Make sure the constant pool item is the right type. */
verify_constant_pool_type(context, key, kind);
methodname = JVM_GetCPMethodNameUTF(env, cb, key);
@@ -1328,11 +1323,8 @@
is_internal = methodname[0] == '<';
pop_and_free(context);
- if (is_invokedynamic)
- clazz_info = context->object_info; // anything will do
- else
- clazz_info = cp_index_to_class_fullinfo(context, key,
- JVM_CONSTANT_Methodref);
+ clazz_info = cp_index_to_class_fullinfo(context, key,
+ JVM_CONSTANT_Methodref);
this_idata->operand.i = key;
this_idata->operand2.fi = clazz_info;
if (is_constructor) {
@@ -1387,17 +1379,15 @@
"Fourth operand byte of invokeinterface must be zero");
}
pop_and_free(context);
- } else if (opcode == JVM_OPC_invokedynamic) {
- if (code[offset + 3] != 0 || code[offset + 4] != 0) {
- CCerror(context,
- "Third and fourth operand bytes of invokedynamic must be zero");
- }
} else if (opcode == JVM_OPC_invokevirtual
|| opcode == JVM_OPC_invokespecial)
set_protected(context, inumber, key, opcode);
break;
}
+ case JVM_OPC_invokedynamic:
+ CCerror(context,
+ "invokedynamic bytecode is not supported in this class file version");
case JVM_OPC_instanceof:
case JVM_OPC_checkcast:
@@ -2085,7 +2075,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit: /* invokespecial call to <init> */
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: {
/* The top stuff on the stack depends on the method signature */
int operand = this_idata->operand.i;
@@ -2101,8 +2090,7 @@
print_formatted_methodname(context, operand);
}
#endif
- if (opcode != JVM_OPC_invokestatic &&
- opcode != JVM_OPC_invokedynamic)
+ if (opcode != JVM_OPC_invokestatic)
/* First, push the object */
*ip++ = (opcode == JVM_OPC_invokeinit ? '@' : 'A');
for (p = signature + 1; *p != JVM_SIGNATURE_ENDFUNC; ) {
@@ -2388,7 +2376,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokeinterface: case JVM_OPC_invokestatic: {
int operand = this_idata->operand.i;
const char *signature =
@@ -2398,8 +2385,7 @@
int item;
const char *p;
check_and_push(context, signature, VM_STRING_UTF);
- if (opcode == JVM_OPC_invokestatic ||
- opcode == JVM_OPC_invokedynamic) {
+ if (opcode == JVM_OPC_invokestatic) {
item = 0;
} else if (opcode == JVM_OPC_invokeinit) {
fullinfo_type init_type = this_idata->operand2.fi;
@@ -2795,7 +2781,6 @@
case JVM_OPC_invokevirtual: case JVM_OPC_invokespecial:
case JVM_OPC_invokeinit:
- case JVM_OPC_invokedynamic:
case JVM_OPC_invokestatic: case JVM_OPC_invokeinterface: {
/* Look to signature to determine correct result. */
int operand = this_idata->operand.i;
--- a/jdk/src/java.base/solaris/lib/security/default.policy Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/solaris/lib/security/default.policy Wed Oct 19 08:06:10 2016 -0700
@@ -4,7 +4,10 @@
permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
permission java.lang.RuntimePermission "loadLibrary.j2ucrypto";
// need "com.oracle.security.ucrypto.debug" for debugging
- permission java.util.PropertyPermission "*", "read";
+ permission java.util.PropertyPermission "com.oracle.security.ucrypto.debug", "read";
+ permission java.util.PropertyPermission "file.separator", "read";
+ permission java.util.PropertyPermission "java.home", "read";
+ permission java.util.PropertyPermission "os.name", "read";
permission java.security.SecurityPermission
"putProviderProperty.OracleUcrypto";
permission java.security.SecurityPermission
--- a/jdk/src/java.base/unix/native/libnet/net_util_md.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/unix/native/libnet/net_util_md.c Wed Oct 19 08:06:10 2016 -0700
@@ -273,13 +273,10 @@
#endif
-
void
NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultDetail) {
- char errmsg[255];
- sprintf(errmsg, "errno: %d, error: %s\n", errno, defaultDetail);
- JNU_ThrowByNameWithLastError(env, name, errmsg);
+ JNU_ThrowByNameWithMessageAndLastError(env, name, defaultDetail);
}
void
--- a/jdk/src/java.base/windows/native/libjli/java_md.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/windows/native/libjli/java_md.c Wed Oct 19 08:06:10 2016 -0700
@@ -48,6 +48,10 @@
char *jvmpath, jint jvmpathsize);
static jboolean GetJREPath(char *path, jint pathsize);
+#ifdef USE_REGISTRY_LOOKUP
+jboolean GetPublicJREHome(char *buf, jint bufsize);
+#endif
+
/* We supports warmup for UI stack that is performed in parallel
* to VM initialization.
* This helps to improve startup of UI application as warmup phase
@@ -346,6 +350,14 @@
}
}
+#ifdef USE_REGISTRY_LOOKUP
+ /* Lookup public JRE using Windows registry. */
+ if (GetPublicJREHome(path, pathsize)) {
+ JLI_TraceLauncher("JRE path is %s\n", path);
+ return JNI_TRUE;
+ }
+#endif
+
JLI_ReportErrorMessage(JRE_ERROR8 JAVA_DLL);
return JNI_FALSE;
}
--- a/jdk/src/java.base/windows/native/libnet/net_util_md.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.base/windows/native/libnet/net_util_md.c Wed Oct 19 08:06:10 2016 -0700
@@ -205,9 +205,7 @@
void
NET_ThrowByNameWithLastError(JNIEnv *env, const char *name,
const char *defaultDetail) {
- char errmsg[255];
- sprintf(errmsg, "errno: %d, error: %s\n", WSAGetLastError(), defaultDetail);
- JNU_ThrowByNameWithLastError(env, name, errmsg);
+ JNU_ThrowByNameWithMessageAndLastError(env, name, defaultDetail);
}
jfieldID
--- a/jdk/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/macosx/native/libjsound/PLATFORM_API_MacOSX_PCM.cpp Wed Oct 19 08:06:10 2016 -0700
@@ -817,6 +817,10 @@
ERROR1("<<DAUDIO_Open: ERROR: unsupported encoding (%d)\n", encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1("<<DAUDIO_Open: ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
OSX_DirectAudioDevice *device = new OSX_DirectAudioDevice();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.cpp Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.cpp Wed Oct 19 08:06:10 2016 -0700
@@ -46,6 +46,7 @@
ContextualGlyphSubstitutionProcessor::ContextualGlyphSubstitutionProcessor(const LEReferenceTo<MorphSubtableHeader> &morphSubtableHeader, LEErrorCode &success)
: StateTableProcessor(morphSubtableHeader, success), entryTable(), contextualGlyphSubstitutionHeader(morphSubtableHeader, success)
{
+ if (LE_FAILURE(success)) return;
contextualGlyphSubstitutionHeader.orphan();
substitutionTableOffset = SWAPW(contextualGlyphSubstitutionHeader->substitutionTableOffset);
@@ -66,10 +67,10 @@
markGlyph = 0;
}
-ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset ContextualGlyphSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR;
const ContextualGlyphSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
+ if (LE_FAILURE(success)) return 0;
ByteOffset newState = SWAPW(entry->newStateOffset);
le_int16 flags = SWAPW(entry->flags);
WordOffset markOffset = SWAPW(entry->markOffset);
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.h Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/ContextualGlyphSubstProc.h Wed Oct 19 08:06:10 2016 -0700
@@ -52,7 +52,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.cpp Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.cpp Wed Oct 19 08:06:10 2016 -0700
@@ -63,10 +63,10 @@
lastGlyph = 0;
}
-ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset IndicRearrangementProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR; // todo- make a param?
- const IndicRearrangementStateEntry *entry = entryTable.getAlias(index,success);
+ const IndicRearrangementStateEntry *entry = entryTable.getAlias(index, success);
+ if (LE_FAILURE(success)) return 0;
ByteOffset newState = SWAPW(entry->newStateOffset);
IndicRearrangementFlags flags = (IndicRearrangementFlags) SWAPW(entry->flags);
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.h Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/IndicRearrangementProcessor.h Wed Oct 19 08:06:10 2016 -0700
@@ -52,7 +52,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.cpp Wed Oct 19 08:06:10 2016 -0700
@@ -67,9 +67,8 @@
m = -1;
}
-ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index)
+ByteOffset LigatureSubstitutionProcessor::processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success)
{
- LEErrorCode success = LE_NO_ERROR;
const LigatureSubstitutionStateEntry *entry = entryTable.getAlias(index, success);
if (LE_FAILURE(success)) {
currGlyph++;
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.h Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/LigatureSubstProc.h Wed Oct 19 08:06:10 2016 -0700
@@ -54,7 +54,7 @@
public:
virtual void beginStateTable();
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index);
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success);
virtual void endStateTable();
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.cpp Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.cpp Wed Oct 19 08:06:10 2016 -0700
@@ -81,6 +81,7 @@
while (currGlyph <= glyphCount) {
if(LE_STATE_PATIENCE_DECR()) break; // patience exceeded.
+ if (LE_FAILURE(success)) break;
ClassCode classCode = classCodeOOB;
if (currGlyph == glyphCount) {
// XXX: How do we handle EOT vs. EOL?
@@ -100,7 +101,7 @@
EntryTableIndex entryTableIndex = stateArray.getObject((le_uint8)classCode, success);
if (LE_FAILURE(success)) { break; }
LE_STATE_PATIENCE_CURR(le_int32, currGlyph);
- currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex);
+ currentState = processStateEntry(glyphStorage, currGlyph, entryTableIndex, success);
LE_STATE_PATIENCE_INCR(currGlyph);
}
--- a/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.h Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/share/native/libfontmanager/layout/StateTableProcessor.h Wed Oct 19 08:06:10 2016 -0700
@@ -53,7 +53,7 @@
virtual void beginStateTable() = 0;
- virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index) = 0;
+ virtual ByteOffset processStateEntry(LEGlyphStorage &glyphStorage, le_int32 &currGlyph, EntryTableIndex index, LEErrorCode &success) = 0;
virtual void endStateTable() = 0;
--- a/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsintrp.c Wed Oct 19 08:06:10 2016 -0700
@@ -244,7 +244,7 @@
// To prevent out of bounds indexing
cmsINLINE cmsFloat32Number fclamp(cmsFloat32Number v)
{
- return v < 0.0f ? 0.0f : (v > 1.0f ? 1.0f : v);
+ return v < 0.0f || v != v ? 0.0f : (v > 1.0f ? 1.0f : v);
}
// Floating-point version of 1D interpolation
--- a/jdk/src/java.desktop/share/native/liblcms/cmsio0.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/share/native/liblcms/cmsio0.c Wed Oct 19 08:06:10 2016 -0700
@@ -1543,6 +1543,13 @@
// If the element is already in memory, return the pointer
if (Icc -> TagPtrs[n]) {
+ if (Icc -> TagTypeHandlers[n] == NULL) goto Error;
+ BaseType = Icc -> TagTypeHandlers[n]->Signature;
+ if (BaseType == 0) goto Error;
+ TagDescriptor = _cmsGetTagDescriptor(Icc-> ContextID, sig);
+ if (TagDescriptor == NULL) goto Error;
+ if (!IsTypeSupported(TagDescriptor, BaseType)) goto Error;
+
if (Icc ->TagSaveAsRaw[n]) goto Error; // We don't support read raw tags as cooked
_cmsUnlockMutex(Icc->ContextID, Icc ->UsrMutex);
--- a/jdk/src/java.desktop/share/native/liblcms/cmstypes.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/share/native/liblcms/cmstypes.c Wed Oct 19 08:06:10 2016 -0700
@@ -4313,7 +4313,10 @@
// Copy MAX_INPUT_DIMENSIONS at most. Expand to cmsUInt32Number
nMaxGrids = InputChans > MAX_INPUT_DIMENSIONS ? MAX_INPUT_DIMENSIONS : InputChans;
- for (i=0; i < nMaxGrids; i++) GridPoints[i] = (cmsUInt32Number) Dimensions8[i];
+ for (i=0; i < nMaxGrids; i++) {
+ if (Dimensions8[i] == 1) goto Error; // Impossible value, 0 for no CLUT and then 2 at least
+ GridPoints[i] = (cmsUInt32Number)Dimensions8[i];
+ }
// Allocate the true CLUT
mpe = cmsStageAllocCLutFloatGranular(self ->ContextID, GridPoints, InputChans, OutputChans, NULL);
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceDataProxy.java Wed Oct 19 08:06:10 2016 -0700
@@ -102,10 +102,13 @@
int w, int h)
{
if (cachedData == null) {
- // Bitmask will be created lazily during the blit phase
- cachedData = X11SurfaceData.createData(x11gc, w, h,
- x11gc.getColorModel(),
- null, 0, getTransparency());
+ try {
+ // Bitmask will be created lazily during the blit phase
+ cachedData = X11SurfaceData.createData(x11gc, w, h,
+ x11gc.getColorModel(),
+ null, 0, getTransparency());
+ } catch (OutOfMemoryError oome) {
+ }
}
return cachedData;
}
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRPMBlitLoops.java Wed Oct 19 08:06:10 2016 -0700
@@ -138,6 +138,9 @@
vImg = (SunVolatileImage) dst.getGraphicsConfig().createCompatibleVolatileImage(w, h, src.getTransparency());
vImg.setAccelerationPriority(1.0f);
+ if (!(vImg.getDestSurface() instanceof XRSurfaceData)) {
+ throw new InvalidPipeException("Could not create XRSurfaceData");
+ }
if (src.getTransparency() == SurfaceData.OPAQUE) {
rgbTmpPM = new WeakReference<SunVolatileImage>(vImg);
} else {
--- a/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/unix/classes/sun/java2d/xr/XRSurfaceDataProxy.java Wed Oct 19 08:06:10 2016 -0700
@@ -59,9 +59,12 @@
public SurfaceData validateSurfaceData(SurfaceData srcData,
SurfaceData cachedData, int w, int h) {
if (cachedData == null) {
- cachedData = XRSurfaceData.createData(xrgc, w, h,
- xrgc.getColorModel(), null, 0,
- getTransparency(), true);
+ try {
+ cachedData = XRSurfaceData.createData(xrgc, w, h,
+ xrgc.getColorModel(), null, 0,
+ getTransparency(), true);
+ } catch (OutOfMemoryError oome) {
+ }
}
return cachedData;
}
--- a/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/unix/native/common/java2d/x11/X11SurfaceData.c Wed Oct 19 08:06:10 2016 -0700
@@ -441,7 +441,7 @@
* width , height must be nonzero otherwise XCreatePixmap
* generates BadValue in error_handler
*/
- if (width <= 0 || height <= 0) {
+ if (width <= 0 || height <= 0 || width > 32767 || height > 32767) {
JNU_ThrowOutOfMemoryError(env,
"Can't create offscreen surface");
return JNI_FALSE;
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_BsdOS_ALSA_PCM.c Wed Oct 19 08:06:10 2016 -0700
@@ -434,7 +434,10 @@
snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
}
#endif
-
+ if (channels <= 0) {
+ ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
if (!info) {
ERROR0("Out of memory\n");
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_LinuxOS_ALSA_PCM.c Wed Oct 19 08:06:10 2016 -0700
@@ -434,7 +434,10 @@
snd_output_stdio_attach(&ALSA_OUTPUT, stdout, 0);
}
#endif
-
+ if (channels <= 0) {
+ ERROR1("ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (AlsaPcmInfo*) malloc(sizeof(AlsaPcmInfo));
if (!info) {
ERROR0("Out of memory\n");
--- a/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/unix/native/libjsound/PLATFORM_API_SolarisOS_PCM.c Wed Oct 19 08:06:10 2016 -0700
@@ -182,6 +182,10 @@
ERROR1(" DAUDIO_Open: invalid encoding %d\n", (int) encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1(" DAUDIO_Open: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
info = (SolPcmInfo*) malloc(sizeof(SolPcmInfo));
if (!info) {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -153,6 +153,19 @@
@Override
public void setMenuBar(MenuBar mb) {
WMenuBarPeer mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
+ if (mbPeer != null) {
+ if (mbPeer.framePeer != this) {
+ mb.removeNotify();
+ mb.addNotify();
+ mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(mb);
+ if (mbPeer != null && mbPeer.framePeer != this) {
+ throw new IllegalStateException("Wrong parent peer");
+ }
+ }
+ if (mbPeer != null) {
+ addChildPeer(mbPeer);
+ }
+ }
setMenuBar0(mbPeer);
updateInsets(insets_);
}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuBarPeer.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuBarPeer.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, 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
@@ -31,6 +31,8 @@
// MenuBarPeer implementation
+ final WFramePeer framePeer;
+
@Override
public native void addMenu(Menu m);
@Override
@@ -44,8 +46,11 @@
// Toolkit & peer internals
WMenuBarPeer(MenuBar target) {
this.target = target;
- WFramePeer framePeer = (WFramePeer)
+ framePeer = (WFramePeer)
WToolkit.targetToPeer(target.getParent());
+ if (framePeer != null) {
+ framePeer.addChildPeer(this);
+ }
create(framePeer);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java Wed Oct 19 08:06:10 2016 -0700
@@ -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
@@ -107,6 +107,7 @@
this.target = target;
this.parent = (WMenuPeer) WToolkit.targetToPeer(target.getParent());
this.isCheckbox = isCheckbox;
+ parent.addChildPeer(this);
create(parent);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuPeer.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuPeer.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, 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
@@ -51,10 +51,12 @@
if (parent instanceof MenuBar) {
WMenuBarPeer mbPeer = (WMenuBarPeer) WToolkit.targetToPeer(parent);
this.parent = mbPeer;
+ mbPeer.addChildPeer(this);
createMenu(mbPeer);
}
else if (parent instanceof Menu) {
this.parent = (WMenuPeer) WToolkit.targetToPeer(parent);
+ this.parent.addChildPeer(this);
createSubMenu(this.parent);
}
else {
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2008, 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
@@ -24,6 +24,9 @@
*/
package sun.awt.windows;
+import java.util.Map;
+import java.util.WeakHashMap;
+
abstract class WObjectPeer {
static {
@@ -45,6 +48,8 @@
// used to synchronize the state of this peer
private final Object stateLock = new Object();
+ private volatile Map<WObjectPeer, WObjectPeer> childPeers;
+
public static WObjectPeer getPeerForTarget(Object t) {
WObjectPeer peer = (WObjectPeer) WToolkit.targetToPeer(t);
return peer;
@@ -77,6 +82,9 @@
}
if (call_disposeImpl) {
+ if (childPeers != null) {
+ disposeChildPeers();
+ }
disposeImpl();
}
}
@@ -88,4 +96,33 @@
* Initialize JNI field and method IDs
*/
private static native void initIDs();
+
+ // if a child peer existence depends on this peer, add it to this collection
+ final void addChildPeer(WObjectPeer child) {
+ synchronized (getStateLock()) {
+ if (childPeers == null) {
+ childPeers = new WeakHashMap<>();
+ }
+ if (isDisposed()) {
+ throw new IllegalStateException("Parent peer is disposed");
+ }
+ childPeers.put(child, this);
+ }
+ }
+
+ // called to dispose dependent child peers
+ private void disposeChildPeers() {
+ synchronized (getStateLock()) {
+ for (WObjectPeer child : childPeers.keySet()) {
+ if (child != null) {
+ try {
+ child.dispose();
+ }
+ catch (Exception e) {
+ // ignored
+ }
+ }
+ }
+ }
+ }
}
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WPopupMenuPeer.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, 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
@@ -58,6 +58,7 @@
parent = WToolkit.getNativeContainer((Component)parent);
parentPeer = (WComponentPeer) WToolkit.targetToPeer(parent);
}
+ parentPeer.addChildPeer(this);
createMenu(parentPeer);
// fix for 5088782: check if menu object is created successfully
checkMenuCreation();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Font.cpp Wed Oct 19 08:06:10 2016 -0700
@@ -640,7 +640,7 @@
int AwtFont::getFontDescriptorNumber(JNIEnv *env, jobject font,
jobject fontDescriptor)
{
- int i, num;
+ int i, num = 0;
jobject refFontDescriptor;
jobjectArray array;
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -1113,11 +1113,19 @@
void AwtFrame::SetMenuBar(AwtMenuBar* mb)
{
+ if (menuBar) {
+ menuBar->SetFrame(NULL);
+ }
menuBar = mb;
if (mb == NULL) {
// Remove existing menu bar, if any.
::SetMenu(GetHWnd(), NULL);
} else {
+ AwtFrame* oldFrame = menuBar->GetFrame();
+ if (oldFrame && oldFrame != this) {
+ oldFrame->SetMenuBar(NULL);
+ }
+ menuBar->SetFrame(this);
if (menuBar->GetHMenu() != NULL) {
::SetMenu(GetHWnd(), menuBar->GetHMenu());
}
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2014, 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
@@ -58,6 +58,9 @@
void AwtMenuBar::Dispose()
{
+ if (m_frame != NULL && m_frame->GetMenuBar() == this) {
+ m_frame->SetMenuBar(NULL);
+ }
m_frame = NULL;
AwtMenu::Dispose();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -63,6 +63,9 @@
virtual AwtMenuBar* GetMenuBar() { return this; }
INLINE AwtFrame* GetFrame() { return m_frame; }
+ INLINE void SetFrame(AwtFrame* frame) {
+ m_frame = frame;
+ }
virtual HWND GetOwnerHWnd();
virtual void RedrawMenuBar();
--- a/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.desktop/windows/native/libjsound/PLATFORM_API_WinOS_DirectSound.cpp Wed Oct 19 08:06:10 2016 -0700
@@ -859,6 +859,10 @@
ERROR1("DAUDIO_Open: ERROR: cannot open the device with encoding=%d!\n", encoding);
return NULL;
}
+ if (channels <= 0) {
+ ERROR1("DAUDIO_Open: ERROR: Invalid number of channels=%d!\n", channels);
+ return NULL;
+ }
if (sampleSizeInBits > 8 &&
#ifdef _LITTLE_ENDIAN
isBigEndian
--- a/jdk/src/java.management/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.management/share/classes/com/sun/jmx/remote/util/ClassLoaderWithRepository.java Wed Oct 19 08:06:10 2016 -0700
@@ -39,8 +39,9 @@
}
protected Class<?> findClass(String name) throws ClassNotFoundException {
+ Class<?> cls;
try {
- return repository.loadClass(name);
+ cls = repository.loadClass(name);
} catch (ClassNotFoundException cne) {
if (cl2 != null) {
return cl2.loadClass(name);
@@ -48,6 +49,15 @@
throw cne;
}
}
+
+ if(!cls.getName().equals(name)){
+ if (cl2 != null) {
+ return cl2.loadClass(name);
+ } else {
+ throw new ClassNotFoundException(name);
+ }
+ }
+ return cls;
}
private ClassLoaderRepository repository;
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptContext.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptContext.java Wed Oct 19 08:06:10 2016 -0700
@@ -85,7 +85,8 @@
public Bindings getBindings(int scope);
/**
- * Sets the value of an attribute in a given scope.
+ * Sets the value of an attribute in a given scope. If the scope is <code>GLOBAL_SCOPE</code>
+ * and no Bindings is set for <code>GLOBAL_SCOPE</code>, then setAttribute call is a no-op.
*
* @param name The name of the attribute to set
* @param value The value of the attribute
--- a/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.scripting/share/classes/javax/script/ScriptEngineFactory.java Wed Oct 19 08:06:10 2016 -0700
@@ -216,8 +216,9 @@
* @param statements The statements to be executed. May be return values of
* calls to the <code>getMethodCallSyntax</code> and <code>getOutputStatement</code> methods.
* @return The Program
+ *
+ * @throws NullPointerException if the <code>statements</code> array or any of its elements is null
*/
-
public String getProgram(String... statements);
/**
--- a/jdk/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.scripting/share/classes/javax/script/SimpleScriptContext.java Wed Oct 19 08:06:10 2016 -0700
@@ -213,7 +213,8 @@
}
/**
- * Sets the value of an attribute in a given scope.
+ * Sets the value of an attribute in a given scope. If the scope is <code>GLOBAL_SCOPE</code>
+ * and no Bindings is set for <code>GLOBAL_SCOPE</code>, then setAttribute call is a no-op.
*
* @param name The name of the attribute to set
* @param value The value of the attribute
--- a/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosTicket.java Wed Oct 19 08:06:10 2016 -0700
@@ -694,7 +694,7 @@
"Proxy Ticket " + flags[PROXY_TICKET_FLAG] + "\n" +
"Postdated Ticket " + flags[POSTDATED_TICKET_FLAG] + "\n" +
"Renewable Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
- "Initial Ticket " + flags[RENEWABLE_TICKET_FLAG] + "\n" +
+ "Initial Ticket " + flags[INITIAL_TICKET_FLAG] + "\n" +
"Auth Time = " + String.valueOf(authTime) + "\n" +
"Start Time = " + String.valueOf(startTime) + "\n" +
"End Time = " + endTime.toString() + "\n" +
--- a/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.crypto.ucrypto/solaris/classes/com/oracle/security/ucrypto/UcryptoProvider.java Wed Oct 19 08:06:10 2016 -0700
@@ -50,12 +50,13 @@
try {
// cannot use LoadLibraryAction because that would make the native
// library available to the bootclassloader, but we run in the
- // extension classloader.
- String osname = System.getProperty("os.name");
- if (osname.startsWith("SunOS")) {
- provProp = AccessController.doPrivileged
- (new PrivilegedAction<HashMap<String, ServiceDesc>>() {
- public HashMap<String, ServiceDesc> run() {
+ // platform classloader.
+ provProp = AccessController.doPrivileged
+ (new PrivilegedAction<>() {
+ @Override
+ public HashMap<String, ServiceDesc> run() {
+ String osname = System.getProperty("os.name");
+ if (osname.startsWith("SunOS")) {
try {
DEBUG = Boolean.parseBoolean(System.getProperty("com.oracle.security.ucrypto.debug"));
String javaHome = System.getProperty("java.home");
@@ -66,14 +67,13 @@
return new HashMap<>();
} catch (Error err) {
if (DEBUG) err.printStackTrace();
- return null;
} catch (SecurityException se) {
if (DEBUG) se.printStackTrace();
- return null;
}
}
- });
- }
+ return null;
+ }
+ });
if (provProp != null) {
boolean[] result = loadLibraries();
if (result.length == 2) {
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Main.java Wed Oct 19 08:06:10 2016 -0700
@@ -653,6 +653,7 @@
}
Manifest man = jf.getManifest();
+ boolean hasSignature = false;
// The map to record display info, only used when -verbose provided
// key: signer info string
@@ -668,6 +669,10 @@
while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
String name = je.getName();
+
+ hasSignature = hasSignature
+ || SignatureFileVerifier.isBlockOrSF(name);
+
CodeSigner[] signers = je.getCodeSigners();
boolean isSigned = (signers != null);
anySigned |= isSigned;
@@ -812,8 +817,11 @@
}
if (!anySigned) {
- System.out.println(rb.getString(
- "jar.is.unsigned.signatures.missing.or.not.parsable."));
+ if (hasSignature) {
+ System.out.println(rb.getString("jar.treated.unsigned"));
+ } else {
+ System.out.println(rb.getString("jar.is.unsigned"));
+ }
} else {
boolean warningAppeared = false;
boolean errorAppeared = false;
--- a/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jartool/share/classes/sun/security/tools/jarsigner/Resources.java Wed Oct 19 08:06:10 2016 -0700
@@ -142,8 +142,10 @@
{"no.manifest.", "no manifest."},
{".Signature.related.entries.","(Signature related entries)"},
{".Unsigned.entries.", "(Unsigned entries)"},
- {"jar.is.unsigned.signatures.missing.or.not.parsable.",
- "jar is unsigned. (signatures missing or not parsable)"},
+ {"jar.is.unsigned",
+ "jar is unsigned."},
+ {"jar.treated.unsigned",
+ "Signature not parsable or verifiable. The jar will be treated as unsigned. The jar may have been signed with a weak algorithm that is now disabled. For more information, rerun jarsigner with debug enabled (-J-Djava.security.debug=jar)."},
{"jar.signed.", "jar signed."},
{"jar.signed.with.signer.errors.", "jar signed, with signer errors."},
{"jar.verified.", "jar verified."},
--- a/jdk/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jdwp.agent/share/native/include/jdwpTransport.h Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -96,6 +96,11 @@
*/
enum {
+ /*
+ * If additional flags are added that apply to jdwpCmdPacket,
+ * then debugLoop.c: reader() will need to be updated to
+ * accept more than JDWPTRANSPORT_FLAGS_NONE.
+ */
JDWPTRANSPORT_FLAGS_NONE = 0x0,
JDWPTRANSPORT_FLAGS_REPLY = 0x80
};
--- a/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugLoop.c Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jdwp.agent/share/native/libjdwp/debugLoop.c Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -218,6 +218,20 @@
if (rc != 0 || (rc == 0 && packet.type.cmd.len == 0)) {
shouldListen = JNI_FALSE;
notifyTransportError();
+ } else if (packet.type.cmd.flags != JDWPTRANSPORT_FLAGS_NONE) {
+ /*
+ * Close the connection when we get a jdwpCmdPacket with an
+ * invalid flags field value. This is a protocol violation
+ * so we drop the connection. Also this could be a web
+ * browser generating an HTTP request that passes the JDWP
+ * handshake. HTTP requests requires that everything be in
+ * the ASCII printable range so a flags value of
+ * JDWPTRANSPORT_FLAGS_NONE(0) cannot be generated via HTTP.
+ */
+ ERROR_MESSAGE(("Received jdwpPacket with flags != 0x%d (actual=0x%x) when a jdwpCmdPacket was expected.",
+ JDWPTRANSPORT_FLAGS_NONE, packet.type.cmd.flags));
+ shouldListen = JNI_FALSE;
+ notifyTransportError();
} else {
cmd = &packet.type.cmd;
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/Jlink.java Wed Oct 19 11:51:40 2016 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink;
-
-import java.lang.reflect.Layer;
-import java.nio.ByteOrder;
-import java.nio.file.Path;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Set;
-import jdk.tools.jlink.internal.ExecutableImage;
-import jdk.tools.jlink.internal.JlinkTask;
-import jdk.tools.jlink.plugin.Plugin;
-import jdk.tools.jlink.plugin.PluginException;
-import jdk.tools.jlink.builder.ImageBuilder;
-import jdk.tools.jlink.internal.PluginRepository;
-
-/**
- * API to call jlink.
- */
-public final class Jlink {
-
- /**
- * Create a plugin.
- *
- * @param name Plugin name
- * @param configuration Plugin configuration.
- * @param pluginsLayer Plugins Layer. null means boot layer.
- * @return A new plugin or null if plugin is unknown.
- */
- public static Plugin newPlugin(String name,
- Map<String, String> configuration, Layer pluginsLayer) {
- Objects.requireNonNull(name);
- Objects.requireNonNull(configuration);
- pluginsLayer = pluginsLayer == null ? Layer.boot() : pluginsLayer;
- return PluginRepository.newPlugin(configuration, name, pluginsLayer);
- }
-
- /**
- * A complete plugin configuration. Instances of this class are used to
- * configure jlink.
- */
- public static final class PluginsConfiguration {
-
- private final List<Plugin> plugins;
- private final ImageBuilder imageBuilder;
- private final String lastSorterPluginName;
-
- /**
- * Empty plugins configuration.
- */
- public PluginsConfiguration() {
- this(Collections.emptyList());
- }
-
- /**
- * Plugins configuration.
- *
- * @param plugins List of plugins.
- */
- public PluginsConfiguration(List<Plugin> plugins) {
- this(plugins, null, null);
- }
-
- /**
- * Plugins configuration with a last sorter and an ImageBuilder. No
- * sorting can occur after the last sorter plugin. The ImageBuilder is
- * in charge to layout the image content on disk.
- *
- * @param plugins List of transformer plugins.
- * @param imageBuilder Image builder.
- * @param lastSorterPluginName Name of last sorter plugin, no sorting
- * can occur after it.
- */
- public PluginsConfiguration(List<Plugin> plugins,
- ImageBuilder imageBuilder, String lastSorterPluginName) {
- this.plugins = plugins == null ? Collections.emptyList()
- : plugins;
- this.imageBuilder = imageBuilder;
- this.lastSorterPluginName = lastSorterPluginName;
- }
-
- /**
- * @return the plugins
- */
- public List<Plugin> getPlugins() {
- return plugins;
- }
-
- /**
- * @return the imageBuilder
- */
- public ImageBuilder getImageBuilder() {
- return imageBuilder;
- }
-
- /**
- * @return the lastSorterPluginName
- */
- public String getLastSorterPluginName() {
- return lastSorterPluginName;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
- builder.append("imagebuilder=").append(imageBuilder).append("\n");
- StringBuilder pluginsBuilder = new StringBuilder();
- for (Plugin p : plugins) {
- pluginsBuilder.append(p).append(",");
- }
- builder.append("plugins=").append(pluginsBuilder).append("\n");
- builder.append("lastsorter=").append(lastSorterPluginName).append("\n");
-
- return builder.toString();
- }
- }
-
- /**
- * Jlink configuration. Instances of this class are used to configure jlink.
- */
- public static final class JlinkConfiguration {
-
- private final List<Path> modulepaths;
- private final Path output;
- private final Set<String> modules;
- private final Set<String> limitmods;
-
- private final ByteOrder endian;
-
- /**
- * jlink configuration,
- *
- * @param output Output directory, must not exist.
- * @param modulepaths Modules paths
- * @param modules Root modules to resolve
- * @param limitmods Limit the universe of observable modules
- * @param endian Jimage byte order. Native order by default
- */
- public JlinkConfiguration(Path output,
- List<Path> modulepaths,
- Set<String> modules,
- Set<String> limitmods,
- ByteOrder endian) {
- this.output = output;
- this.modulepaths = modulepaths == null ? Collections.emptyList() : modulepaths;
- this.modules = modules == null ? Collections.emptySet() : modules;
- this.limitmods = limitmods == null ? Collections.emptySet() : limitmods;
- this.endian = endian == null ? ByteOrder.nativeOrder() : endian;
- }
-
- /**
- * jlink configuration,
- *
- * @param output Output directory, must not exist.
- * @param modulepaths Modules paths
- * @param modules Root modules to resolve
- * @param limitmods Limit the universe of observable modules
- */
- public JlinkConfiguration(Path output,
- List<Path> modulepaths,
- Set<String> modules,
- Set<String> limitmods) {
- this(output, modulepaths, modules, limitmods,
- ByteOrder.nativeOrder());
- }
-
- /**
- * @return the modulepaths
- */
- public List<Path> getModulepaths() {
- return modulepaths;
- }
-
- /**
- * @return the byte ordering
- */
- public ByteOrder getByteOrder() {
- return endian;
- }
-
- /**
- * @return the output
- */
- public Path getOutput() {
- return output;
- }
-
- /**
- * @return the modules
- */
- public Set<String> getModules() {
- return modules;
- }
-
- /**
- * @return the limitmods
- */
- public Set<String> getLimitmods() {
- return limitmods;
- }
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder();
-
- builder.append("output=").append(output).append("\n");
- StringBuilder pathsBuilder = new StringBuilder();
- for (Path p : modulepaths) {
- pathsBuilder.append(p).append(",");
- }
- builder.append("modulepaths=").append(pathsBuilder).append("\n");
-
- StringBuilder modsBuilder = new StringBuilder();
- for (String p : modules) {
- modsBuilder.append(p).append(",");
- }
- builder.append("modules=").append(modsBuilder).append("\n");
-
- StringBuilder limitsBuilder = new StringBuilder();
- for (String p : limitmods) {
- limitsBuilder.append(p).append(",");
- }
- builder.append("limitmodules=").append(limitsBuilder).append("\n");
- builder.append("endian=").append(endian).append("\n");
- return builder.toString();
- }
- }
-
- /**
- * Jlink instance constructor, if a security manager is set, the jlink
- * permission is checked.
- */
- public Jlink() {
- if (System.getSecurityManager() != null) {
- System.getSecurityManager().
- checkPermission(new JlinkPermission("jlink"));
- }
- }
-
- /**
- * Build the image.
- *
- * @param config Jlink config, must not be null.
- * @throws PluginException
- */
- public void build(JlinkConfiguration config) {
- build(config, null);
- }
-
- /**
- * Build the image with a plugin configuration.
- *
- * @param config Jlink config, must not be null.
- * @param pluginsConfig Plugins config, can be null
- * @throws PluginException
- */
- public void build(JlinkConfiguration config, PluginsConfiguration pluginsConfig) {
- Objects.requireNonNull(config);
- try {
- JlinkTask.createImage(config, pluginsConfig);
- } catch (Exception ex) {
- throw new PluginException(ex);
- }
- }
-
- /**
- * Post process the image with a plugin configuration.
- *
- * @param image Existing image.
- * @param plugins Plugins cannot be null
- */
- public void postProcess(ExecutableImage image, List<Plugin> plugins) {
- Objects.requireNonNull(image);
- Objects.requireNonNull(plugins);
- try {
- JlinkTask.postProcessImage(image, plugins);
- } catch (Exception ex) {
- throw new PluginException(ex);
- }
- }
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/JlinkPermission.java Wed Oct 19 11:51:40 2016 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package jdk.tools.jlink;
-
-import java.security.BasicPermission;
-
-/**
- * The permission required to use jlink API. The permission target_name is
- * "jlink". e.g.: permission jdk.tools.jlink.plugins.JlinkPermission "jlink";
- *
- */
-public final class JlinkPermission extends BasicPermission {
-
- private static final long serialVersionUID = -3687912306077727801L;
-
- public JlinkPermission(String name) {
- super(name);
- }
-
-}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/builder/DefaultImageBuilder.java Wed Oct 19 08:06:10 2016 -0700
@@ -37,17 +37,17 @@
import java.io.UncheckedIOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
-import java.io.UncheckedIOException;
import java.io.Writer;
import java.lang.module.ModuleDescriptor;
import java.nio.charset.StandardCharsets;
+import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
-import java.nio.file.attribute.PosixFileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
-import java.util.ArrayList;
import java.util.Collections;
+import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -55,7 +55,8 @@
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
-import java.util.stream.Collectors;
+import static java.util.stream.Collectors.*;
+
import jdk.tools.jlink.internal.BasicImageWriter;
import jdk.tools.jlink.internal.plugins.FileCopierPlugin.SymImageFile;
import jdk.tools.jlink.internal.ExecutableImage;
@@ -171,15 +172,36 @@
Properties release = releaseProperties(files);
Path bin = root.resolve("bin");
- files.entries().forEach(f -> {
- if (!f.type().equals(ResourcePoolEntry.Type.CLASS_OR_RESOURCE)) {
+ // check any duplicated resource files
+ Map<Path, Set<String>> duplicates = new HashMap<>();
+ files.entries()
+ .filter(f -> f.type() != ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ .collect(groupingBy(this::entryToImagePath,
+ mapping(ResourcePoolEntry::moduleName, toSet())))
+ .entrySet()
+ .stream()
+ .filter(e -> e.getValue().size() > 1)
+ .forEach(e -> duplicates.put(e.getKey(), e.getValue()));
+
+ // write non-classes resource files to the image
+ files.entries()
+ .filter(f -> f.type() != ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ .forEach(f -> {
try {
accept(f);
+ } catch (FileAlreadyExistsException e) {
+ // error for duplicated entries
+ Path path = entryToImagePath(f);
+ UncheckedIOException x =
+ new UncheckedIOException(path + " duplicated in " +
+ duplicates.get(path), e);
+ x.addSuppressed(e);
+ throw x;
} catch (IOException ioExp) {
throw new UncheckedIOException(ioExp);
}
- }
- });
+ });
+
files.moduleView().modules().forEach(m -> {
// Only add modules that contain packages
if (!m.packages().isEmpty()) {
@@ -226,7 +248,7 @@
version().
stream().
map(Object::toString).
- collect(Collectors.joining("."));
+ collect(joining("."));
}
private static String quote(String str) {
@@ -344,28 +366,69 @@
}
}
+ /**
+ * Returns the file name of this entry
+ */
+ private String entryToFileName(ResourcePoolEntry entry) {
+ if (entry.type() == ResourcePoolEntry.Type.CLASS_OR_RESOURCE)
+ throw new IllegalArgumentException("invalid type: " + entry);
+
+ String module = "/" + entry.moduleName() + "/";
+ String filename = entry.path().substring(module.length());
+ // Remove radical native|config|...
+ return filename.substring(filename.indexOf('/') + 1);
+ }
+
+ /**
+ * Returns the path of the given entry to be written in the image
+ */
+ private Path entryToImagePath(ResourcePoolEntry entry) {
+ switch (entry.type()) {
+ case NATIVE_LIB:
+ String filename = entryToFileName(entry);
+ return Paths.get(nativeDir(filename), filename);
+ case NATIVE_CMD:
+ return Paths.get("bin", entryToFileName(entry));
+ case CONFIG:
+ return Paths.get("conf", entryToFileName(entry));
+ case HEADER_FILE:
+ return Paths.get("include", entryToFileName(entry));
+ case MAN_PAGE:
+ return Paths.get("man", entryToFileName(entry));
+ case TOP:
+ return Paths.get(entryToFileName(entry));
+ case OTHER:
+ return Paths.get("other", entryToFileName(entry));
+ default:
+ throw new IllegalArgumentException("invalid type: " + entry);
+ }
+ }
+
private void accept(ResourcePoolEntry file) throws IOException {
- String fullPath = file.path();
- String module = "/" + file.moduleName() + "/";
- String filename = fullPath.substring(module.length());
- // Remove radical native|config|...
- filename = filename.substring(filename.indexOf('/') + 1);
try (InputStream in = file.content()) {
switch (file.type()) {
case NATIVE_LIB:
- writeEntry(in, destFile(nativeDir(filename), filename));
+ Path dest = root.resolve(entryToImagePath(file));
+ writeEntry(in, dest);
break;
case NATIVE_CMD:
- Path path = destFile("bin", filename);
- writeEntry(in, path);
- path.toFile().setExecutable(true);
+ Path p = root.resolve(entryToImagePath(file));
+ writeEntry(in, p);
+ p.toFile().setExecutable(true);
break;
case CONFIG:
- writeEntry(in, destFile("conf", filename));
+ writeEntry(in, root.resolve(entryToImagePath(file)));
+ break;
+ case HEADER_FILE:
+ writeEntry(in, root.resolve(entryToImagePath(file)));
+ break;
+ case MAN_PAGE:
+ writeEntry(in, root.resolve(entryToImagePath(file)));
break;
case TOP:
break;
case OTHER:
+ String filename = entryToFileName(file);
if (file instanceof SymImageFile) {
SymImageFile sym = (SymImageFile) file;
Path target = root.resolve(sym.getTargetPath());
@@ -379,15 +442,11 @@
}
break;
default:
- throw new InternalError("unexpected entry: " + fullPath);
+ throw new InternalError("unexpected entry: " + file.path());
}
}
}
- private Path destFile(String dir, String filename) {
- return root.resolve(dir).resolve(filename);
- }
-
private void writeEntry(InputStream in, Path dstFile) throws IOException {
Objects.requireNonNull(in);
Objects.requireNonNull(dstFile);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Archive.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Archive.java Wed Oct 19 08:06:10 2016 -0700
@@ -44,9 +44,11 @@
public static enum EntryType {
MODULE_NAME,
CLASS_OR_RESOURCE,
+ CONFIG,
NATIVE_LIB,
NATIVE_CMD,
- CONFIG,
+ HEADER_FILE,
+ MAN_PAGE,
SERVICE;
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ArchiveEntryResourcePoolEntry.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ArchiveEntryResourcePoolEntry.java Wed Oct 19 08:06:10 2016 -0700
@@ -73,6 +73,10 @@
return ResourcePoolEntry.Type.NATIVE_CMD;
case NATIVE_LIB:
return ResourcePoolEntry.Type.NATIVE_LIB;
+ case HEADER_FILE:
+ return ResourcePoolEntry.Type.HEADER_FILE;
+ case MAN_PAGE:
+ return ResourcePoolEntry.Type.MAN_PAGE;
default:
return ResourcePoolEntry.Type.OTHER;
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/ImagePluginConfiguration.java Wed Oct 19 08:06:10 2016 -0700
@@ -33,7 +33,6 @@
import java.util.Map;
import java.util.Map.Entry;
import jdk.tools.jlink.builder.ImageBuilder;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.plugin.Plugin.Category;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal;
+
+import java.lang.reflect.Layer;
+import java.nio.ByteOrder;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.builder.ImageBuilder;
+
+/**
+ * API to call jlink.
+ */
+public final class Jlink {
+
+ /**
+ * Create a plugin.
+ *
+ * @param name Plugin name
+ * @param configuration Plugin configuration.
+ * @param pluginsLayer Plugins Layer. null means boot layer.
+ * @return A new plugin or null if plugin is unknown.
+ */
+ public static Plugin newPlugin(String name,
+ Map<String, String> configuration, Layer pluginsLayer) {
+ Objects.requireNonNull(name);
+ Objects.requireNonNull(configuration);
+ pluginsLayer = pluginsLayer == null ? Layer.boot() : pluginsLayer;
+ return PluginRepository.newPlugin(configuration, name, pluginsLayer);
+ }
+
+ /**
+ * A complete plugin configuration. Instances of this class are used to
+ * configure jlink.
+ */
+ public static final class PluginsConfiguration {
+
+ private final List<Plugin> plugins;
+ private final ImageBuilder imageBuilder;
+ private final String lastSorterPluginName;
+
+ /**
+ * Empty plugins configuration.
+ */
+ public PluginsConfiguration() {
+ this(Collections.emptyList());
+ }
+
+ /**
+ * Plugins configuration.
+ *
+ * @param plugins List of plugins.
+ */
+ public PluginsConfiguration(List<Plugin> plugins) {
+ this(plugins, null, null);
+ }
+
+ /**
+ * Plugins configuration with a last sorter and an ImageBuilder. No
+ * sorting can occur after the last sorter plugin. The ImageBuilder is
+ * in charge to layout the image content on disk.
+ *
+ * @param plugins List of transformer plugins.
+ * @param imageBuilder Image builder.
+ * @param lastSorterPluginName Name of last sorter plugin, no sorting
+ * can occur after it.
+ */
+ public PluginsConfiguration(List<Plugin> plugins,
+ ImageBuilder imageBuilder, String lastSorterPluginName) {
+ this.plugins = plugins == null ? Collections.emptyList()
+ : plugins;
+ this.imageBuilder = imageBuilder;
+ this.lastSorterPluginName = lastSorterPluginName;
+ }
+
+ /**
+ * @return the plugins
+ */
+ public List<Plugin> getPlugins() {
+ return plugins;
+ }
+
+ /**
+ * @return the imageBuilder
+ */
+ public ImageBuilder getImageBuilder() {
+ return imageBuilder;
+ }
+
+ /**
+ * @return the lastSorterPluginName
+ */
+ public String getLastSorterPluginName() {
+ return lastSorterPluginName;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("imagebuilder=").append(imageBuilder).append("\n");
+ StringBuilder pluginsBuilder = new StringBuilder();
+ for (Plugin p : plugins) {
+ pluginsBuilder.append(p).append(",");
+ }
+ builder.append("plugins=").append(pluginsBuilder).append("\n");
+ builder.append("lastsorter=").append(lastSorterPluginName).append("\n");
+
+ return builder.toString();
+ }
+ }
+
+ /**
+ * Jlink configuration. Instances of this class are used to configure jlink.
+ */
+ public static final class JlinkConfiguration {
+
+ private final List<Path> modulepaths;
+ private final Path output;
+ private final Set<String> modules;
+ private final Set<String> limitmods;
+
+ private final ByteOrder endian;
+
+ /**
+ * jlink configuration,
+ *
+ * @param output Output directory, must not exist.
+ * @param modulepaths Modules paths
+ * @param modules Root modules to resolve
+ * @param limitmods Limit the universe of observable modules
+ * @param endian Jimage byte order. Native order by default
+ */
+ public JlinkConfiguration(Path output,
+ List<Path> modulepaths,
+ Set<String> modules,
+ Set<String> limitmods,
+ ByteOrder endian) {
+ this.output = output;
+ this.modulepaths = modulepaths == null ? Collections.emptyList() : modulepaths;
+ this.modules = modules == null ? Collections.emptySet() : modules;
+ this.limitmods = limitmods == null ? Collections.emptySet() : limitmods;
+ this.endian = endian == null ? ByteOrder.nativeOrder() : endian;
+ }
+
+ /**
+ * jlink configuration,
+ *
+ * @param output Output directory, must not exist.
+ * @param modulepaths Modules paths
+ * @param modules Root modules to resolve
+ * @param limitmods Limit the universe of observable modules
+ */
+ public JlinkConfiguration(Path output,
+ List<Path> modulepaths,
+ Set<String> modules,
+ Set<String> limitmods) {
+ this(output, modulepaths, modules, limitmods,
+ ByteOrder.nativeOrder());
+ }
+
+ /**
+ * @return the modulepaths
+ */
+ public List<Path> getModulepaths() {
+ return modulepaths;
+ }
+
+ /**
+ * @return the byte ordering
+ */
+ public ByteOrder getByteOrder() {
+ return endian;
+ }
+
+ /**
+ * @return the output
+ */
+ public Path getOutput() {
+ return output;
+ }
+
+ /**
+ * @return the modules
+ */
+ public Set<String> getModules() {
+ return modules;
+ }
+
+ /**
+ * @return the limitmods
+ */
+ public Set<String> getLimitmods() {
+ return limitmods;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+
+ builder.append("output=").append(output).append("\n");
+ StringBuilder pathsBuilder = new StringBuilder();
+ for (Path p : modulepaths) {
+ pathsBuilder.append(p).append(",");
+ }
+ builder.append("modulepaths=").append(pathsBuilder).append("\n");
+
+ StringBuilder modsBuilder = new StringBuilder();
+ for (String p : modules) {
+ modsBuilder.append(p).append(",");
+ }
+ builder.append("modules=").append(modsBuilder).append("\n");
+
+ StringBuilder limitsBuilder = new StringBuilder();
+ for (String p : limitmods) {
+ limitsBuilder.append(p).append(",");
+ }
+ builder.append("limitmodules=").append(limitsBuilder).append("\n");
+ builder.append("endian=").append(endian).append("\n");
+ return builder.toString();
+ }
+ }
+
+ /**
+ * Jlink instance constructor, if a security manager is set, the jlink
+ * permission is checked.
+ */
+ public Jlink() {
+ if (System.getSecurityManager() != null) {
+ System.getSecurityManager().
+ checkPermission(new JlinkPermission("jlink"));
+ }
+ }
+
+ /**
+ * Build the image.
+ *
+ * @param config Jlink config, must not be null.
+ * @throws PluginException
+ */
+ public void build(JlinkConfiguration config) {
+ build(config, null);
+ }
+
+ /**
+ * Build the image with a plugin configuration.
+ *
+ * @param config Jlink config, must not be null.
+ * @param pluginsConfig Plugins config, can be null
+ * @throws PluginException
+ */
+ public void build(JlinkConfiguration config, PluginsConfiguration pluginsConfig) {
+ Objects.requireNonNull(config);
+ try {
+ JlinkTask.createImage(config, pluginsConfig);
+ } catch (Exception ex) {
+ throw new PluginException(ex);
+ }
+ }
+
+ /**
+ * Post process the image with a plugin configuration.
+ *
+ * @param image Existing image.
+ * @param plugins Plugins cannot be null
+ */
+ public void postProcess(ExecutableImage image, List<Plugin> plugins) {
+ Objects.requireNonNull(image);
+ Objects.requireNonNull(plugins);
+ try {
+ JlinkTask.postProcessImage(image, plugins);
+ } catch (Exception ex) {
+ throw new PluginException(ex);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkPermission.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal;
+
+import java.security.BasicPermission;
+
+/**
+ * The permission required to use jlink API. The permission target_name is
+ * "jlink". e.g.: permission jdk.tools.jlink.plugins.JlinkPermission "jlink";
+ *
+ */
+public final class JlinkPermission extends BasicPermission {
+
+ private static final long serialVersionUID = -3687912306077727801L;
+
+ public JlinkPermission(String name) {
+ super(name);
+ }
+
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkTask.java Wed Oct 19 08:06:10 2016 -0700
@@ -46,11 +46,11 @@
import jdk.internal.module.ConfigurableModuleFinder.Phase;
import jdk.tools.jlink.internal.TaskHelper.BadArgs;
import static jdk.tools.jlink.internal.TaskHelper.JLINK_BUNDLE;
+import jdk.tools.jlink.internal.Jlink.JlinkConfiguration;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.TaskHelper.Option;
import jdk.tools.jlink.internal.TaskHelper.OptionsHelper;
import jdk.tools.jlink.internal.ImagePluginStack.ImageProvider;
-import jdk.tools.jlink.Jlink.JlinkConfiguration;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.PluginException;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.plugin.Plugin;
@@ -213,8 +213,8 @@
}
return EXIT_OK;
- } catch (UncheckedIOException | PluginException | IllegalArgumentException |
- IOException | ResolutionException e) {
+ } catch (PluginException | IllegalArgumentException |
+ UncheckedIOException |IOException | ResolutionException e) {
log.println(taskHelper.getMessage("error.prefix") + " " + e.getMessage());
if (DEBUG) {
e.printStackTrace(log);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JmodArchive.java Wed Oct 19 08:06:10 2016 -0700
@@ -128,12 +128,16 @@
switch (section) {
case CLASSES:
return EntryType.CLASS_OR_RESOURCE;
+ case CONFIG:
+ return EntryType.CONFIG;
case NATIVE_LIBS:
return EntryType.NATIVE_LIB;
case NATIVE_CMDS:
return EntryType.NATIVE_CMD;
- case CONFIG:
- return EntryType.CONFIG;
+ case HEADER_FILES:
+ return EntryType.HEADER_FILE;
+ case MAN_PAGES:
+ return EntryType.MAN_PAGE;
default:
throw new InternalError("unexpected entry: " + section);
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java Wed Oct 19 08:06:10 2016 -0700
@@ -30,9 +30,9 @@
public class Main {
public static void main(String... args) throws Exception {
- JlinkTask t = new JlinkTask();
- int rc = t.run(args);
- System.exit(rc);
+ System.exit(run(new PrintWriter(System.out, true),
+ new PrintWriter(System.err, true),
+ args));
}
/**
@@ -44,6 +44,11 @@
* @return an exit code. 0 means success, non-zero means an error occurred.
*/
public static int run(PrintWriter out, PrintWriter err, String... args) {
+ if (System.getSecurityManager() != null) {
+ System.getSecurityManager().
+ checkPermission(new JlinkPermission("jlink"));
+ }
+
JlinkTask t = new JlinkTask();
t.setLog(out, err);
return t.run(args);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/TaskHelper.java Wed Oct 19 08:06:10 2016 -0700
@@ -49,13 +49,14 @@
import jdk.internal.module.ConfigurableModuleFinder;
import jdk.internal.module.ConfigurableModuleFinder.Phase;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
+import jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
+import jdk.tools.jlink.internal.plugins.ExcludeJmodSectionPlugin;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.Plugin.Category;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.builder.ImageBuilder;
import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.plugins.PluginsResourceBundle;
import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
@@ -323,6 +324,20 @@
addArgumentMap(plugin);
}, "-G");
mainOptions.add(plugOption);
+ } else if (plugin instanceof ExcludeJmodSectionPlugin) {
+ plugOption = new PlugOption(false, (task, opt, arg) -> {
+ Map<String, String> m = addArgumentMap(plugin);
+ m.put(ExcludeJmodSectionPlugin.NAME,
+ ExcludeJmodSectionPlugin.MAN_PAGES);
+ }, "--no-man-pages");
+ mainOptions.add(plugOption);
+
+ plugOption = new PlugOption(false, (task, opt, arg) -> {
+ Map<String, String> m = addArgumentMap(plugin);
+ m.put(ExcludeJmodSectionPlugin.NAME,
+ ExcludeJmodSectionPlugin.INCLUDE_HEADER_FILES);
+ }, "--no-header-files");
+ mainOptions.add(plugOption);
}
}
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/packager/AppRuntimeImageBuilder.java Wed Oct 19 08:06:10 2016 -0700
@@ -26,8 +26,8 @@
package jdk.tools.jlink.internal.packager;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.builder.DefaultImageBuilder;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.internal.JlinkTask;
import jdk.tools.jlink.plugin.Plugin;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/plugins/ExcludeJmodSectionPlugin.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package jdk.tools.jlink.internal.plugins;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import jdk.tools.jlink.plugin.Plugin;
+import jdk.tools.jlink.plugin.PluginException;
+import jdk.tools.jlink.plugin.ResourcePool;
+import jdk.tools.jlink.plugin.ResourcePoolBuilder;
+import jdk.tools.jlink.plugin.ResourcePoolEntry.Type;
+
+/**
+ *
+ * A plugin to exclude a JMOD section such as man pages or header files
+ */
+public final class ExcludeJmodSectionPlugin implements Plugin {
+
+ public static final String NAME = "exclude-jmod-section";
+ public static final String MAN_PAGES = "man";
+ public static final String INCLUDE_HEADER_FILES = "headers";
+
+ private final Set<Type> filters = new HashSet<>();
+
+ @Override
+ public String getName() {
+ return NAME;
+ }
+
+ @Override
+ public void configure(Map<String, String> config) {
+ String arg = config.get(NAME);
+ if (arg.isEmpty()) {
+ throw new PluginException("Section name must be specified");
+ }
+
+ switch (arg) {
+ case MAN_PAGES:
+ filters.add(Type.MAN_PAGE);
+ break;
+ case INCLUDE_HEADER_FILES:
+ filters.add(Type.HEADER_FILE);
+ break;
+ default:
+ throw new PluginException("Invalid section name: " + arg);
+ }
+ }
+
+ @Override
+ public ResourcePool transform(ResourcePool in, ResourcePoolBuilder out) {
+ in.transformAndCopy(entry -> {
+ // filter entries whose type corresponds to the specified JMOD section
+ if (filters.contains(entry.type())) {
+ entry = null;
+ }
+ return entry;
+ }, out);
+ return out.build();
+ }
+
+ @Override
+ public Category getType() {
+ return Category.FILTER;
+ }
+
+ @Override
+ public String getDescription() {
+ return PluginsResourceBundle.getDescription(NAME);
+ }
+
+ @Override
+ public boolean hasArguments() {
+ return true;
+ }
+
+ @Override
+ public String getArgumentsDescription() {
+ return PluginsResourceBundle.getArgument(NAME);
+ }
+}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/plugin/ResourcePoolEntry.java Wed Oct 19 08:06:10 2016 -0700
@@ -24,13 +24,12 @@
*/
package jdk.tools.jlink.plugin;
-import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
-import java.nio.file.Files;
import java.nio.file.Path;
+
import jdk.tools.jlink.internal.ResourcePoolEntryFactory;
/**
@@ -64,6 +63,8 @@
CONFIG,
NATIVE_CMD,
NATIVE_LIB,
+ HEADER_FILE,
+ MAN_PAGE,
TOP,
OTHER
}
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jlink/resources/plugins.properties Wed Oct 19 08:06:10 2016 -0700
@@ -68,6 +68,12 @@
exclude-resources.description=\
Specify resources to exclude. e.g.: **.jcov,glob:**/META-INF/**
+exclude-jmod-section.argument=<section-name>\n\
+where <section-name> is \"man\" or \"headers".
+
+exclude-jmod-section.description=\
+Specify a JMOD section to exclude
+
generate-jli-classes.argument=<none|@filename>
generate-jli-classes.description=\
@@ -145,6 +151,12 @@
plugin.opt.G=\
\ -G, --strip-debug Strip debug information
+plugin.opt.no-man-pages=\
+\ --no-man-pages Exclude man pages
+
+plugin.opt.no-header-files=\
+\ --no-header-files Exclude include header files
+
main.plugin.name=\
\Plugin Name
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/JmodTask.java Wed Oct 19 08:06:10 2016 -0700
@@ -165,6 +165,8 @@
List<Path> cmds;
List<Path> configs;
List<Path> libs;
+ List<Path> headerFiles;
+ List<Path> manPages;
ModuleFinder moduleFinder;
Version moduleVersion;
String mainClass;
@@ -346,6 +348,9 @@
final List<Path> libs = options.libs;
final List<Path> configs = options.configs;
final List<Path> classpath = options.classpath;
+ final List<Path> headerFiles = options.headerFiles;
+ final List<Path> manPages = options.manPages;
+
final Version moduleVersion = options.moduleVersion;
final String mainClass = options.mainClass;
final String osName = options.osName;
@@ -369,6 +374,9 @@
processSection(out, Section.NATIVE_CMDS, cmds);
processSection(out, Section.NATIVE_LIBS, libs);
processSection(out, Section.CONFIG, configs);
+ processSection(out, Section.HEADER_FILES, headerFiles);
+ processSection(out, Section.MAN_PAGES, manPages);
+
}
/**
@@ -596,7 +604,7 @@
return "";
}
- void processClasses(JmodOutputStream zos, List<Path> classpaths)
+ void processClasses(JmodOutputStream out, List<Path> classpaths)
throws IOException
{
if (classpaths == null)
@@ -604,24 +612,24 @@
for (Path p : classpaths) {
if (Files.isDirectory(p)) {
- processSection(zos, Section.CLASSES, p);
+ processSection(out, Section.CLASSES, p);
} else if (Files.isRegularFile(p) && p.toString().endsWith(".jar")) {
try (JarFile jf = new JarFile(p.toFile())) {
- JarEntryConsumer jec = new JarEntryConsumer(zos, jf);
+ JarEntryConsumer jec = new JarEntryConsumer(out, jf);
jf.stream().filter(jec).forEach(jec);
}
}
}
}
- void processSection(JmodOutputStream zos, Section section, List<Path> paths)
+ void processSection(JmodOutputStream out, Section section, List<Path> paths)
throws IOException
{
if (paths == null)
return;
for (Path p : paths)
- processSection(zos, section, p);
+ processSection(out, section, p);
}
void processSection(JmodOutputStream out, Section section, Path top)
@@ -1195,6 +1203,12 @@
= parser.acceptsAll(Set.of("h", "help"), getMessage("main.opt.help"))
.forHelp();
+ OptionSpec<Path> headerFiles
+ = parser.accepts("header-files", getMessage("main.opt.header-files"))
+ .withRequiredArg()
+ .withValuesSeparatedBy(File.pathSeparatorChar)
+ .withValuesConvertedBy(DirPathConverter.INSTANCE);
+
OptionSpec<Path> libs
= parser.accepts("libs", getMessage("main.opt.libs"))
.withRequiredArg()
@@ -1206,6 +1220,12 @@
.withRequiredArg()
.describedAs(getMessage("main.opt.main-class.arg"));
+ OptionSpec<Path> manPages
+ = parser.accepts("man-pages", getMessage("main.opt.man-pages"))
+ .withRequiredArg()
+ .withValuesSeparatedBy(File.pathSeparatorChar)
+ .withValuesConvertedBy(DirPathConverter.INSTANCE);
+
OptionSpec<Path> modulePath
= parser.acceptsAll(Set.of("p", "module-path"),
getMessage("main.opt.module-path"))
@@ -1272,6 +1292,10 @@
options.excludes = opts.valuesOf(excludes);
if (opts.has(libs))
options.libs = opts.valuesOf(libs);
+ if (opts.has(headerFiles))
+ options.headerFiles = opts.valuesOf(headerFiles);
+ if (opts.has(manPages))
+ options.manPages = opts.valuesOf(manPages);
if (opts.has(modulePath)) {
Path[] dirs = opts.valuesOf(modulePath).toArray(new Path[0]);
options.moduleFinder = ModuleFinder.of(dirs);
--- a/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/jdk/tools/jmod/resources/jmod.properties Wed Oct 19 08:06:10 2016 -0700
@@ -54,9 +54,11 @@
main.opt.exclude=Exclude files matching the supplied comma separated pattern\
\ list, each element using one the following forms: <glob-pattern>,\
\ glob:<glob-pattern> or regex:<regex-pattern>
+main.opt.header-files=Location of header files
main.opt.module-version= Module version
main.opt.main-class=Main class
main.opt.main-class.arg=class-name
+main.opt.man-pages=Location of man pages
main.opt.os-name=Operating system name
main.opt.os-name.arg=os-name
main.opt.os-arch=Operating system architecture
--- a/jdk/src/jdk.jlink/share/classes/module-info.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.jlink/share/classes/module-info.java Wed Oct 19 08:06:10 2016 -0700
@@ -38,6 +38,7 @@
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.StripDebugPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludePlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludeFilesPlugin;
+ provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.ExcludeJmodSectionPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.SystemModuleDescriptorPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.StripNativeCommandsPlugin;
provides jdk.tools.jlink.plugin.Plugin with jdk.tools.jlink.internal.plugins.OrderResourcesPlugin;
--- a/jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/src/jdk.pack200/share/native/common-unpack/unpack.cpp Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -174,7 +174,10 @@
const char* utf8String() {
assert(tagMatches(CONSTANT_Utf8));
- assert(value.b.len == strlen((const char*)value.b.ptr));
+ if (value.b.len != strlen((const char*)value.b.ptr)) {
+ unpack_abort("bad utf8 encoding");
+ // and fall through
+ }
return (const char*)value.b.ptr;
}
@@ -1319,10 +1322,10 @@
CHECK;
int nc = 0;
- for ( const char* ncp = form.utf8String() ; *ncp; ncp++) {
- if (*ncp == 'L') nc++;
+ for (int j = 0; j < (int)form.value.b.len; j++) {
+ int c = form.value.b.ptr[j];
+ if (c == 'L') nc++;
}
-
ncTotal += nc;
e.refs = U_NEW(entry*, cpMap[i].nrefs = 1 + nc);
CHECK;
@@ -2830,6 +2833,7 @@
}
assert(!b.le_bci || prevBCI == (int)to_bci(prevBII));
+ CHECK;
switch (b.le_len) {
case 0: break;
case 1: putu1(x); break;
@@ -4026,6 +4030,10 @@
uint len = bcimap.length();
uint* map = (uint*) bcimap.base();
assert(len > 0); // must be initialized before using to_bci
+ if (len == 0) {
+ abort("bad bcimap");
+ return 0;
+ }
if (bii < len)
return map[bii];
// Else it's a fractional or out-of-range BCI.
@@ -4048,6 +4056,7 @@
break;
case 8: // (8) [PH]
putu2(to_bci(code_StackMapTable_P.getInt()));
+ CHECK;
break;
}
}
@@ -4095,6 +4104,7 @@
CHECK;
for (int curIP = 0; ; curIP++) {
+ CHECK;
int curPC = (int)(wpoffset() - codeBase);
bcimap.add(curPC);
ensure_put_space(10); // covers most instrs w/o further bounds check
@@ -4336,6 +4346,7 @@
int curIP = code_fixup_source.get(i);
int destIP = curIP + bc_label.getInt();
int span = to_bci(destIP) - to_bci(curIP);
+ CHECK;
switch (type) {
case 2: putu2_at(bp, (ushort)span); break;
case 4: putu4_at(bp, span); break;
@@ -4532,11 +4543,13 @@
if (tag <= 127) {
// (64-127) [(2)]
if (tag >= 64) put_stackmap_type();
+ CHECK_0;
} else if (tag <= 251) {
// (247) [(1)(2)]
// (248-251) [(1)]
if (tag >= 247) putu2(code_StackMapTable_offset.getInt());
if (tag == 247) put_stackmap_type();
+ CHECK_0;
} else if (tag <= 254) {
// (252) [(1)(2)]
// (253) [(1)(2)(2)]
@@ -4563,6 +4576,7 @@
putu2(count = code_LineNumberTable_N.getInt());
for (j = 0; j < count; j++) {
putu2(to_bci(code_LineNumberTable_bci_P.getInt()));
+ CHECK_0;
putu2(code_LineNumberTable_line.getInt());
}
break;
@@ -4573,9 +4587,11 @@
for (j = 0; j < count; j++) {
int bii = code_LocalVariableTable_bci_P.getInt();
int bci = to_bci(bii);
+ CHECK_0;
putu2(bci);
bii += code_LocalVariableTable_span_O.getInt();
putu2(to_bci(bii) - bci);
+ CHECK_0;
putref(code_LocalVariableTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTable_type_RS.getRefN());
@@ -4590,9 +4606,11 @@
for (j = 0; j < count; j++) {
int bii = code_LocalVariableTypeTable_bci_P.getInt();
int bci = to_bci(bii);
+ CHECK_0;
putu2(bci);
bii += code_LocalVariableTypeTable_span_O.getInt();
putu2(to_bci(bii) - bci);
+ CHECK_0;
putref(code_LocalVariableTypeTable_name_RU.getRefN());
CHECK_0;
putref(code_LocalVariableTypeTable_type_RS.getRefN());
@@ -5036,6 +5054,7 @@
entry* e = file_name.getRef();
CHECK_0;
cur_file.name = e->utf8String();
+ CHECK_0;
bool haveLongSize = (testBit(archive_options, AO_HAVE_FILE_SIZE_HI));
cur_file.size = file_size_hi.getLong(file_size_lo, haveLongSize);
if (testBit(archive_options, AO_HAVE_FILE_MODTIME))
--- a/jdk/test/com/oracle/security/ucrypto/TestAES.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/com/oracle/security/ucrypto/TestAES.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,11 @@
/*
* @test
- * @bug 7088989 8014374
+ * @bug 7088989 8014374 8167512
* @summary Ensure the AES ciphers of OracleUcrypto provider works correctly
* @key randomness
+ * @run main TestAES
+ * @run main/othervm/java.security.policy==empty.policy TestAES
*/
import java.io.*;
--- a/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/java/lang/StackWalker/CallerSensitiveMethod/Main.java Wed Oct 19 08:06:10 2016 -0700
@@ -26,6 +26,7 @@
* @bug 8157464
* @summary Basic test for StackWalker.getCallerClass()
* @library src
+ * @modules java.base/jdk.internal.reflect
* @build java.base/java.util.CSM csm/*
* @run main/othervm csm/jdk.test.CallerSensitiveTest
* @run main/othervm csm/jdk.test.CallerSensitiveTest sm
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/AccessControlTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,454 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import util.ClassSupplier;
+import util.MemberFactory;
+
+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 java.lang.reflect.Modifier;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import static java.util.stream.Collectors.groupingBy;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.mapping;
+import static java.util.stream.Collectors.toCollection;
+import static util.MemberFactory.*;
+import static util.MemberFactory.Group.*;
+import static util.ClassSupplier.*;
+
+/**
+ * @test
+ * @summary An exhaustive test of reflective access controls
+ * @bug 6378384
+ * @build a.PublicSuper a.Package b.PublicSub b.Package
+ * util.MemberFactory util.ClassSupplier
+ * @run main AccessControlTest
+ */
+public class AccessControlTest {
+
+ public static void main(String[] args) throws Exception {
+ boolean ok = true;
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_A)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PACKAGE_CLASS_IN_PKG_B)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_A).target(PACKAGE_CLASS_IN_PKG_A)
+ .denied (ALL)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUPERCLASS_IN_PKG_A)
+ .allowed(PUBLIC_MEMBERS, PROTECTED_STATIC_F_M)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_INSTANCE_F_M,
+ PROTECTED_C)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUPERCLASS_IN_PKG_A).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(PUBLIC_MEMBERS, PROTECTED_INSTANCE_F_M, PROTECTED_STATIC_F_M)
+ .denied (PRIVATE_MEMBERS, PACKAGE_MEMBERS, PROTECTED_C)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PACKAGE_CLASS_IN_PKG_B).target(PACKAGE_CLASS_IN_PKG_B)
+ .allowed(PACKAGE_MEMBERS, PROTECTED_MEMBERS, PUBLIC_MEMBERS)
+ .denied (PRIVATE_MEMBERS)
+ .perform();
+
+ ok &= new Test()
+ .current(PUBLIC_SUBCLASS_IN_PKG_B)
+ .member (PUBLIC_SUBCLASS_IN_PKG_B).target(PUBLIC_SUBCLASS_IN_PKG_B)
+ .allowed(ALL)
+ .perform();
+
+ if (ok) {
+ System.out.println("\nAll cases passed.");
+ } else {
+ throw new RuntimeException("Some cases failed - see log.");
+ }
+ }
+
+ // use this for generating an exhaustive set of test cases on stdout
+ public static class Generate {
+ public static void main(String[] args) {
+ for (ClassSupplier current : ClassSupplier.values()) {
+ for (ClassSupplier member : ClassSupplier.values()) {
+ for (ClassSupplier target : ClassSupplier.values()) {
+ if (member.get().isAssignableFrom(target.get())) {
+ new Test()
+ .current(current).member(member).target(target)
+ .allowed(ALL)
+ .perform(true);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ static class Test {
+
+ ClassSupplier currentClassSupplier, memberClassSupplier, targetClassSupplier;
+ EnumSet<MemberFactory> expectAllowedMembers = EnumSet.noneOf(MemberFactory.class);
+ EnumSet<MemberFactory> expectDeniedMembers = EnumSet.noneOf(MemberFactory.class);
+
+ Test current(ClassSupplier current) {
+ currentClassSupplier = current;
+ return this;
+ }
+
+ Test member(ClassSupplier member) {
+ memberClassSupplier = member;
+ return this;
+ }
+
+ Test target(ClassSupplier target) {
+ targetClassSupplier = target;
+ return this;
+ }
+
+ Test allowed(MemberFactory... allowed) {
+ expectAllowedMembers = MemberFactory.asSet(allowed);
+ return this;
+ }
+
+ Test allowed(MemberFactory.Group... allowedGroups) {
+ expectAllowedMembers = MemberFactory.groupsToMembers(
+ MemberFactory.Group.asSet(allowedGroups));
+ return this;
+ }
+
+ Test denied(MemberFactory... denied) {
+ expectDeniedMembers = MemberFactory.asSet(denied);
+ return this;
+ }
+
+ Test denied(MemberFactory.Group... deniedGroups) {
+ expectDeniedMembers = MemberFactory.groupsToMembers(
+ MemberFactory.Group.asSet(deniedGroups));
+ return this;
+ }
+
+ boolean perform() {
+ return perform(false);
+ }
+
+ boolean perform(boolean generateCases) {
+
+ // some validation 1st
+ EnumSet<MemberFactory> intersection = EnumSet.copyOf(expectAllowedMembers);
+ intersection.retainAll(expectDeniedMembers);
+ if (!intersection.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Expected allowed and denied MemberFactories have non-empty intersection: " +
+ intersection);
+ }
+
+ EnumSet<MemberFactory> missing = EnumSet.allOf(MemberFactory.class);
+ missing.removeAll(expectAllowedMembers);
+ missing.removeAll(expectDeniedMembers);
+ if (!missing.isEmpty()) {
+ throw new IllegalArgumentException(
+ "Union of expected allowed and denied MemberFactories is missing elements: " +
+ missing);
+ }
+
+ // retrieve method that will perform reflective access
+ Method checkAccessMethod;
+ try {
+ checkAccessMethod = currentClassSupplier.get().getDeclaredMethod(
+ "checkAccess", AccessibleObject.class, Object.class);
+ // in case of inaccessible currentClass
+ checkAccessMethod.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+
+ // construct a target object (for instance field/method)
+ Object target;
+ Constructor<?> targetConstructor =
+ (Constructor<?>) PUBLIC_CONSTRUCTOR.apply(targetClassSupplier.get());
+ // in case of inaccessible targetClass
+ targetConstructor.setAccessible(true);
+ try {
+ target = targetConstructor.newInstance(
+ new Object[targetConstructor.getParameterCount()]);
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+
+ Class<?> memberClass = memberClassSupplier.get();
+
+ Map<Boolean, EnumSet<MemberFactory>> actualMembers = Stream.concat(
+
+ expectAllowedMembers.stream().map(member -> new Trial(member, true)),
+ expectDeniedMembers.stream().map(member -> new Trial(member, false))
+
+ ).map(trial -> {
+
+ // obtain AccessibleObject to be used to perform reflective access
+ AccessibleObject accessibleObject = trial.member.apply(memberClass);
+
+ // only need target 'obj' for instance fields and methods
+ Object obj =
+ (accessibleObject instanceof Field &&
+ !Modifier.isStatic(((Field) accessibleObject).getModifiers())
+ ||
+ accessibleObject instanceof Method &&
+ !Modifier.isStatic(((Method) accessibleObject).getModifiers())
+ )
+ ? target : null;
+
+ // invoke checkAccess method and let it perform the reflective access
+ try {
+ checkAccessMethod.invoke(null, accessibleObject, obj);
+ trial.actualAllowed = true;
+ } catch (IllegalAccessException e) {
+ // should not happen as checkAccessMethod.isAccessible()
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ if (e.getTargetException() instanceof IllegalAccessException) {
+ trial.actualAllowed = false;
+ } else {
+ // any other Exception is a fault in test or infrastructure - fail fast
+ throw new RuntimeException(e.getTargetException());
+ }
+ }
+
+ if (!generateCases) {
+ System.out.printf(
+ "%-26s accessing %26s's %-25s %-43s - expected %s, actual %s: %s\n",
+ currentClassSupplier, memberClassSupplier, trial.member.name(),
+ (obj == null ? "" : "with instance of " + targetClassSupplier),
+ (trial.expectAllowed ? "allowed" : "denied "),
+ (trial.actualAllowed ? "allowed" : "denied "),
+ (trial.expectAllowed == trial.actualAllowed ? "OK" : "FAILURE")
+ );
+ }
+
+ return trial;
+
+ }).collect(
+ groupingBy(
+ Trial::isActualAllowed,
+ mapping(
+ Trial::getMember,
+ toCollection(() -> EnumSet.noneOf(MemberFactory.class))))
+ );
+
+ EnumSet<MemberFactory> actualAllowedMembers =
+ Optional.ofNullable(actualMembers.get(true))
+ .orElse(EnumSet.noneOf(MemberFactory.class));
+ EnumSet<MemberFactory> actualDeniedMembers =
+ Optional.ofNullable(actualMembers.get(false))
+ .orElse(EnumSet.noneOf(MemberFactory.class));
+
+ if (generateCases) {
+ System.out.printf(
+ " ok &= new Test()\n" +
+ " .current(%s)\n" +
+ " .member (%s).target(%s)\n",
+ currentClassSupplier,
+ memberClassSupplier, targetClassSupplier
+ );
+
+ if (!actualAllowedMembers.isEmpty()) {
+ EnumSet<? extends Enum> actualAllowed =
+ MemberFactory.membersToGroupsOrNull(actualAllowedMembers);
+ if (actualAllowed == null)
+ actualAllowed = actualAllowedMembers;
+ System.out.print(
+ chunkBy(3, actualAllowed.stream().map(Enum::name))
+ .map(chunk -> chunk.collect(joining(", ")))
+ .collect(joining(",\n" +
+ " ",
+ " .allowed(",
+ ")\n"))
+ );
+ }
+
+ if (!actualDeniedMembers.isEmpty()) {
+ EnumSet<? extends Enum> actualDenied =
+ MemberFactory.membersToGroupsOrNull(actualDeniedMembers);
+ if (actualDenied == null)
+ actualDenied = actualAllowedMembers;
+ System.out.print(
+ chunkBy(3, actualDenied.stream().map(Enum::name))
+ .map(chunk -> chunk.collect(joining(", ")))
+ .collect(joining(",\n" +
+ " ",
+ " .denied (",
+ ")\n"))
+ );
+ }
+
+ System.out.print(
+ " .perform();\n"
+ );
+ }
+
+ return expectAllowedMembers.equals(actualAllowedMembers) &&
+ expectDeniedMembers.equals(actualDeniedMembers);
+ }
+ }
+
+ private static <T> Stream<Stream<T>> chunkBy(int chunkSize, Stream<T> stream) {
+ Iterator<T> elements = stream.iterator();
+ Stream.Builder<Stream<T>> b1 = Stream.builder();
+ while (elements.hasNext()) {
+ Stream.Builder<T> b2 = Stream.builder();
+ for (int i = 0; i < chunkSize && elements.hasNext(); i++) {
+ b2.accept(elements.next());
+ }
+ b1.accept(b2.build());
+ }
+ return b1.build();
+ }
+
+ private static class Trial {
+ final MemberFactory member;
+ final boolean expectAllowed;
+ boolean actualAllowed;
+
+ Trial(MemberFactory member, boolean expectAllowed) {
+ this.member = member;
+ this.expectAllowed = expectAllowed;
+ }
+
+ MemberFactory getMember() {
+ return member;
+ }
+
+ boolean isActualAllowed() {
+ return actualAllowed;
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/a/Package.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package a;
+
+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;
+
+/**
+ * A package-private class in a.
+ */
+class Package {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private Package(Void _1, Void _2, Void _3) {}
+ Package(Void _1, Void _2) {}
+ protected Package(Void _1) {}
+ public Package() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/a/PublicSuper.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package a;
+
+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;
+
+/**
+ * A public class in a which is a superclass of public class in b.
+ */
+public class PublicSuper {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private PublicSuper(Void _1, Void _2, Void _3) {}
+ PublicSuper(Void _1, Void _2) {}
+ protected PublicSuper(Void _1) {}
+ public PublicSuper() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/b/Package.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package b;
+
+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;
+
+/**
+ * A package-private class in b.
+ */
+class Package {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private Package(Void _1, Void _2, Void _3) {}
+ Package(Void _1, Void _2) {}
+ protected Package(Void _1) {}
+ public Package() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/b/PublicSub.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package b;
+
+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;
+
+/**
+ * A public class in b which is a subclass of public class in a.
+ */
+public class PublicSub extends a.PublicSuper {
+
+ // fields
+ private static int privateStatic;
+ private int privateInstance;
+ static int packageStatic;
+ int packageInstance;
+ protected static int protectedStatic;
+ protected int protectedInstance;
+ public static int publicStatic;
+ public int publicInstance;
+
+ // methods
+ private static int privateStatic() { return 42; }
+ private int privateInstance() { return 42; }
+ static int packageStatic() { return 42; }
+ int packageInstance() { return 42; }
+ protected static int protectedStatic() { return 42; }
+ protected int protectedInstance() { return 42; }
+ public static int publicStatic() { return 42; }
+ public int publicInstance() { return 42; }
+
+ // constructors
+ private PublicSub(Void _1, Void _2, Void _3) {}
+ PublicSub(Void _1, Void _2) {}
+ protected PublicSub(Void _1) {}
+ public PublicSub() {}
+
+
+ // testing method
+ public static void checkAccess(AccessibleObject accessibleObject, Object obj)
+ throws IllegalAccessException,
+ InvocationTargetException,
+ InstantiationException
+ {
+ if (accessibleObject instanceof Field) {
+ Field field = (Field) accessibleObject;
+ field.set(obj, 42);
+ field.get(obj);
+ } else if (accessibleObject instanceof Method) {
+ Method method = (Method) accessibleObject;
+ method.invoke(obj);
+ } else if (accessibleObject instanceof Constructor) {
+ Constructor<?> constructor = (Constructor<?>) accessibleObject;
+ Object[] params = new Object[constructor.getParameterCount()];
+ constructor.newInstance(params);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/util/ClassSupplier.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * 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 util;
+
+import java.util.function.Supplier;
+
+/**
+ * An enumeration of suppliers of test classes.
+ */
+public enum ClassSupplier implements Supplier<Class<?>> {
+ PACKAGE_CLASS_IN_PKG_A("a.Package"),
+ PUBLIC_SUPERCLASS_IN_PKG_A("a.PublicSuper"),
+ PACKAGE_CLASS_IN_PKG_B("b.Package"),
+ PUBLIC_SUBCLASS_IN_PKG_B("b.PublicSub");
+
+ private final String className;
+
+ ClassSupplier(String className) {
+ this.className = className;
+ }
+
+ @Override
+ public Class<?> get() {
+ try {
+ return Class.forName(className);
+ } catch (ClassNotFoundException e) {
+ throw (Error) new NoClassDefFoundError(className).initCause(e);
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/reflect/AccessControl/util/MemberFactory.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package util;
+
+import java.lang.reflect.AccessibleObject;
+import java.util.Arrays;
+import java.util.EnumSet;
+import java.util.Iterator;
+import java.util.function.BiFunction;
+import java.util.function.Function;
+
+import static util.MemberFactory.Kind.CONSTRUCTOR;
+import static util.MemberFactory.Kind.FIELD;
+import static util.MemberFactory.Kind.METHOD;
+
+/**
+ * Enumeration of:
+ * <p>
+ * {private, package, protected, public} x {instance, static} x {field, method}
+ * <p>
+ * and:
+ * <p>
+ * {private, package, protected, public} x {constructor},
+ * <p>
+ * with each element acting as a factory of AccessibleObject(s)
+ * declared by given declaringClass(es).
+ */
+public enum MemberFactory implements Function<Class<?>, AccessibleObject> {
+ // instance fields
+ PRIVATE_INSTANCE_FIELD(FIELD, "privateInstance"),
+ PACKAGE_INSTANCE_FIELD(FIELD, "packageInstance"),
+ PROTECTED_INSTANCE_FIELD(FIELD, "protectedInstance"),
+ PUBLIC_INSTANCE_FIELD(FIELD, "publicInstance"),
+ // instance methods
+ PRIVATE_INSTANCE_METHOD(METHOD, "privateInstance"),
+ PACKAGE_INSTANCE_METHOD(METHOD, "packageInstance"),
+ PROTECTED_INSTANCE_METHOD(METHOD, "protectedInstance"),
+ PUBLIC_INSTANCE_METHOD(METHOD, "publicInstance"),
+ // static fields
+ PRIVATE_STATIC_FIELD(FIELD, "privateStatic"),
+ PACKAGE_STATIC_FIELD(FIELD, "packageStatic"),
+ PROTECTED_STATIC_FIELD(FIELD, "protectedStatic"),
+ PUBLIC_STATIC_FIELD(FIELD, "publicStatic"),
+ // static methods
+ PRIVATE_STATIC_METHOD(METHOD, "privateStatic"),
+ PACKAGE_STATIC_METHOD(METHOD, "packageStatic"),
+ PROTECTED_STATIC_METHOD(METHOD, "protectedStatic"),
+ PUBLIC_STATIC_METHOD(METHOD, "publicStatic"),
+ // constructors
+ PRIVATE_CONSTRUCTOR(CONSTRUCTOR, null, Void.class, Void.class, Void.class),
+ PACKAGE_CONSTRUCTOR(CONSTRUCTOR, null, Void.class, Void.class),
+ PROTECTED_CONSTRUCTOR(CONSTRUCTOR, null, Void.class),
+ PUBLIC_CONSTRUCTOR(CONSTRUCTOR, null),;
+
+ final Kind kind;
+ final String name;
+ final Class<?>[] parameterTypes;
+
+ MemberFactory(Kind kind, String name, Class<?>... parameterTypes) {
+ this.kind = kind;
+ this.name = name;
+ this.parameterTypes = parameterTypes;
+ }
+
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass) {
+ return kind.apply(declaringClass, this);
+ }
+
+ public static EnumSet<MemberFactory> asSet(MemberFactory... members) {
+ return members.length == 0 ? EnumSet.noneOf(MemberFactory.class)
+ : EnumSet.copyOf(Arrays.asList(members));
+ }
+
+ /**
+ * @param members the set of MemberFactory(s) to convert to set of
+ * MemberFactory.Group(s).
+ * @return a set of groups that cover all elements of the members set if
+ * such set of groups exists or null if it doesn't.
+ */
+ public static EnumSet<Group> membersToGroupsOrNull(EnumSet<MemberFactory> members) {
+ EnumSet<MemberFactory> mSet = members.clone();
+ EnumSet<Group> gSet = EnumSet.allOf(Group.class);
+ Iterator<Group> gIter = gSet.iterator();
+ while (gIter.hasNext()) {
+ Group g = gIter.next();
+ if (mSet.containsAll(g.members)) {
+ mSet.removeAll(g.members);
+ } else {
+ gIter.remove();
+ }
+ }
+ return mSet.isEmpty() ? gSet : null;
+ }
+
+ /**
+ * @param groups the set of MemberFactory.Group(s) to convert to set of
+ * MemberFactory(s).
+ * @return a set of members as a union of members of all groups.
+ */
+ public static EnumSet<MemberFactory> groupsToMembers(EnumSet<Group> groups) {
+ EnumSet<MemberFactory> mSet = EnumSet.noneOf(MemberFactory.class);
+ for (Group g : groups) {
+ mSet.addAll(g.members);
+ }
+ return mSet;
+ }
+
+ enum Kind implements BiFunction<Class<?>, MemberFactory, AccessibleObject> {
+ FIELD {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredField(factory.name);
+ } catch (NoSuchFieldException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ },
+ METHOD {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredMethod(factory.name, factory.parameterTypes);
+ } catch (NoSuchMethodException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ },
+ CONSTRUCTOR {
+ @Override
+ public AccessibleObject apply(Class<?> declaringClass, MemberFactory factory) {
+ assert factory.kind == this;
+ try {
+ return declaringClass.getDeclaredConstructor(factory.parameterTypes);
+ } catch (NoSuchMethodException e) {
+ // a fault in test - fail fast
+ throw new RuntimeException(e.getMessage());
+ }
+ }
+ }
+ }
+
+ /**
+ * We define groups of MemberFactory(s) for members that commonly
+ * exhibit same access restrictions in various cases in order to allow
+ * specifying groups instead of individual members in the test cases,
+ * making them less verbose.
+ */
+ public enum Group {
+ // all members
+ ALL(MemberFactory.values()),
+ // all private members
+ PRIVATE_MEMBERS(PRIVATE_INSTANCE_FIELD, PRIVATE_INSTANCE_METHOD,
+ PRIVATE_STATIC_FIELD, PRIVATE_STATIC_METHOD,
+ PRIVATE_CONSTRUCTOR),
+ // all package members
+ PACKAGE_MEMBERS(PACKAGE_INSTANCE_FIELD, PACKAGE_INSTANCE_METHOD,
+ PACKAGE_STATIC_FIELD, PACKAGE_STATIC_METHOD,
+ PACKAGE_CONSTRUCTOR),
+ // all protected members
+ PROTECTED_MEMBERS(PROTECTED_INSTANCE_FIELD, PROTECTED_INSTANCE_METHOD,
+ PROTECTED_STATIC_FIELD, PROTECTED_STATIC_METHOD,
+ PROTECTED_CONSTRUCTOR),
+ // all public members
+ PUBLIC_MEMBERS(PUBLIC_INSTANCE_FIELD, PUBLIC_INSTANCE_METHOD,
+ PUBLIC_STATIC_FIELD, PUBLIC_STATIC_METHOD,
+ PUBLIC_CONSTRUCTOR),
+ // instance field and method pairs
+ PRIVATE_INSTANCE_F_M(PRIVATE_INSTANCE_FIELD, PRIVATE_INSTANCE_METHOD),
+ PACKAGE_INSTANCE_F_M(PACKAGE_INSTANCE_FIELD, PACKAGE_INSTANCE_METHOD),
+ PROTECTED_INSTANCE_F_M(PROTECTED_INSTANCE_FIELD, PROTECTED_INSTANCE_METHOD),
+ PUBLIC_INSTANCE_F_M(PUBLIC_INSTANCE_FIELD, PUBLIC_INSTANCE_METHOD),
+ // static field and method pairs
+ PRIVATE_STATIC_F_M(PRIVATE_STATIC_FIELD, PRIVATE_STATIC_METHOD),
+ PACKAGE_STATIC_F_M(PACKAGE_STATIC_FIELD, PACKAGE_STATIC_METHOD),
+ PROTECTED_STATIC_F_M(PROTECTED_STATIC_FIELD, PROTECTED_STATIC_METHOD),
+ PUBLIC_STATIC_F_M(PUBLIC_STATIC_FIELD, PUBLIC_STATIC_METHOD),
+ // constructor singles
+ PRIVATE_C(PRIVATE_CONSTRUCTOR),
+ PACKAGE_C(PACKAGE_CONSTRUCTOR),
+ PROTECTED_C(PROTECTED_CONSTRUCTOR),
+ PUBLIC_C(PUBLIC_CONSTRUCTOR);
+
+ final EnumSet<MemberFactory> members;
+
+ Group(MemberFactory... members) {
+ this.members = EnumSet.copyOf(Arrays.asList(members));
+ }
+
+ public static EnumSet<Group> asSet(Group... groups) {
+ return groups.length == 0 ? EnumSet.noneOf(Group.class)
+ : EnumSet.copyOf(Arrays.asList(groups));
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/rmi/server/UnicastRemoteObject/serialFilter/FilterUROTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.InvalidClassException;
+import java.io.ObjectInputFilter;
+import java.io.Serializable;
+
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.UnmarshalException;
+import java.rmi.server.UnicastRemoteObject;
+
+import java.util.Objects;
+
+import org.testng.Assert;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+/*
+ * @test
+ * @run testng/othervm FilterUROTest
+ * @summary Check that objects are exported with ObjectInputFilters via UnicastRemoteObject
+ */
+public class FilterUROTest {
+
+ /**
+ * Data to test serialFilter call counts.
+ * - name
+ * - Object
+ * - expected count of calls to checkInput.
+ *
+ * @return array of test data
+ */
+ @DataProvider(name = "bindData")
+ static Object[][] bindObjects() {
+ Object[][] data = {
+ {"SimpleString", "SimpleString", 0},
+ {"String", new XX("now is the time"), 1},
+ {"String[]", new XX(new String[3]), 3},
+ {"Long[4]", new XX(new Long[4]), 3},
+ {"RejectME", new XX(new RejectME()), -1},
+ };
+ return data;
+ }
+
+ /*
+ * Test exporting an object with a serialFilter using exportObject().
+ * Send some objects and check the number of calls to the serialFilter.
+ */
+ @Test(dataProvider = "bindData")
+ public void useExportObject(String name, Object obj, int expectedFilterCount) throws RemoteException {
+ try {
+ RemoteImpl impl = RemoteImpl.create();
+ Echo client = (Echo) UnicastRemoteObject
+ .exportObject(impl, 0, impl.checker);
+ int count = client.filterCount(obj);
+ System.out.printf("count: %d, obj: %s%n", count, obj);
+ Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
+ } catch (RemoteException rex) {
+ if (expectedFilterCount == -1 &&
+ UnmarshalException.class.equals(rex.getCause().getClass()) &&
+ InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
+ return; // normal expected exception
+ }
+ rex.printStackTrace();
+ Assert.fail("unexpected remote exception", rex);
+ } catch (Exception rex) {
+ Assert.fail("unexpected exception", rex);
+ }
+ }
+
+ /*
+ * Test exporting an object with a serialFilter using exportObject()
+ * with explicit (but null) SocketFactories.
+ * Send some objects and check the number of calls to the serialFilter.
+ */
+ @Test(dataProvider = "bindData")
+ public void useExportObject2(String name, Object obj, int expectedFilterCount) throws RemoteException {
+ try {
+ RemoteImpl impl = RemoteImpl.create();
+ Echo client = (Echo) UnicastRemoteObject
+ .exportObject(impl, 0, null, null, impl.checker);
+ int count = client.filterCount(obj);
+ System.out.printf("count: %d, obj: %s%n", count, obj);
+ Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
+ } catch (RemoteException rex) {
+ if (expectedFilterCount == -1 &&
+ UnmarshalException.class.equals(rex.getCause().getClass()) &&
+ InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
+ return; // normal expected exception
+ }
+ rex.printStackTrace();
+ Assert.fail("unexpected remote exception", rex);
+ } catch (Exception rex) {
+ Assert.fail("unexpected exception", rex);
+ }
+ }
+
+ /**
+ * A simple Serializable holding an object that is passed by value.
+ * It and its contents are checked by the filter.
+ */
+ static class XX implements Serializable {
+ private static final long serialVersionUID = 362498820763181265L;
+
+ final Object obj;
+
+ XX(Object obj) {
+ this.obj = obj;
+ }
+
+ public String toString() {
+ return super.toString() + "//" + Objects.toString(obj);
+ }
+ }
+
+ interface Echo extends Remote {
+ int filterCount(Object obj) throws RemoteException;
+ }
+
+ /**
+ * This remote object just counts the calls to the serialFilter
+ * and returns it. The caller can check the number against
+ * what was expected for the object passed as an argument.
+ * A new RemoteImpl is used for each test so the count starts at zero again.
+ */
+ static class RemoteImpl implements Echo {
+
+ private static final long serialVersionUID = -6999613679881262446L;
+
+ transient Checker checker;
+
+ static RemoteImpl create() throws RemoteException {
+ RemoteImpl impl = new RemoteImpl(new Checker());
+ return impl;
+ }
+
+ private RemoteImpl(Checker checker) throws RemoteException {
+ this.checker = checker;
+ }
+
+ public int filterCount(Object obj) throws RemoteException {
+ return checker.count();
+ }
+
+ }
+
+ /**
+ * A ObjectInputFilter that just counts when it is called.
+ */
+ static class Checker implements ObjectInputFilter {
+ int count;
+
+ @Override
+ public Status checkInput(FilterInfo filterInfo) {
+ if (filterInfo.serialClass() == RejectME.class) {
+ return Status.REJECTED;
+ }
+ count++;
+ return Status.UNDECIDED;
+ }
+
+ public int count() {
+ return count;
+ }
+ }
+
+ /**
+ * A class to be rejected by the filter.
+ */
+ static class RejectME implements Serializable {
+ private static final long serialVersionUID = 2L;
+ }
+}
--- a/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/javax/crypto/SecretKeyFactory/FailOverTest.sh Wed Oct 19 08:06:10 2016 -0700
@@ -88,6 +88,7 @@
${TESTJAVA}${FS}bin${FS}java \
${TESTVMOPTS} \
+ -Djava.security.properties=${TESTSRC}${FS}security.properties \
-classpath "${TESTSRC}${FS}P1.jar${PS}${TESTSRC}${FS}P2.jar${PS}." \
FailOverTest
result=$?
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/javax/crypto/SecretKeyFactory/security.properties Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,6 @@
+# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+# ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+
+jdk.security.provider.preferred=
+jdk.jar.disabledAlgorithms=
+
--- a/jdk/test/javax/script/DummyScriptEngineFactory.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/javax/script/DummyScriptEngineFactory.java Wed Oct 19 08:06:10 2016 -0700
@@ -91,9 +91,10 @@
}
public String getProgram(String... statements) {
+ Objects.requireNonNull(statements);
StringBuffer buf = new StringBuffer();
- for (int i = 0; i < statements.length; i++) {
- buf.append(statements[i]);
+ for (String stat : statements) {
+ buf.append(Objects.requireNonNull(stat));
}
return buf.toString();
}
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/OriginServer.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/OriginServer.java Wed Oct 19 08:06:10 2016 -0700
@@ -36,10 +36,12 @@
* Http get request in both clear and secure channel
*/
-public abstract class OriginServer implements Runnable {
+public abstract class OriginServer implements Runnable, Closeable {
private ServerSocket server = null;
Exception serverException = null;
+ private volatile boolean closed;
+
/**
* Constructs a OriginServer based on ss and
* obtains a response data's bytecodes using the method
@@ -53,6 +55,14 @@
throw serverException;
}
+ @Override
+ public void close() throws IOException {
+ if (closed)
+ return;
+ closed = true;
+ server.close();
+ }
+
/**
* Returns an array of bytes containing the bytes for
* the data sent in the response.
@@ -73,8 +83,10 @@
try {
socket = server.accept();
} catch (IOException e) {
- System.out.println("Class Server died: " + e.getMessage());
- serverException = e;
+ if (!closed) {
+ System.out.println("Class Server died: " + e.getMessage());
+ serverException = e;
+ }
return;
}
try {
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyAuthTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -23,22 +23,31 @@
/*
* @test
- * @bug 4323990 4413069
+ * @bug 4323990 4413069 8160838
* @summary HttpsURLConnection doesn't send Proxy-Authorization on CONNECT
* Incorrect checking of proxy server response
* @modules java.base/sun.net.www
- * @run main/othervm ProxyAuthTest
- *
- * No way to reserve and restore java.lang.Authenticator, need to run this
- * test in othervm mode.
+ * @run main/othervm ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic, ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=BAsIc ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Basic,Digest ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Unknown,bAsIc ProxyAuthTest fail
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes= ProxyAuthTest succeed
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=Digest,NTLM,Negotiate ProxyAuthTest succeed
+ * @run main/othervm -Djdk.http.auth.tunneling.disabledSchemes=UNKNOWN,notKnown ProxyAuthTest succeed
*/
+// No way to reserve and restore java.lang.Authenticator, as well as read-once
+// system properties, so this tests needs to run in othervm mode.
+
import java.io.*;
import java.net.*;
import java.security.KeyStore;
import javax.net.*;
import javax.net.ssl.*;
import java.security.cert.*;
+import static java.nio.charset.StandardCharsets.US_ASCII;
/*
* ProxyAuthTest.java -- includes a simple server that can serve
@@ -75,7 +84,7 @@
*/
public byte[] getBytes() {
return "Proxy authentication for tunneling succeeded ..".
- getBytes();
+ getBytes(US_ASCII);
}
}
@@ -83,6 +92,13 @@
* Main method to create the server and the client
*/
public static void main(String args[]) throws Exception {
+ boolean expectSuccess;
+ if (args[0].equals("succeed")) {
+ expectSuccess = true;
+ } else {
+ expectSuccess = false;
+ }
+
String keyFilename =
System.getProperty("test.src", "./") + "/" + pathToStores +
"/" + keyStoreFile;
@@ -99,12 +115,13 @@
/*
* setup the server
*/
+ Closeable server;
try {
ServerSocketFactory ssf =
ProxyAuthTest.getServerSocketFactory(useSSL);
ServerSocket ss = ssf.createServerSocket(serverPort);
serverPort = ss.getLocalPort();
- new TestServer(ss);
+ server = new TestServer(ss);
} catch (Exception e) {
System.out.println("Server side failed:" +
e.getMessage());
@@ -113,9 +130,27 @@
// trigger the client
try {
doClientSide();
- } catch (Exception e) {
- System.out.println("Client side failed: " + e.getMessage());
- throw e;
+ if (!expectSuccess) {
+ throw new RuntimeException(
+ "Expected exception/failure to connect, but succeeded.");
+ }
+ } catch (IOException e) {
+ if (expectSuccess) {
+ System.out.println("Client side failed: " + e.getMessage());
+ throw e;
+ }
+
+ if (! (e.getMessage().contains("Unable to tunnel through proxy") &&
+ e.getMessage().contains("407")) ) {
+ throw new RuntimeException(
+ "Expected exception about cannot tunnel, 407, etc, but got", e);
+ } else {
+ // Informative
+ System.out.println("Caught expected exception: " + e.getMessage());
+ }
+ } finally {
+ if (server != null)
+ server.close();
}
}
@@ -145,11 +180,11 @@
}
}
- static void doClientSide() throws Exception {
+ static void doClientSide() throws IOException {
/*
* setup up a proxy with authentication information
*/
- setupProxy();
+ ProxyTunnelServer ps = setupProxy();
/*
* we want to avoid URLspoofCheck failures in cases where the cert
@@ -157,18 +192,28 @@
*/
HttpsURLConnection.setDefaultHostnameVerifier(
new NameVerifier());
+
+ InetSocketAddress paddr = new InetSocketAddress("localhost", ps.getPort());
+ Proxy proxy = new Proxy(Proxy.Type.HTTP, paddr);
+
URL url = new URL("https://" + "localhost:" + serverPort
+ "/index.html");
BufferedReader in = null;
+ HttpsURLConnection uc = (HttpsURLConnection) url.openConnection(proxy);
try {
- in = new BufferedReader(new InputStreamReader(
- url.openStream()));
+ in = new BufferedReader(new InputStreamReader(uc.getInputStream()));
String inputLine;
System.out.print("Client recieved from the server: ");
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
- } catch (SSLException e) {
+ } catch (IOException e) {
+ // Assert that the error stream is not accessible from the failed
+ // tunnel setup.
+ if (uc.getErrorStream() != null) {
+ throw new RuntimeException("Unexpected error stream.");
+ }
+
if (in != null)
in.close();
throw e;
@@ -181,7 +226,7 @@
}
}
- static void setupProxy() throws IOException {
+ static ProxyTunnelServer setupProxy() throws IOException {
ProxyTunnelServer pserver = new ProxyTunnelServer();
/*
* register a system wide authenticator and setup the proxy for
@@ -194,9 +239,7 @@
pserver.setUserAuth("Test", "test123");
pserver.start();
- System.setProperty("https.proxyHost", "localhost");
- System.setProperty("https.proxyPort", String.valueOf(
- pserver.getPort()));
+ return pserver;
}
public static class TestAuthenticator extends Authenticator {
--- a/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyTunnelServer.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/sun/net/www/protocol/https/HttpsClient/ProxyTunnelServer.java Wed Oct 19 08:06:10 2016 -0700
@@ -65,6 +65,7 @@
ss = (ServerSocket) ServerSocketFactory.getDefault().
createServerSocket(0);
}
+ setDaemon(true);
}
public void needUserAuth(boolean auth) {
@@ -211,6 +212,7 @@
this.sockOut = sockOut;
input = sockIn.getInputStream();
output = sockOut.getOutputStream();
+ setDaemon(true);
}
public void run() {
--- a/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxyWithAuth.sh Wed Oct 19 08:06:10 2016 -0700
@@ -57,5 +57,6 @@
${TESTSRC}${FS}ProxyTunnelServer.java \
${TESTSRC}${FS}PostThruProxyWithAuth.java
${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} ${EXTRAOPTS} \
+ -Djdk.http.auth.tunneling.disabledSchemes= \
PostThruProxyWithAuth ${HOSTNAME} ${TESTSRC}
exit
--- a/jdk/test/sun/security/ec/TestEC.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/sun/security/ec/TestEC.java Wed Oct 19 08:06:10 2016 -0700
@@ -28,7 +28,7 @@
/**
* @test
- * @bug 6840752
+ * @bug 6840752 8168078
* @summary Provide out-of-the-box support for ECC algorithms
* @library ../pkcs11
* @library ../pkcs11/ec
@@ -37,6 +37,7 @@
* @modules jdk.crypto.pkcs11/sun.security.pkcs11.wrapper
* @compile -XDignore.symbol.file TestEC.java
* @run main/othervm -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
+ * @run main/othervm/java.security.policy=TestEC.policy -Djdk.tls.namedGroups="secp256r1,sect193r1" TestEC
*/
import java.security.NoSuchProviderException;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/sun/security/ec/TestEC.policy Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,3 @@
+grant codebase "file:${test.classes}/*" {
+ permission java.security.AllPermission;
+};
--- a/jdk/test/sun/security/pkcs/pkcs7/PKCS7VerifyTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/sun/security/pkcs/pkcs7/PKCS7VerifyTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -27,8 +27,8 @@
* @summary Read signed data in one or more PKCS7 objects from individual files,
* verify SignerInfos and certificate chain.
* @modules java.base/sun.security.pkcs
- * @run main PKCS7VerifyTest PKCS7TEST.DSA.base64
- * @run main PKCS7VerifyTest PKCS7TEST.DSA.base64 PKCS7TEST.SF
+ * @run main/othervm PKCS7VerifyTest PKCS7TEST.DSA.base64
+ * @run main/othervm PKCS7VerifyTest PKCS7TEST.DSA.base64 PKCS7TEST.SF
*/
import java.io.ByteArrayInputStream;
import java.io.File;
@@ -36,6 +36,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.HashMap;
@@ -55,6 +56,8 @@
throw new RuntimeException("usage: java JarVerify <file1> <file2>");
}
+ Security.setProperty("jdk.jar.disabledAlgorithms", "");
+
// The command " java PKCS7VerifyTest file1 [file2] "
// treats file1 as containing the DER encoding of a PKCS7 signed data
// object. If file2 is absent, the program verifies that some signature
--- a/jdk/test/sun/security/pkcs11/PKCS11Test.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java Wed Oct 19 08:06:10 2016 -0700
@@ -47,6 +47,7 @@
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
@@ -112,7 +113,7 @@
found = true;
break;
}
- } catch (Exception e) {
+ } catch (Exception | ServiceConfigurationError e) {
// ignore and move on to the next one
}
}
--- a/jdk/test/sun/security/tools/jarsigner/JarSigningNonAscii.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/sun/security/tools/jarsigner/JarSigningNonAscii.java Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -26,10 +26,12 @@
* @bug 4924188
* @summary sign a JAR file that has entry names with non-ASCII characters.
* @modules jdk.jartool/sun.security.tools.jarsigner
+ * @run main/othervm JarSigningNonAscii
*/
import sun.security.tools.*;
import java.io.*;
+import java.security.Security;
import java.util.*;
import java.util.jar.*;
import java.security.cert.Certificate;
@@ -40,6 +42,7 @@
private static String keystore;
public static void main(String[] args) throws Exception {
+ Security.setProperty("jdk.jar.disabledAlgorithms", "");
String srcDir = System.getProperty("test.src", ".");
String destDir = System.getProperty("test.classes", ".");
--- a/jdk/test/tools/jlink/IntegrationTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/tools/jlink/IntegrationTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -37,14 +37,14 @@
import java.util.Properties;
import java.util.Set;
import java.util.function.Function;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.JlinkConfiguration;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.builder.DefaultImageBuilder;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.internal.ExecutableImage;
+import jdk.tools.jlink.internal.Jlink.JlinkConfiguration;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PostProcessor;
import jdk.tools.jlink.internal.plugins.DefaultCompressPlugin;
import jdk.tools.jlink.internal.plugins.StripDebugPlugin;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/JLinkToolProviderTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.security.AccessControlException;
+import java.util.spi.ToolProvider;
+
+/*
+ * @test
+ * @build JLinkToolProviderTest
+ * @run main/othervm/java.security.policy=toolprovider.policy JLinkToolProviderTest
+ */
+public class JLinkToolProviderTest {
+ static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+ .orElseThrow(() ->
+ new RuntimeException("jlink tool not found")
+ );
+
+ private static void checkJlinkOptions(String... options) {
+ StringWriter writer = new StringWriter();
+ PrintWriter pw = new PrintWriter(writer);
+
+ try {
+ JLINK_TOOL.run(pw, pw, options);
+ throw new AssertionError("SecurityException should have been thrown!");
+ } catch (AccessControlException ace) {
+ if (! ace.getPermission().getClass().getName().contains("JlinkPermission")) {
+ throw new AssertionError("expected JlinkPermission check failure");
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ checkJlinkOptions("--help");
+ checkJlinkOptions("--list-plugins");
+ }
+}
--- a/jdk/test/tools/jlink/SecurityTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/tools/jlink/SecurityTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -25,12 +25,12 @@
* @test
* @summary Test JlinkPermission
* @author Jean-Francois Denise
- * @modules jdk.jlink/jdk.tools.jlink
+ * @modules jdk.jlink/jdk.tools.jlink.internal
* @run main/othervm SecurityTest
*/
import java.security.AccessControlException;
-import jdk.tools.jlink.Jlink;
+import jdk.tools.jlink.internal.Jlink;
public class SecurityTest {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/plugins/ExcludeJmodSectionPluginTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,340 @@
+/**
+ * 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
+ * @summary Test --no-man-pages and --no-header-files
+ * @library /lib/testlibrary
+ * @modules jdk.compiler
+ * jdk.jlink
+ * @build CompilerUtils
+ * @run testng ExcludeJmodSectionPluginTest
+ */
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.SimpleFileVisitor;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.spi.ToolProvider;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+public class ExcludeJmodSectionPluginTest {
+ static final ToolProvider JMOD_TOOL = ToolProvider.findFirst("jmod")
+ .orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
+
+ static final ToolProvider JLINK_TOOL = ToolProvider.findFirst("jlink")
+ .orElseThrow(() ->
+ new RuntimeException("jlink tool not found")
+ );
+
+ static final Path MODULE_PATH = Paths.get(System.getProperty("java.home"), "jmods");
+ static final Path SRC_DIR = Paths.get("src");
+ static final Path MODS_DIR = Paths.get("mods");
+ static final Path JMODS_DIR = Paths.get("jmods");
+ static final Path MAN_DIR = Paths.get("man");
+ static final Path INCLUDE_DIR = Paths.get("include");
+ static final Path IMAGES_DIR = Paths.get("images");
+
+ @BeforeTest
+ private void setup() throws Exception {
+ // build jmod files
+ JmodFileBuilder m1 = new JmodFileBuilder("m1");
+ m1.headerFile("m1a.h");
+ m1.headerFile("m1b.h");
+ m1.build();
+
+ JmodFileBuilder m2 = new JmodFileBuilder("m2");
+ m2.headerFile("m2.h");
+ m2.manPage("tool2.1");
+ m2.build();
+
+ JmodFileBuilder m3 = new JmodFileBuilder("m3");
+ m3.manPage("tool3.1");
+ m3.build();
+ }
+
+ private String imageDir(String dir) {
+ return IMAGES_DIR.resolve(dir).toString();
+ }
+
+
+ @DataProvider(name = "jlinkoptions")
+ public Object[][] jlinkoptions() {
+ // options and expected header files & man pages
+ return new Object[][] {
+ { new String [] {
+ "test1",
+ "--exclude-files=/java.base/include/**,/java.base/man/**",
+ },
+ List.of("include/m1a.h",
+ "include/m1b.h",
+ "include/m2.h",
+ "man/tool2.1",
+ "man/tool3.1")
+ },
+
+ { new String [] {
+ "test2",
+ "--no-man-pages",
+ "--no-header-files",
+ },
+ List.of()
+ },
+
+ { new String[] {
+ "test3",
+ "--no-header-files",
+ "--exclude-files=/java.base/man/**"
+ },
+ List.of("man/tool2.1",
+ "man/tool3.1") },
+
+ { new String [] {
+ "test4",
+ "--no-man-pages",
+ "--exclude-files=/java.base/include/**,/m2/include/**",
+ },
+ List.of("include/m1a.h",
+ "include/m1b.h")
+ },
+
+ { new String [] {
+ "test5",
+ "--no-header-files",
+ "--exclude-files=/java.base/man/**,/m2/man/**"
+ },
+ List.of("man/tool3.1")
+ },
+ };
+ }
+
+ @Test(dataProvider = "jlinkoptions")
+ public void test(String[] opts, List<String> expectedFiles) throws Exception {
+ if (Files.notExists(MODULE_PATH)) {
+ // exploded image
+ return;
+ }
+
+ String dir = opts[0];
+ List<String> options = new ArrayList<>();
+ for (int i = 1; i < opts.length; i++) {
+ options.add(opts[i]);
+ }
+
+ String mpath = MODULE_PATH.toString() + File.pathSeparator +
+ JMODS_DIR.toString();
+ Stream.of("--module-path", mpath,
+ "--add-modules", "m1,m2,m3",
+ "--output", imageDir(dir))
+ .forEach(options::add);
+
+ Path image = createImage(dir, options, expectedFiles);
+
+ // check if any unexpected header file or man page
+ Set<Path> extraFiles = Files.walk(image, Integer.MAX_VALUE)
+ .filter(p -> Files.isRegularFile(p))
+ .filter(p -> p.getParent().endsWith("include") ||
+ p.getParent().endsWith("man"))
+ .filter(p -> {
+ String fn = String.format("%s/%s",
+ p.getParent().getFileName().toString(),
+ p.getFileName().toString());
+ return !expectedFiles.contains(fn);
+ })
+ .collect(Collectors.toSet());
+
+ if (extraFiles.size() > 0) {
+ System.out.println("Unexpected files: " + extraFiles.toString());
+ assertTrue(extraFiles.isEmpty());
+ }
+ }
+
+ /**
+ * Test java.base's include header files
+ */
+ @Test
+ public void testJavaBase() {
+ if (Files.notExists(MODULE_PATH)) {
+ // exploded image
+ return;
+ }
+ List<String> options = List.of("--module-path",
+ MODULE_PATH.toString(),
+ "--add-modules", "java.base",
+ "--output", imageDir("base"));
+ createImage("base", options,
+ List.of("include/jni.h", "include/jvmti.h"));
+
+ }
+
+ private Path createImage(String outputDir, List<String> options,
+ List<String> expectedFiles) {
+ System.out.println("jlink " + options.toString());
+ int rc = JLINK_TOOL.run(System.out, System.out,
+ options.toArray(new String[0]));
+ assertTrue(rc == 0);
+
+ Path d = IMAGES_DIR.resolve(outputDir);
+ for (String fn : expectedFiles) {
+ Path path = d.resolve(fn);
+ if (Files.notExists(path)) {
+ throw new RuntimeException(path + " not found");
+ }
+ }
+ return d;
+ }
+
+ private void deleteDirectory(Path dir) throws IOException {
+ Files.walkFileTree(dir, new SimpleFileVisitor<Path>() {
+ @Override
+ public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
+ throws IOException
+ {
+ Files.delete(file);
+ return FileVisitResult.CONTINUE;
+ }
+
+ @Override
+ public FileVisitResult postVisitDirectory(Path dir, IOException exc)
+ throws IOException
+ {
+ Files.delete(dir);
+ return FileVisitResult.CONTINUE;
+ }
+ });
+ }
+
+ /**
+ * Builder to create JMOD file
+ */
+ class JmodFileBuilder {
+
+ final String name;
+ final Set<String> manPages = new HashSet<>();
+ final Set<String> headerFiles = new HashSet<>();
+
+ JmodFileBuilder(String name) throws IOException {
+ this.name = name;
+
+ Path msrc = SRC_DIR.resolve(name);
+ if (Files.exists(msrc)) {
+ deleteDirectory(msrc);
+ }
+ }
+
+ JmodFileBuilder manPage(String filename) {
+ manPages.add(filename);
+ return this;
+ }
+
+ JmodFileBuilder headerFile(String filename) {
+ headerFiles.add(filename);
+ return this;
+ }
+
+ Path build() throws IOException {
+ compileModule();
+ // create man pages
+ Path mdir = MAN_DIR.resolve(name);
+ for (String filename : manPages) {
+ Files.createDirectories(mdir);
+ Files.createFile(mdir.resolve(filename));
+ }
+ // create header files
+ mdir = INCLUDE_DIR.resolve(name);
+ for (String filename : headerFiles) {
+ Files.createDirectories(mdir);
+ Files.createFile(mdir.resolve(filename));
+ }
+ return createJmodFile();
+ }
+
+ void compileModule() throws IOException {
+ Path msrc = SRC_DIR.resolve(name);
+ Files.createDirectories(msrc);
+ Path minfo = msrc.resolve("module-info.java");
+ try (BufferedWriter bw = Files.newBufferedWriter(minfo);
+ PrintWriter writer = new PrintWriter(bw)) {
+ writer.format("module %s { }%n", name);
+ }
+
+ assertTrue(CompilerUtils.compile(msrc, MODS_DIR,
+ "--module-source-path",
+ SRC_DIR.toString()));
+ }
+
+ Path createJmodFile() throws IOException {
+ Path mclasses = MODS_DIR.resolve(name);
+ Files.createDirectories(JMODS_DIR);
+ Path outfile = JMODS_DIR.resolve(name + ".jmod");
+ List<String> args = new ArrayList<>();
+ args.add("create");
+ // add classes
+ args.add("--class-path");
+ args.add(mclasses.toString());
+ // man pages
+ if (manPages.size() > 0) {
+ args.add("--man-pages");
+ args.add(MAN_DIR.resolve(name).toString());
+ }
+ // header files
+ if (headerFiles.size() > 0) {
+ args.add("--header-files");
+ args.add(INCLUDE_DIR.resolve(name).toString());
+ }
+ args.add(outfile.toString());
+
+ if (Files.exists(outfile))
+ Files.delete(outfile);
+
+ System.out.println("jmod " +
+ args.stream().collect(Collectors.joining(" ")));
+
+ int rc = JMOD_TOOL.run(System.out, System.out,
+ args.toArray(new String[args.size()]));
+ if (rc != 0) {
+ throw new AssertionError("jmod failed: rc = " + rc);
+ }
+ return outfile;
+ }
+ }
+}
--- a/jdk/test/tools/jlink/plugins/LastSorterTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/tools/jlink/plugins/LastSorterTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -37,11 +37,11 @@
import java.util.Map;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.ImagePluginStack;
+import jdk.tools.jlink.internal.Jlink;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
-import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- a/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/tools/jlink/plugins/PluginsNegativeTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -36,11 +36,11 @@
import java.util.Map;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.Jlink;
+import jdk.tools.jlink.internal.Jlink.PluginsConfiguration;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
-import jdk.tools.jlink.Jlink;
-import jdk.tools.jlink.Jlink.PluginsConfiguration;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- a/jdk/test/tools/jlink/plugins/PrevisitorTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/jdk/test/tools/jlink/plugins/PrevisitorTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -40,13 +40,13 @@
import java.util.stream.Collectors;
import jdk.tools.jlink.internal.ImagePluginConfiguration;
+import jdk.tools.jlink.internal.Jlink;
import jdk.tools.jlink.internal.PluginRepository;
import jdk.tools.jlink.internal.ImagePluginStack;
import jdk.tools.jlink.internal.ResourcePoolManager;
import jdk.tools.jlink.internal.ResourcePoolManager.ResourcePoolImpl;
import jdk.tools.jlink.internal.ResourcePrevisitor;
import jdk.tools.jlink.internal.StringTable;
-import jdk.tools.jlink.Jlink;
import jdk.tools.jlink.plugin.Plugin;
import jdk.tools.jlink.plugin.ResourcePool;
import jdk.tools.jlink.plugin.ResourcePoolBuilder;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/tools/jlink/toolprovider.policy Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,2 @@
+grant {
+};
--- a/langtools/.hgtags Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/.hgtags Wed Oct 19 08:06:10 2016 -0700
@@ -382,3 +382,4 @@
dd56c243c199a540c9f1fbff4855f0934b32a9d0 jdk-9+137
90dd93e668a521642382561c47abe96ee2e065b7 jdk-9+138
17a82cb0e4b480e97021691d39917f15e3f7b653 jdk-9+139
+6842e63d6c3971172214b411f29965852ca175d1 jdk-9+140
--- a/langtools/make/build.properties Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/make/build.properties Wed Oct 19 08:06:10 2016 -0700
@@ -24,11 +24,12 @@
#
#javac configuration for "normal build" (these will be passed to the bootstrap compiler):
-javac.opts = -XDignore.symbol.file=true -Xlint:all,-deprecation,-options -Werror -g:source,lines,vars
+javac.opts = -XDignore.symbol.file=true -Xlint:all,-deprecation,-options,-exports -Werror -g:source,lines,vars
javac.source = 9
javac.target = 9
#version used to compile build tools
+javac.build.opts = -XDignore.symbol.file=true -Xlint:all,-deprecation,-options -Werror -g:source,lines,vars
javac.build.source = 8
javac.build.target = 8
--- a/langtools/make/build.xml Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/make/build.xml Wed Oct 19 08:06:10 2016 -0700
@@ -275,7 +275,7 @@
classpath="${ant.core.lib}"
bootclasspath="${langtools.jdk.home}/jre/lib/rt.jar"
includeantruntime="false">
- <compilerarg line="${javac.opts} -XDstringConcat=inline"/>
+ <compilerarg line="${javac.build.opts} -XDstringConcat=inline"/>
</javac>
<taskdef name="pparse"
classname="anttasks.PropertiesParserTask"
@@ -291,7 +291,7 @@
destdir="${build.dir}/toolclasses/"
classpath="${ant.core.lib}"
includeantruntime="false">
- <compilerarg line="${javac.opts} -XDstringConcat=inline"/>
+ <compilerarg line="${javac.build.opts} -XDstringConcat=inline"/>
</javac>
<taskdef name="pcompile"
classname="anttasks.CompilePropertiesTask"
--- a/langtools/make/gensrc/GensrcCommon.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/make/gensrc/GensrcCommon.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/langtools/make/intellij/misc.xml Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/make/intellij/misc.xml Wed Oct 19 08:06:10 2016 -0700
@@ -4,14 +4,17 @@
<entry_points version="2.0" />
</component>
<component name="JTRegService">
- <option name="JTRegDir" value="@IDEA_JTREG_HOME@" />
- <option name="JTRegOptions" value='@XPATCH@' />
- <option name="alternativeJrePath" value="@IDEA_TARGET_JDK@" />
- <option name="alternativeJrePathEnabled" value="true" />
- <option name="workDir" value="build" />
+ <path>@IDEA_JTREG_HOME@</path>
+ <workDir>build</workDir>
+ <jre alt="true" value="@IDEA_TARGET_JDK@" />
+ <options>@XPATCH@</options>
+ <ant>
+ <target file="file://$PROJECT_DIR$/.idea/build.xml" name="build-all-classes" />
+ </ant>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" assert-keyword="true" jdk-15="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/.idea/out" />
</component>
</project>
+
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java Wed Oct 19 08:06:10 2016 -0700
@@ -949,6 +949,7 @@
@Override @DefinedBy(Api.LANGUAGE_MODEL)
public java.util.List<Directive> getDirectives() {
+ complete();
completeUsesProvides();
return Collections.unmodifiableList(directives);
}
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Wed Oct 19 08:06:10 2016 -0700
@@ -30,6 +30,7 @@
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.function.BiPredicate;
@@ -468,89 +469,14 @@
* and return-type substitutable with each method in the original list.
*/
private FunctionDescriptor mergeDescriptors(TypeSymbol origin, List<Symbol> methodSyms) {
- //pick argument types - simply take the signature that is a
- //subsignature of all other signatures in the list (as per JLS 8.4.2)
- List<Symbol> mostSpecific = List.nil();
- outer: for (Symbol msym1 : methodSyms) {
- Type mt1 = memberType(origin.type, msym1);
- for (Symbol msym2 : methodSyms) {
- Type mt2 = memberType(origin.type, msym2);
- if (!isSubSignature(mt1, mt2)) {
- continue outer;
- }
- }
- mostSpecific = mostSpecific.prepend(msym1);
- }
- if (mostSpecific.isEmpty()) {
- return null;
- }
-
-
- //pick return types - this is done in two phases: (i) first, the most
- //specific return type is chosen using strict subtyping; if this fails,
- //a second attempt is made using return type substitutability (see JLS 8.4.5)
- boolean phase2 = false;
- Symbol bestSoFar = null;
- while (bestSoFar == null) {
- outer: for (Symbol msym1 : mostSpecific) {
- Type mt1 = memberType(origin.type, msym1);
- for (Symbol msym2 : methodSyms) {
- Type mt2 = memberType(origin.type, msym2);
- if (phase2 ?
- !returnTypeSubstitutable(mt1, mt2) :
- !isSubtypeInternal(mt1.getReturnType(), mt2.getReturnType())) {
- continue outer;
+ return mergeAbstracts(methodSyms, origin.type, false)
+ .map(bestSoFar -> new FunctionDescriptor(bestSoFar.baseSymbol()) {
+ @Override
+ public Type getType(Type origin) {
+ Type mt = memberType(origin, getSymbol());
+ return createMethodTypeWithThrown(mt, bestSoFar.type.getThrownTypes());
}
- }
- bestSoFar = msym1;
- }
- if (phase2) {
- break;
- } else {
- phase2 = true;
- }
- }
- if (bestSoFar == null) return null;
-
- //merge thrown types - form the intersection of all the thrown types in
- //all the signatures in the list
- List<Type> thrown = null;
- Type mt1 = memberType(origin.type, bestSoFar);
- boolean toErase = !mt1.hasTag(FORALL);
- for (Symbol msym2 : methodSyms) {
- Type mt2 = memberType(origin.type, msym2);
- List<Type> thrown_mt2 = mt2.getThrownTypes();
- if (toErase) {
- thrown_mt2 = erasure(thrown_mt2);
- } else {
- /* If bestSoFar is generic then all the methods are generic.
- * The opposite is not true: a non generic method can override
- * a generic method (raw override) so it's safe to cast mt1 and
- * mt2 to ForAll.
- */
- ForAll fa1 = (ForAll)mt1;
- ForAll fa2 = (ForAll)mt2;
- thrown_mt2 = subst(thrown_mt2, fa2.tvars, fa1.tvars);
- }
- thrown = (thrown == null) ?
- thrown_mt2 :
- chk.intersect(thrown_mt2, thrown);
- }
-
- final List<Type> thrown1 = thrown;
- return new FunctionDescriptor(bestSoFar) {
- @Override
- public Type getType(Type origin) {
- Type mt = memberType(origin, getSymbol());
- return createMethodTypeWithThrown(mt, thrown1);
- }
- };
- }
-
- boolean isSubtypeInternal(Type s, Type t) {
- return (s.isPrimitive() && t.isPrimitive()) ?
- isSameType(t, s) :
- isSubtype(s, t);
+ }).orElse(null);
}
FunctionDescriptorLookupError failure(String msg, Object... args) {
@@ -2604,6 +2530,106 @@
return false;
}
+ /**
+ * This enum defines the strategy for implementing most specific return type check
+ * during the most specific and functional interface checks.
+ */
+ public enum MostSpecificReturnCheck {
+ /**
+ * Return r1 is more specific than r2 if {@code r1 <: r2}. Extra care required for (i) handling
+ * method type variables (if either method is generic) and (ii) subtyping should be replaced
+ * by type-equivalence for primitives. This is essentially an inlined version of
+ * {@link Types#resultSubtype(Type, Type, Warner)}, where the assignability check has been
+ * replaced with a strict subtyping check.
+ */
+ BASIC() {
+ @Override
+ public boolean test(Type mt1, Type mt2, Types types) {
+ List<Type> tvars = mt1.getTypeArguments();
+ List<Type> svars = mt2.getTypeArguments();
+ Type t = mt1.getReturnType();
+ Type s = types.subst(mt2.getReturnType(), svars, tvars);
+ return types.isSameType(t, s) ||
+ !t.isPrimitive() &&
+ !s.isPrimitive() &&
+ types.isSubtype(t, s);
+ }
+ },
+ /**
+ * Return r1 is more specific than r2 if r1 is return-type-substitutable for r2.
+ */
+ RTS() {
+ @Override
+ public boolean test(Type mt1, Type mt2, Types types) {
+ return types.returnTypeSubstitutable(mt1, mt2);
+ }
+ };
+
+ public abstract boolean test(Type mt1, Type mt2, Types types);
+ }
+
+ /**
+ * Merge multiple abstract methods. The preferred method is a method that is a subsignature
+ * of all the other signatures and whose return type is more specific {@see MostSpecificReturnCheck}.
+ * The resulting preferred method has a thrown clause that is the intersection of the merged
+ * methods' clauses.
+ */
+ public Optional<Symbol> mergeAbstracts(List<Symbol> ambiguousInOrder, Type site, boolean sigCheck) {
+ //first check for preconditions
+ boolean shouldErase = false;
+ List<Type> erasedParams = ambiguousInOrder.head.erasure(this).getParameterTypes();
+ for (Symbol s : ambiguousInOrder) {
+ if ((s.flags() & ABSTRACT) == 0 ||
+ (sigCheck && !isSameTypes(erasedParams, s.erasure(this).getParameterTypes()))) {
+ return Optional.empty();
+ } else if (s.type.hasTag(FORALL)) {
+ shouldErase = true;
+ }
+ }
+ //then merge abstracts
+ for (MostSpecificReturnCheck mostSpecificReturnCheck : MostSpecificReturnCheck.values()) {
+ outer: for (Symbol s : ambiguousInOrder) {
+ Type mt = memberType(site, s);
+ List<Type> allThrown = mt.getThrownTypes();
+ for (Symbol s2 : ambiguousInOrder) {
+ if (s != s2) {
+ Type mt2 = memberType(site, s2);
+ if (!isSubSignature(mt, mt2) ||
+ !mostSpecificReturnCheck.test(mt, mt2, this)) {
+ //ambiguity cannot be resolved
+ continue outer;
+ } else {
+ List<Type> thrownTypes2 = mt2.getThrownTypes();
+ if (!mt.hasTag(FORALL) && shouldErase) {
+ thrownTypes2 = erasure(thrownTypes2);
+ } else if (mt.hasTag(FORALL)) {
+ //subsignature implies that if most specific is generic, then all other
+ //methods are too
+ Assert.check(mt2.hasTag(FORALL));
+ // if both are generic methods, adjust thrown types ahead of intersection computation
+ thrownTypes2 = subst(thrownTypes2, mt2.getTypeArguments(), mt.getTypeArguments());
+ }
+ allThrown = chk.intersect(allThrown, thrownTypes2);
+ }
+ }
+ }
+ return (allThrown == mt.getThrownTypes()) ?
+ Optional.of(s) :
+ Optional.of(new MethodSymbol(
+ s.flags(),
+ s.name,
+ createMethodTypeWithThrown(s.type, allThrown),
+ s.owner) {
+ @Override
+ public Symbol baseSymbol() {
+ return s;
+ }
+ });
+ }
+ }
+ return Optional.empty();
+ }
+
// <editor-fold defaultstate="collapsed" desc="Determining method implementation in given site">
class ImplementationCache {
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java Wed Oct 19 08:06:10 2016 -0700
@@ -1691,28 +1691,6 @@
}
}
//where
- Type mostSpecificReturnType(Type mt1, Type mt2) {
- Type rt1 = mt1.getReturnType();
- Type rt2 = mt2.getReturnType();
-
- if (mt1.hasTag(FORALL) && mt2.hasTag(FORALL)) {
- //if both are generic methods, adjust return type ahead of subtyping check
- rt1 = types.subst(rt1, mt1.getTypeArguments(), mt2.getTypeArguments());
- }
- //first use subtyping, then return type substitutability
- if (types.isSubtype(rt1, rt2)) {
- return mt1;
- } else if (types.isSubtype(rt2, rt1)) {
- return mt2;
- } else if (types.returnTypeSubstitutable(mt1, mt2)) {
- return mt1;
- } else if (types.returnTypeSubstitutable(mt2, mt1)) {
- return mt2;
- } else {
- return null;
- }
- }
- //where
Symbol ambiguityError(Symbol m1, Symbol m2) {
if (((m1.flags() | m2.flags()) & CLASH) != 0) {
return (m1.flags() & CLASH) == 0 ? m1 : m2;
@@ -4112,43 +4090,7 @@
*/
Symbol mergeAbstracts(Type site) {
List<Symbol> ambiguousInOrder = ambiguousSyms.reverse();
- for (Symbol s : ambiguousInOrder) {
- Type mt = types.memberType(site, s);
- boolean found = true;
- List<Type> allThrown = mt.getThrownTypes();
- for (Symbol s2 : ambiguousInOrder) {
- Type mt2 = types.memberType(site, s2);
- if ((s2.flags() & ABSTRACT) == 0 ||
- !types.overrideEquivalent(mt, mt2) ||
- !types.isSameTypes(s.erasure(types).getParameterTypes(),
- s2.erasure(types).getParameterTypes())) {
- //ambiguity cannot be resolved
- return this;
- }
- Type mst = mostSpecificReturnType(mt, mt2);
- if (mst == null || mst != mt) {
- found = false;
- break;
- }
- List<Type> thrownTypes2 = mt2.getThrownTypes();
- if (mt.hasTag(FORALL) && mt2.hasTag(FORALL)) {
- // if both are generic methods, adjust thrown types ahead of intersection computation
- thrownTypes2 = types.subst(thrownTypes2, mt2.getTypeArguments(), mt.getTypeArguments());
- }
- allThrown = chk.intersect(allThrown, thrownTypes2);
- }
- if (found) {
- //all ambiguous methods were abstract and one method had
- //most specific return type then others
- return (allThrown == mt.getThrownTypes()) ?
- s : new MethodSymbol(
- s.flags(),
- s.name,
- types.createMethodTypeWithThrown(s.type, allThrown),
- s.owner);
- }
- }
- return this;
+ return types.mergeAbstracts(ambiguousInOrder, site, true).orElse(this);
}
@Override
--- a/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/search.js Wed Oct 19 08:06:10 2016 -0700
@@ -30,6 +30,9 @@
var catTypes = "Types";
var catMembers = "Members";
var catSearchTags = "SearchTags";
+var highlight = "<span class=\"resultHighlight\">$&</span>";
+var camelCaseRegexp = "";
+var secondaryMatcher = "";
function getName(name) {
var anchor = "";
var ch = '';
@@ -65,27 +68,35 @@
}
return anchor;
}
+function getHighlightedText(item) {
+ var ccMatcher = new RegExp(camelCaseRegexp);
+ var label = item.replace(ccMatcher, highlight);
+ if (label === item) {
+ label = item.replace(secondaryMatcher, highlight);
+ }
+ return label;
+}
var watermark = 'Search';
$(function() {
$("#search").prop("disabled", false);
$("#reset").prop("disabled", false);
$("#search").val(watermark).addClass('watermark');
- $("#search").blur(function(){
+ $("#search").blur(function() {
if ($(this).val().length == 0) {
$(this).val(watermark).addClass('watermark');
}
});
- $("#search").keydown(function(){
- if ($(this).val() == watermark) {
+ $("#search").keydown(function() {
+ if ($(this).val() == watermark) {
$(this).val('').removeClass('watermark');
}
});
- $("#reset").click(function(){
- $("#search").val('');
- $("#search").focus();
+ $("#reset").click(function() {
+ $("#search").val('');
+ $("#search").focus();
});
$("#search").focus();
- $("#search")[0].setSelectionRange(0,0);
+ $("#search")[0].setSelectionRange(0, 0);
});
$.widget("custom.catcomplete", $.ui.autocomplete, {
_create: function() {
@@ -112,22 +123,19 @@
});
},
_renderItem: function(ul, item) {
- var result = this.element.val();
- var regexp = new RegExp($.ui.autocomplete.escapeRegex(result), "i");
- highlight = "<span class=\"resultHighlight\">$&</span>";
var label = "";
if (item.category === catModules) {
- label = item.l.replace(regexp, highlight);
+ label = getHighlightedText(item.l);
} else if (item.category === catPackages) {
label = (item.m)
- ? (item.m + "/" + item.l).replace(regexp, highlight)
- : item.l.replace(regexp, highlight);
+ ? getHighlightedText(item.m + "/" + item.l)
+ : getHighlightedText(item.l);
} else if (item.category === catTypes) {
- label += (item.p + "." + item.l).replace(regexp, highlight);
+ label = getHighlightedText(item.p + "." + item.l);
} else if (item.category === catMembers) {
- label += item.p + "." + (item.c + "." + item.l).replace(regexp, highlight);
+ label = getHighlightedText(item.p + "." + (item.c + "." + item.l));
} else if (item.category === catSearchTags) {
- label = item.l.replace(regexp, highlight);
+ label = getHighlightedText(item.l);
} else {
label = item.l;
}
@@ -163,7 +171,9 @@
var tgresult = new Array();
var displayCount = 0;
var exactMatcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term) + "$", "i");
- var secondaryMatcher = 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");
if (moduleSearchIndex) {
var mdleCount = 0;
$.each(moduleSearchIndex, function(index, item) {
@@ -171,6 +181,8 @@
if (exactMatcher.test(item.l)) {
result.unshift(item);
mdleCount++;
+ } else if (camelCaseMatcher.test(item.l)) {
+ result.unshift(item);
} else if (secondaryMatcher.test(item.l)) {
result.push(item);
}
@@ -188,6 +200,8 @@
if (exactMatcher.test(item.l)) {
presult.unshift(item);
pCount++;
+ } else if (camelCaseMatcher.test(pkg)) {
+ presult.unshift(item);
} else if (secondaryMatcher.test(pkg)) {
presult.push(item);
}
@@ -202,6 +216,8 @@
if (exactMatcher.test(item.l)) {
tresult.unshift(item);
tCount++;
+ } else if (camelCaseMatcher.test(item.l)) {
+ tresult.unshift(item);
} else if (secondaryMatcher.test(item.p + "." + item.l)) {
tresult.push(item);
}
@@ -216,6 +232,8 @@
if (exactMatcher.test(item.l)) {
mresult.unshift(item);
mCount++;
+ } else if (camelCaseMatcher.test(item.l)) {
+ mresult.unshift(item);
} else if (secondaryMatcher.test(item.c + "." + item.l)) {
mresult.push(item);
}
@@ -294,4 +312,4 @@
}
}
});
-});
+});
\ No newline at end of file
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeprscan/Main.java Wed Oct 19 08:06:10 2016 -0700
@@ -384,14 +384,14 @@
.collect(toList()));
} else {
// TODO: kind of a hack...
- // Create a throwaway compilation task with options "-release N"
+ // Create a throwaway compilation task with options "--release N"
// which has the side effect of setting the file manager's
// PLATFORM_CLASS_PATH to the right value.
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fm =
compiler.getStandardFileManager(this, null, StandardCharsets.UTF_8);
JavaCompiler.CompilationTask task =
- compiler.getTask(null, fm, this, List.of("-release", release), null, null);
+ compiler.getTask(null, fm, this, List.of("--release", release), null, null);
List<Path> paths = new ArrayList<>();
for (Path p : fm.getLocationAsPaths(StandardLocation.PLATFORM_CLASS_PATH)) {
try (Stream<Path> str = Files.walk(p)) {
--- a/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jdeps/share/classes/com/sun/tools/jdeps/JdepsTask.java Wed Oct 19 08:06:10 2016 -0700
@@ -680,20 +680,21 @@
private boolean genModuleInfo(JdepsConfiguration config) throws IOException {
// check if any JAR file contains unnamed package
for (String arg : inputArgs) {
- Optional<String> classInUnnamedPackage =
- ClassFileReader.newInstance(Paths.get(arg))
- .entries().stream()
- .filter(n -> n.endsWith(".class"))
- .filter(cn -> toPackageName(cn).isEmpty())
- .findFirst();
+ try (ClassFileReader reader = ClassFileReader.newInstance(Paths.get(arg))) {
+ Optional<String> classInUnnamedPackage =
+ reader.entries().stream()
+ .filter(n -> n.endsWith(".class"))
+ .filter(cn -> toPackageName(cn).isEmpty())
+ .findFirst();
- if (classInUnnamedPackage.isPresent()) {
- if (classInUnnamedPackage.get().equals("module-info.class")) {
- reportError("err.genmoduleinfo.not.jarfile", arg);
- } else {
- reportError("err.genmoduleinfo.unnamed.package", arg);
+ if (classInUnnamedPackage.isPresent()) {
+ if (classInUnnamedPackage.get().equals("module-info.class")) {
+ reportError("err.genmoduleinfo.not.jarfile", arg);
+ } else {
+ reportError("err.genmoduleinfo.unnamed.package", arg);
+ }
+ return false;
}
- return false;
}
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Oct 19 08:06:10 2016 -0700
@@ -73,7 +73,6 @@
import jdk.jshell.JShell;
import jdk.jshell.JShell.Subscription;
import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.Snippet;
import jdk.jshell.Snippet.Status;
import jdk.jshell.SnippetEvent;
@@ -1137,10 +1136,9 @@
return state.snippets();
}
- Stream<PersistentSnippet> dropableSnippets() {
+ Stream<Snippet> dropableSnippets() {
return state.snippets()
- .filter(sn -> state.status(sn).isActive() && sn instanceof PersistentSnippet)
- .map(sn -> (PersistentSnippet) sn);
+ .filter(sn -> state.status(sn).isActive());
}
Stream<VarSnippet> allVarSnippets() {
@@ -1761,13 +1759,13 @@
errormsg("jshell.err.drop.arg");
return false;
}
- Stream<PersistentSnippet> stream = argsToSnippets(this::dropableSnippets, args);
+ Stream<Snippet> stream = argsToSnippets(this::dropableSnippets, args);
if (stream == null) {
// Snippet not found. Error already printed
fluffmsg("jshell.msg.see.classes.etc");
return false;
}
- List<PersistentSnippet> snippets = stream.collect(toList());
+ List<Snippet> snippets = stream.collect(toList());
if (snippets.size() > args.size()) {
// One of the args references more thean one snippet
errormsg("jshell.err.drop.ambiguous");
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/StopDetectingInputStream.java Wed Oct 19 08:06:10 2016 -0700
@@ -77,9 +77,7 @@
} catch (IOException ex) {
errorHandler.accept(ex);
} finally {
- synchronized (StopDetectingInputStream.this) {
- state = StopDetectingInputStream.State.CLOSED;
- }
+ shutdown();
}
}
};
@@ -140,8 +138,10 @@
}
public synchronized void setState(State state) {
- this.state = state;
- notifyAll();
+ if (this.state != State.CLOSED) {
+ this.state = state;
+ notifyAll();
+ }
}
private synchronized State waitInputNeeded() {
--- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/resources/l10n.properties Wed Oct 19 08:06:10 2016 -0700
@@ -743,7 +743,7 @@
/set format verbose result '{name} ==> {value}{post}' added,modified,replaced-ok-primary \n\
\n\
/set format verbose display '{result}{pre}created scratch variable {name} : {type}{post}' expression-added,modified,replaced-primary \n\
-/set format verbose display '{result}{pre}value of {name} : {type}{post}' varvalue-primary \n\
+/set format verbose display '{result}{pre}value of {name} : {type}{post}' varvalue-added,modified,replaced-primary \n\
/set format verbose display '{result}{pre}assigned to {name} : {type}{post}' assignment-primary \n\
/set format verbose display '{result}{pre}{action} variable {name} : {type}{resolve}{post}' varinit,vardecl \n\
/set format verbose display '{pre}{action} variable {name}{resolve}{post}' vardecl,varinit-notdefined \n\
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Eval.java Wed Oct 19 08:06:10 2016 -0700
@@ -521,10 +521,13 @@
List<SnippetEvent> drop(Snippet si) {
Unit c = new Unit(state, si);
-
- Set<Unit> ins = c.dependents().collect(toSet());
- Set<Unit> outs = compileAndLoad(ins);
-
+ Set<Unit> outs;
+ if (si instanceof PersistentSnippet) {
+ Set<Unit> ins = c.dependents().collect(toSet());
+ outs = compileAndLoad(ins);
+ } else {
+ outs = Collections.emptySet();
+ }
return events(c, outs, null, null);
}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/JShell.java Wed Oct 19 08:06:10 2016 -0700
@@ -58,7 +58,7 @@
* API. A {@code JShell} instance holds the evolving compilation and
* execution state. The state is changed with the instance methods
* {@link jdk.jshell.JShell#eval(java.lang.String) eval(String)},
- * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet) drop(PersistentSnippet)} and
+ * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet) drop(Snippet)} and
* {@link jdk.jshell.JShell#addToClasspath(java.lang.String) addToClasspath(String)}.
* The majority of methods query the state.
* A {@code JShell} instance also allows registering for events with
@@ -428,7 +428,12 @@
}
/**
- * Remove a declaration from the state.
+ * Remove a declaration from the state. That is, if the snippet is an
+ * {@linkplain jdk.jshell.Snippet.Status#isActive() active}
+ * {@linkplain jdk.jshell.PersistentSnippet persistent} snippet, remove the
+ * snippet and update the JShell evaluation state accordingly.
+ * For all active snippets, change the {@linkplain #status status} to
+ * {@link jdk.jshell.Snippet.Status#DROPPED DROPPED}.
* @param snippet The snippet to remove
* @return The list of events from updating declarations dependent on the
* dropped snippet.
@@ -436,7 +441,7 @@
* @throws IllegalArgumentException if the snippet is not associated with
* this {@code JShell} instance.
*/
- public List<SnippetEvent> drop(PersistentSnippet snippet) throws IllegalStateException {
+ public List<SnippetEvent> drop(Snippet snippet) throws IllegalStateException {
checkIfAlive();
checkValidSnippet(snippet);
List<SnippetEvent> events = eval.drop(snippet);
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Key.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Key.java Wed Oct 19 08:06:10 2016 -0700
@@ -74,7 +74,7 @@
/**
* Grouping for snippets which persist and influence future code.
* They are keyed off at least the name. They may be Modified/Replaced
- * with new input and can be dropped (JShell#drop).
+ * with new input.
*/
static abstract class PersistentKey extends Key {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/PersistentSnippet.java Wed Oct 19 08:06:10 2016 -0700
@@ -28,8 +28,8 @@
/**
* Grouping for Snippets which persist and influence future code.
* A persistent snippet can be
- * {@linkplain jdk.jshell.Snippet.Status#OVERWRITTEN overwritten)}
- * with new input and can be dropped {@link JShell#drop}.
+ * {@linkplain jdk.jshell.Snippet.Status#OVERWRITTEN overwritten}
+ * with new input.
* <p>
* <code>PersistentSnippet</code> is immutable: an access to
* any of its methods will always return the same result.
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/Snippet.java Wed Oct 19 08:06:10 2016 -0700
@@ -443,9 +443,7 @@
/**
* The snippet is inactive because of an explicit call to
- * the {@link JShell#drop(PersistentSnippet)}.
- * Only a {@link jdk.jshell.PersistentSnippet} can have this
- * {@code Status}.
+ * the {@link JShell#drop(Snippet)}.
* <p>
* The snippet is not visible to other snippets
* ({@link Status#isDefined() isDefined() == false})
@@ -525,10 +523,11 @@
/**
* Indicates whether the Snippet is active, that is,
- * will the snippet be re-evaluated when a new
+ * will a {@linkplain jdk.jshell.PersistentSnippet persistent}
+ * snippet be re-evaluated when a new
* {@link JShell#eval(java.lang.String) JShell.eval(String)} or
- * {@link JShell#drop(jdk.jshell.PersistentSnippet)
- * JShell.drop(PersistentSnippet)} that could change
+ * {@link JShell#drop(jdk.jshell.Snippet)
+ * JShell.drop(Snippet)} that could change
* its status is invoked. This is more broad than
* {@link Status#isDefined()} since a Snippet which is
* {@link Status#RECOVERABLE_NOT_DEFINED}
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SnippetEvent.java Wed Oct 19 08:06:10 2016 -0700
@@ -30,7 +30,7 @@
/**
* A description of a change to a Snippet. These are generated by direct changes
* to state with {@link JShell#eval(java.lang.String) JShell.eval(String)} or
- * {@link JShell#drop(jdk.jshell.PersistentSnippet) JShell.drop(PersistentSnippet)},
+ * {@link JShell#drop(jdk.jshell.Snippet) JShell.drop(Snippet)},
* or indirectly by these same methods as
* dependencies change or Snippets are overwritten. For direct changes, the
* {@link SnippetEvent#causeSnippet()} is {@code null}.
@@ -108,7 +108,7 @@
* creation of a new Snippet via
* {@link jdk.jshell.JShell#eval(java.lang.String) eval} or it is the
* explicit drop of a Snippet with
- * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet) drop}.
+ * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet) drop}.
*
* @return the Snippet which caused this change or {@code null} if
* directly caused by an API action.
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/SourceCodeAnalysisImpl.java Wed Oct 19 08:06:10 2016 -0700
@@ -116,6 +116,7 @@
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.QualifiedNameable;
+import javax.lang.model.element.TypeParameterElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.ArrayType;
import javax.lang.model.type.ExecutableType;
@@ -132,6 +133,7 @@
import static jdk.jshell.Util.REPL_DOESNOTMATTER_CLASS_NAME;
import static java.util.stream.Collectors.joining;
import static jdk.jshell.SourceCodeAnalysis.Completeness.DEFINITELY_INCOMPLETE;
+import static jdk.jshell.TreeDissector.printType;
/**
* The concrete implementation of SourceCodeAnalysis.
@@ -1185,7 +1187,7 @@
proc.debug(ex, "SourceCodeAnalysisImpl.element2String(..., " + el + ")");
}
- return Util.expunge(elementHeader(el));
+ return Util.expunge(elementHeader(sourceCache.originalTask, el, !hasSyntheticParameterNames(el)));
}
private boolean hasSyntheticParameterNames(Element el) {
@@ -1248,7 +1250,7 @@
topLevelName2Signature2Method.put(binaryName, cache = createMethodCache(binaryName));
}
- String handle = elementHeader(method, false);
+ String handle = elementHeader(originalTask, method, false);
return cache.getOrDefault(handle, method);
}
@@ -1276,7 +1278,7 @@
Element currentMethod = trees.getElement(getCurrentPath());
if (currentMethod != null) {
- signature2Method.put(elementHeader(currentMethod, false), currentMethod);
+ signature2Method.put(elementHeader(originalTask, currentMethod, false), currentMethod);
}
return null;
@@ -1331,39 +1333,79 @@
return availableSources = result;
}
- private String elementHeader(Element el) {
- return elementHeader(el, true);
+ private String elementHeader(AnalyzeTask at, Element el) {
+ return elementHeader(at, el, true);
}
- private String elementHeader(Element el, boolean includeParameterNames) {
+ private String elementHeader(AnalyzeTask at, Element el, boolean includeParameterNames) {
switch (el.getKind()) {
- case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE:
- return ((TypeElement) el).getQualifiedName().toString();
+ case ANNOTATION_TYPE: case CLASS: case ENUM: case INTERFACE: {
+ TypeElement type = (TypeElement)el;
+ String fullname = type.getQualifiedName().toString();
+ Element pkg = at.getElements().getPackageOf(el);
+ String name = pkg == null ? fullname :
+ proc.maps.fullClassNameAndPackageToClass(fullname, ((PackageElement)pkg).getQualifiedName().toString());
+
+ return name + typeParametersOpt(at, type.getTypeParameters());
+ }
+ case TYPE_PARAMETER: {
+ TypeParameterElement tp = (TypeParameterElement)el;
+ String name = tp.getSimpleName().toString();
+
+ List<? extends TypeMirror> bounds = tp.getBounds();
+ boolean boundIsObject = bounds.isEmpty() ||
+ bounds.size() == 1 && at.getTypes().isSameType(bounds.get(0), Symtab.instance(at.getContext()).objectType);
+
+ return boundIsObject
+ ? name
+ : name + " extends " + bounds.stream()
+ .map(bound -> printType(at, proc, bound))
+ .collect(joining(" & "));
+ }
case FIELD:
- return elementHeader(el.getEnclosingElement()) + "." + el.getSimpleName() + ":" + el.asType();
+ return elementHeader(at, el.getEnclosingElement()) + "." + el.getSimpleName() + ":" + el.asType();
case ENUM_CONSTANT:
- return elementHeader(el.getEnclosingElement()) + "." + el.getSimpleName();
+ return elementHeader(at, el.getEnclosingElement()) + "." + el.getSimpleName();
case EXCEPTION_PARAMETER: case LOCAL_VARIABLE: case PARAMETER: case RESOURCE_VARIABLE:
return el.getSimpleName() + ":" + el.asType();
- case CONSTRUCTOR: case METHOD:
+ case CONSTRUCTOR: case METHOD: {
StringBuilder header = new StringBuilder();
- header.append(elementHeader(el.getEnclosingElement()));
- if (el.getKind() == ElementKind.METHOD) {
- header.append(".");
- header.append(el.getSimpleName());
+
+ boolean isMethod = el.getKind() == ElementKind.METHOD;
+ ExecutableElement method = (ExecutableElement) el;
+
+ if (isMethod) {
+ // return type
+ header.append(printType(at, proc, method.getReturnType())).append(" ");
+ } else {
+ // type parameters for the constructor
+ String typeParameters = typeParametersOpt(at, method.getTypeParameters());
+ if (!typeParameters.isEmpty()) {
+ header.append(typeParameters).append(" ");
+ }
}
+
+ // receiver type
+ String clazz = elementHeader(at, el.getEnclosingElement());
+ header.append(clazz);
+
+ if (isMethod) {
+ //method name with type parameters
+ (clazz.isEmpty() ? header : header.append("."))
+ .append(typeParametersOpt(at, method.getTypeParameters()))
+ .append(el.getSimpleName());
+ }
+
+ // arguments
header.append("(");
String sep = "";
- ExecutableElement method = (ExecutableElement) el;
for (Iterator<? extends VariableElement> i = method.getParameters().iterator(); i.hasNext();) {
VariableElement p = i.next();
header.append(sep);
if (!i.hasNext() && method.isVarArgs()) {
- header.append(unwrapArrayType(p.asType()));
- header.append("...");
-
+ header.append(printType(at, proc, unwrapArrayType(p.asType()))).append("...");
} else {
- header.append(p.asType());
+ header.append(printType(at, proc, p.asType()));
}
if (includeParameterNames) {
header.append(" ");
@@ -1372,8 +1414,18 @@
sep = ", ";
}
header.append(")");
+
+ // throws
+ List<? extends TypeMirror> thrownTypes = method.getThrownTypes();
+ if (!thrownTypes.isEmpty()) {
+ header.append(" throws ")
+ .append(thrownTypes.stream()
+ .map(type -> printType(at, proc, type))
+ .collect(joining(", ")));
+ }
return header.toString();
- default:
+ }
+ default:
return el.toString();
}
}
@@ -1383,6 +1435,12 @@
}
return arrayType;
}
+ private String typeParametersOpt(AnalyzeTask at, List<? extends TypeParameterElement> typeParameters) {
+ return typeParameters.isEmpty() ? ""
+ : typeParameters.stream()
+ .map(tp -> elementHeader(at, tp))
+ .collect(joining(", ", "<", ">"));
+ }
@Override
public String analyzeType(String code, int cursor) {
--- a/langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/src/jdk.jshell/share/classes/jdk/jshell/package-info.java Wed Oct 19 08:06:10 2016 -0700
@@ -46,7 +46,7 @@
* {@link jdk.jshell.SnippetEvent}. There are three major kinds of
* changes to the status of a snippet: it can created with <code>eval</code>,
* it can be dropped from the active source state with
- * {@link jdk.jshell.JShell#drop(jdk.jshell.PersistentSnippet)}, and it can have
+ * {@link jdk.jshell.JShell#drop(jdk.jshell.Snippet)}, and it can have
* its status updated as a result of a status change in another snippet.
* For
* example: given <code>js</code>, an instance of <code>JShell</code>, executing
--- a/langtools/test/Makefile Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/Makefile Wed Oct 19 08:06:10 2016 -0700
@@ -321,6 +321,7 @@
$(JTREG_EXCLUSIONS) \
$(JTREG_OPTIONS) \
$(JTREG_TESTDIRS) \
+ 2>&1 | tee $(JTREG_OUTPUT_DIR)/output.txt \
|| ( $(call EXIT_IF_FATAL,$(FATAL_JTREG_EXIT)) ; \
echo $$status > $(JTREG_OUTPUT_DIR)/status.txt \
)
--- a/langtools/test/jdk/javadoc/doclet/testSearch/TestSearch.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/jdk/javadoc/doclet/testSearch/TestSearch.java Wed Oct 19 08:06:10 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8141492 8071982
+ * @bug 8141492 8071982 8141636
* @summary Test the search feature of javadoc.
* @author bpatel
* @library ../lib
@@ -45,6 +45,7 @@
checkExit(Exit.OK);
checkSearchOutput("UnnamedPkgClass.html", true);
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(false,
"package-search-index.zip",
"tag-search-index.zip");
@@ -62,6 +63,7 @@
checkSearchOutput(true);
checkSingleIndex(true);
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -78,6 +80,7 @@
checkSearchOutput(true);
checkSingleIndex(true);
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -110,6 +113,7 @@
checkSearchOutput(true);
checkSingleIndex(true);
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -142,6 +146,7 @@
checkSearchOutput(true);
checkIndexNoComment();
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -158,6 +163,7 @@
checkSearchOutput(true);
checkIndexNoDeprecated();
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -174,6 +180,7 @@
checkSearchOutput(true);
checkSplitIndex();
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(true,
"member-search-index.zip",
"package-search-index.zip",
@@ -189,6 +196,7 @@
checkSearchOutput(true);
checkJavaFXOutput();
checkJqueryAndImageFiles(true);
+ checkSearchJS();
checkFiles(false,
"tag-search-index.zip");
checkFiles(true,
@@ -420,4 +428,11 @@
"resources/x.png",
"resources/glass.png");
}
+
+ void checkSearchJS() {
+ 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)");
+ }
}
--- a/langtools/test/jdk/jshell/CompletionSuggestionTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/jdk/jshell/CompletionSuggestionTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -23,8 +23,8 @@
/*
* @test
- * @bug 8131025 8141092 8153761
- * @summary Test Completion
+ * @bug 8131025 8141092 8153761 8145263
+ * @summary Test Completion and Documentation
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.javap
@@ -43,6 +43,8 @@
import java.util.Collections;
import java.util.Set;
import java.util.HashSet;
+import java.util.function.BiFunction;
+import java.util.function.Function;
import java.util.jar.JarEntry;
import java.util.jar.JarOutputStream;
@@ -304,35 +306,35 @@
public void testDocumentation() throws Exception {
dontReadParameterNamesFromClassFile();
assertDocumentation("System.getProperty(|",
- "java.lang.System.getProperty(java.lang.String key)",
- "java.lang.System.getProperty(java.lang.String key, java.lang.String def)");
+ "String System.getProperty(String key)",
+ "String System.getProperty(String key, String def)");
assertEval("char[] chars = null;");
assertDocumentation("new String(chars, |",
- "java.lang.String(char[] arg0, int arg1, int arg2)");
+ "String(char[], int, int)");
assertDocumentation("String.format(|",
- "java.lang.String.format(java.lang.String arg0, java.lang.Object... arg1)",
- "java.lang.String.format(java.util.Locale arg0, java.lang.String arg1, java.lang.Object... arg2)");
- assertDocumentation("\"\".getBytes(\"\"|", "java.lang.String.getBytes(int arg0, int arg1, byte[] arg2, int arg3)",
- "java.lang.String.getBytes(java.lang.String arg0)",
- "java.lang.String.getBytes(java.nio.charset.Charset arg0)");
- assertDocumentation("\"\".getBytes(\"\" |", "java.lang.String.getBytes(int arg0, int arg1, byte[] arg2, int arg3)",
- "java.lang.String.getBytes(java.lang.String arg0)",
- "java.lang.String.getBytes(java.nio.charset.Charset arg0)");
+ "String String.format(String, Object...)",
+ "String String.format(java.util.Locale, String, Object...)");
+ assertDocumentation("\"\".getBytes(\"\"|", "void String.getBytes(int, int, byte[], int)",
+ "byte[] String.getBytes(String) throws java.io.UnsupportedEncodingException",
+ "byte[] String.getBytes(java.nio.charset.Charset)");
+ assertDocumentation("\"\".getBytes(\"\" |", "void String.getBytes(int, int, byte[], int)",
+ "byte[] String.getBytes(String) throws java.io.UnsupportedEncodingException",
+ "byte[] String.getBytes(java.nio.charset.Charset)");
}
public void testMethodsWithNoArguments() throws Exception {
dontReadParameterNamesFromClassFile();
assertDocumentation("System.out.println(|",
- "java.io.PrintStream.println()",
- "java.io.PrintStream.println(boolean arg0)",
- "java.io.PrintStream.println(char arg0)",
- "java.io.PrintStream.println(int arg0)",
- "java.io.PrintStream.println(long arg0)",
- "java.io.PrintStream.println(float arg0)",
- "java.io.PrintStream.println(double arg0)",
- "java.io.PrintStream.println(char[] arg0)",
- "java.io.PrintStream.println(java.lang.String arg0)",
- "java.io.PrintStream.println(java.lang.Object arg0)");
+ "void java.io.PrintStream.println()",
+ "void java.io.PrintStream.println(boolean)",
+ "void java.io.PrintStream.println(char)",
+ "void java.io.PrintStream.println(int)",
+ "void java.io.PrintStream.println(long)",
+ "void java.io.PrintStream.println(float)",
+ "void java.io.PrintStream.println(double)",
+ "void java.io.PrintStream.println(char[])",
+ "void java.io.PrintStream.println(String)",
+ "void java.io.PrintStream.println(Object)");
}
public void testErroneous() {
@@ -472,14 +474,14 @@
public void testDocumentationOfUserDefinedMethods() {
assertEval("void f() {}");
- assertDocumentation("f(|", "f()");
+ assertDocumentation("f(|", "void f()");
assertEval("void f(int i) {}");
- assertDocumentation("f(|", "f()", "f(int i)");
+ assertDocumentation("f(|", "void f()", "void f(int i)");
assertEval("<T> void f(T... ts) {}", DiagCheck.DIAG_WARNING, DiagCheck.DIAG_OK);
- assertDocumentation("f(|", "f()", "f(int i)", "f(T... ts)");
+ assertDocumentation("f(|", "void f()", "void f(int i)", "void <T>f(T... ts)");
assertEval("class A {}");
assertEval("void f(A a) {}");
- assertDocumentation("f(|", "f()", "f(int i)", "f(T... ts)", "f(A a)");
+ assertDocumentation("f(|", "void f()", "void f(int i)", "void <T>f(T... ts)", "void f(A a)");
}
public void testDocumentationOfUserDefinedConstructors() {
@@ -489,25 +491,25 @@
ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET)));
assertDocumentation("new A(|", "A()", "A(int i)");
- assertEval("class A<T> { A(T t) {} A(int i) {}}",
+ assertEval("class A<T> { A(T a) {} A(int i) {} <U> A(T t, U u) {}}",
ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(a2, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
- assertDocumentation("new A(|", "A(T t)", "A(int i)");
+ assertDocumentation("new A(|", "A<T>(T a)", "A<T>(int i)", "<U> A<T>(T t, U u)");
}
public void testDocumentationOfOverriddenMethods() throws Exception {
dontReadParameterNamesFromClassFile();
assertDocumentation("\"\".wait(|",
- "java.lang.Object.wait(long arg0)",
- "java.lang.Object.wait(long arg0, int arg1)",
- "java.lang.Object.wait()");
+ "void Object.wait(long) throws InterruptedException",
+ "void Object.wait(long, int) throws InterruptedException",
+ "void Object.wait() throws InterruptedException");
assertEval("class Base {void method() {}}");
Snippet e = classKey(assertEval("class Extend extends Base {}"));
- assertDocumentation("new Extend().method(|", "Base.method()");
+ assertDocumentation("new Extend().method(|", "void Base.method()");
assertEval("class Extend extends Base {void method() {}}",
ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(e, VALID, OVERWRITTEN, false, MAIN_SNIPPET));
- assertDocumentation("new Extend().method(|", "Extend.method()");
+ assertDocumentation("new Extend().method(|", "void Extend.method()");
}
public void testDocumentationOfInvisibleMethods() {
@@ -534,13 +536,67 @@
assertEval("void method(int n, Object o) { }");
assertEval("void method(Object n, int o) { }");
assertDocumentation("method(primitive,|",
- "method(int n, java.lang.Object o)",
- "method(java.lang.Object n, int o)");
+ "void method(int n, Object o)",
+ "void method(Object n, int o)");
assertDocumentation("method(boxed,|",
- "method(int n, java.lang.Object o)",
- "method(java.lang.Object n, int o)");
+ "void method(int n, Object o)",
+ "void method(Object n, int o)");
assertDocumentation("method(object,|",
- "method(java.lang.Object n, int o)");
+ "void method(Object n, int o)");
+ }
+
+ public void testDocumentationWithGenerics() {
+ class TestDocumentationWithGenerics {
+ private final Function<Integer, String> codeFacotry;
+ private final BiFunction<String, Integer, String> evalFormatter;
+ private final BiFunction<String, Integer, String> docFormatter;
+ int count;
+
+ TestDocumentationWithGenerics(
+ Function<Integer, String> codeFactory,
+ BiFunction<String, Integer, String> evalFormatter,
+ BiFunction<String, Integer, String> documentationFormatter) {
+ this.codeFacotry = codeFactory;
+ this.evalFormatter = evalFormatter;
+ this.docFormatter = documentationFormatter;
+ }
+
+ void assertDoc(String generics) {
+ assertDoc(generics, generics);
+ }
+
+ void assertDoc(String generics, String expectedGenerics) {
+ assertEval(evalFormatter.apply(generics, count));
+ assertDocumentation(codeFacotry.apply(count), docFormatter.apply(expectedGenerics, count));
+ count++;
+ }
+ }
+
+ TestDocumentationWithGenerics[] tests = {
+ new TestDocumentationWithGenerics(
+ i -> "f" + i + "(|",
+ (g, i) -> "<" + g + "> void f" + i + "() {}",
+ (g, i) -> "void <" + g + ">f" + i + "()"
+ ),
+ new TestDocumentationWithGenerics(
+ i -> "new C" + i + "().f(|",
+ (g, i) -> "class C" + i + "<" + g + "> { void f() {} }",
+ (g, i) -> "void C" + i + "<" + g + ">.f()"
+ )
+ };
+
+ Arrays.stream(tests).forEach(t -> {
+ t.assertDoc("T");
+ t.assertDoc("T extends Object",
+ "T");
+ t.assertDoc("T extends String");
+ t.assertDoc("T extends java.lang.String",
+ "T extends String");
+ t.assertDoc("T extends Number & Comparable<T>");
+ t.assertDoc("T extends java.io.Serializable & CharSequence");
+ t.assertDoc("K, D, M extends java.util.Map<K, D>",
+ "K, D, M extends java.util.Map<K,D>");
+ });
}
public void testVarArgs() {
--- a/langtools/test/jdk/jshell/DropTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/jdk/jshell/DropTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -23,14 +23,14 @@
/*
* @test
- * @bug 8081431 8080069
+ * @bug 8081431 8080069 8167128
* @summary Test of JShell#drop().
* @build KullaTesting TestingInputStream
* @run testng DropTest
*/
import jdk.jshell.DeclarationSnippet;
-import jdk.jshell.PersistentSnippet;
+import jdk.jshell.Snippet;
import jdk.jshell.VarSnippet;
import org.testng.annotations.Test;
@@ -40,9 +40,9 @@
public class DropTest extends KullaTesting {
public void testDrop() {
- PersistentSnippet var = varKey(assertEval("int x;"));
- PersistentSnippet method = methodKey(assertEval("int mu() { return x * 4; }"));
- PersistentSnippet clazz = classKey(assertEval("class C { String v() { return \"#\" + mu(); } }"));
+ Snippet var = varKey(assertEval("int x;"));
+ Snippet method = methodKey(assertEval("int mu() { return x * 4; }"));
+ Snippet clazz = classKey(assertEval("class C { String v() { return \"#\" + mu(); } }"));
assertDrop(var,
ste(var, VALID, DROPPED, true, null),
ste(method, VALID, RECOVERABLE_DEFINED, false, var));
@@ -62,7 +62,7 @@
assertEval("int x = 10;", "10",
added(VALID),
ste(method, RECOVERABLE_DEFINED, VALID, false, MAIN_SNIPPET));
- PersistentSnippet c0 = varKey(assertEval("C c0 = new C();"));
+ Snippet c0 = varKey(assertEval("C c0 = new C();"));
assertEval("c0.v();", "\"#40\"");
assertEval("C c = new C();",
ste(MAIN_SNIPPET, VALID, VALID, false, null),
@@ -88,8 +88,8 @@
}
public void testDropImport() {
- PersistentSnippet imp = importKey(assertEval("import java.util.*;"));
- PersistentSnippet decl = varKey(
+ Snippet imp = importKey(assertEval("import java.util.*;"));
+ Snippet decl = varKey(
assertEval("List<Integer> list = Arrays.asList(1, 2, 3);", "[1, 2, 3]"));
assertEval("list;", "[1, 2, 3]");
assertDrop(imp,
@@ -100,8 +100,13 @@
assertDeclareFail("list;", "compiler.err.cant.resolve.location");
}
+ public void testDropStatement() {
+ Snippet x = key(assertEval("if (true);"));
+ assertDrop(x, ste(x, VALID, DROPPED, true, null));
+ }
+
public void testDropVarToMethod() {
- PersistentSnippet x = varKey(assertEval("int x;"));
+ Snippet x = varKey(assertEval("int x;"));
DeclarationSnippet method = methodKey(assertEval("double mu() { return x * 4; }"));
assertEval("x == 0;", "true");
assertEval("mu() == 0.0;", "true");
@@ -118,7 +123,7 @@
}
public void testDropMethodToMethod() {
- PersistentSnippet a = methodKey(assertEval("double a() { return 2; }"));
+ Snippet a = methodKey(assertEval("double a() { return 2; }"));
DeclarationSnippet b = methodKey(assertEval("double b() { return a() * 10; }"));
assertEval("double c() { return b() * 3; }");
DeclarationSnippet d = methodKey(assertEval("double d() { return c() + 1000; }"));
@@ -134,7 +139,7 @@
}
public void testDropClassToMethod() {
- PersistentSnippet c = classKey(assertEval("class C { int f() { return 7; } }"));
+ Snippet c = classKey(assertEval("class C { int f() { return 7; } }"));
DeclarationSnippet m = methodKey(assertEval("int m() { return new C().f(); }"));
assertDrop(c,
ste(c, VALID, DROPPED, true, null),
@@ -145,7 +150,7 @@
}
public void testDropVarToClass() {
- PersistentSnippet x = varKey(assertEval("int x;"));
+ Snippet x = varKey(assertEval("int x;"));
DeclarationSnippet a = classKey(assertEval("class A { double a = 4 * x; }"));
assertDrop(x,
DiagCheck.DIAG_OK,
@@ -160,7 +165,7 @@
}
public void testDropMethodToClass() {
- PersistentSnippet x = methodKey(assertEval("int x() { return 0; }"));
+ Snippet x = methodKey(assertEval("int x() { return 0; }"));
DeclarationSnippet a = classKey(assertEval("class A { double a = 4 * x(); }"));
assertDrop(x,
DiagCheck.DIAG_OK,
@@ -174,10 +179,10 @@
}
public void testDropClassToClass() {
- PersistentSnippet a = classKey(assertEval("class A {}"));
- PersistentSnippet b = classKey(assertEval("class B extends A {}"));
- PersistentSnippet c = classKey(assertEval("class C extends B {}"));
- PersistentSnippet d = classKey(assertEval("class D extends C {}"));
+ Snippet a = classKey(assertEval("class A {}"));
+ Snippet b = classKey(assertEval("class B extends A {}"));
+ Snippet c = classKey(assertEval("class C extends B {}"));
+ Snippet d = classKey(assertEval("class D extends C {}"));
assertDrop(a,
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
@@ -201,9 +206,9 @@
public void testDropNoUpdate() {
String as1 = "class A {}";
String as2 = "class A extends java.util.ArrayList<Boolean> {}";
- PersistentSnippet a = classKey(assertEval(as1, added(VALID)));
- PersistentSnippet b = classKey(assertEval("class B extends A {}", added(VALID)));
- PersistentSnippet ax = classKey(assertEval(as2,
+ Snippet a = classKey(assertEval(as1, added(VALID)));
+ Snippet b = classKey(assertEval("class B extends A {}", added(VALID)));
+ Snippet ax = classKey(assertEval(as2,
ste(MAIN_SNIPPET, VALID, VALID, true, null),
ste(a, VALID, OVERWRITTEN, false, MAIN_SNIPPET),
ste(b, VALID, VALID, true, MAIN_SNIPPET)));
--- a/langtools/test/jdk/jshell/IdGeneratorTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/jdk/jshell/IdGeneratorTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -35,7 +35,6 @@
import jdk.jshell.EvalException;
import jdk.jshell.JShell;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.SnippetEvent;
import jdk.jshell.UnresolvedReferenceException;
import jdk.jshell.VarSnippet;
@@ -88,7 +87,7 @@
try (JShell jShell = builder.build()) {
List<SnippetEvent> eval = jShell.eval("int a, b;");
checkIds(eval);
- checkIds(jShell.drop((PersistentSnippet) eval.get(0).snippet()));
+ checkIds(jShell.drop(eval.get(0).snippet()));
}
}
--- a/langtools/test/jdk/jshell/IllegalArgumentExceptionTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/jdk/jshell/IllegalArgumentExceptionTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -31,7 +31,6 @@
import java.util.function.Consumer;
import jdk.jshell.DeclarationSnippet;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.Snippet;
import jdk.jshell.VarSnippet;
import org.testng.annotations.Test;
@@ -64,7 +63,7 @@
}
public void testDrop() {
- testIllegalArgumentException((key) -> getState().drop((PersistentSnippet) key));
+ testIllegalArgumentException((key) -> getState().drop(key));
}
public void testUnresolved() {
--- a/langtools/test/jdk/jshell/JShellStateClosedTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/jdk/jshell/JShellStateClosedTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -33,7 +33,6 @@
import jdk.jshell.DeclarationSnippet;
import jdk.jshell.ImportSnippet;
import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.Snippet;
import jdk.jshell.TypeDeclSnippet;
import jdk.jshell.VarSnippet;
@@ -127,7 +126,7 @@
}
public void testDrop() {
- testStateClosedException((key) -> getState().drop((PersistentSnippet) key));
+ testStateClosedException((key) -> getState().drop(key));
}
public void testUnresolved() {
--- a/langtools/test/jdk/jshell/KullaTesting.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/jdk/jshell/KullaTesting.java Wed Oct 19 08:06:10 2016 -0700
@@ -54,7 +54,6 @@
import jdk.jshell.ImportSnippet;
import jdk.jshell.Snippet.Kind;
import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.Snippet.Status;
import jdk.jshell.Snippet.SubKind;
import jdk.jshell.TypeDeclSnippet;
@@ -733,15 +732,15 @@
assertEquals(expectedSubKind.kind(), expectedKind, "Checking kind: ");
}
- public void assertDrop(PersistentSnippet key, STEInfo mainInfo, STEInfo... updates) {
+ public void assertDrop(Snippet key, STEInfo mainInfo, STEInfo... updates) {
assertDrop(key, DiagCheck.DIAG_OK, DiagCheck.DIAG_OK, mainInfo, updates);
}
- public void assertDrop(PersistentSnippet key, DiagCheck diagMain, DiagCheck diagUpdates, STEInfo mainInfo, STEInfo... updates) {
+ public void assertDrop(Snippet key, DiagCheck diagMain, DiagCheck diagUpdates, STEInfo mainInfo, STEInfo... updates) {
assertDrop(key, diagMain, diagUpdates, new EventChain(mainInfo, null, null, updates));
}
- public void assertDrop(PersistentSnippet key, DiagCheck diagMain, DiagCheck diagUpdates, EventChain... eventChains) {
+ public void assertDrop(Snippet key, DiagCheck diagMain, DiagCheck diagUpdates, EventChain... eventChains) {
checkEvents(() -> getState().drop(key), "drop(" + key + ")", diagMain, diagUpdates, eventChains);
}
--- a/langtools/test/jdk/jshell/ReplaceTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/jdk/jshell/ReplaceTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -33,7 +33,6 @@
import java.util.stream.Stream;
import jdk.jshell.Snippet;
import jdk.jshell.MethodSnippet;
-import jdk.jshell.PersistentSnippet;
import jdk.jshell.TypeDeclSnippet;
import jdk.jshell.VarSnippet;
import jdk.jshell.DeclarationSnippet;
@@ -585,14 +584,14 @@
}
public void testForwardSingleImportMethodToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
+ Snippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.String.format;",
added(VALID),
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("new A().s;", "\"10\"");
- PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+ Snippet format = methodKey(assertEval("void format(String s, int d) { }",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -605,14 +604,14 @@
}
public void testForwardSingleImportMethodToClass2() {
- PersistentSnippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
+ Snippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.String.format;",
added(VALID),
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("new A().s();", "\"10\"");
- PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+ Snippet format = methodKey(assertEval("void format(String s, int d) { }",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -625,7 +624,7 @@
}
public void testForwardSingleImportClassToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { static List<Integer> list; }",
+ Snippet a = classKey(assertEval("class A { static List<Integer> list; }",
added(RECOVERABLE_NOT_DEFINED)));
assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
assertEval("import java.util.List;",
@@ -634,7 +633,7 @@
assertEval("import java.util.Arrays;", added(VALID));
assertEval("A.list = Arrays.asList(1, 2, 3);", "[1, 2, 3]");
- PersistentSnippet list = classKey(assertEval("class List {}",
+ Snippet list = classKey(assertEval("class List {}",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -647,7 +646,7 @@
}
public void testForwardSingleImportClassToClass2() {
- PersistentSnippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
+ Snippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
added(RECOVERABLE_NOT_DEFINED)));
assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
assertEval("import java.util.ArrayList;",
@@ -655,7 +654,7 @@
ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET));
Snippet vara = varKey(assertEval("A a = new A();", "[]"));
- PersistentSnippet arraylist = classKey(assertEval("class ArrayList {}",
+ Snippet arraylist = classKey(assertEval("class ArrayList {}",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -671,7 +670,7 @@
}
public void testForwardImportOnDemandMethodToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
+ Snippet a = classKey(assertEval("class A { String s = format(\"%d\", 10); }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.String.*;",
@@ -679,7 +678,7 @@
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("A x = new A();");
assertEval("x.s;", "\"10\"");
- PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+ Snippet format = methodKey(assertEval("void format(String s, int d) { }",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -693,14 +692,14 @@
}
public void testForwardImportOnDemandMethodToClass2() {
- PersistentSnippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
+ Snippet a = classKey(assertEval("class A { String s() { return format(\"%d\", 10); } }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.String.*;",
added(VALID),
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("new A().s();", "\"10\"");
- PersistentSnippet format = methodKey(assertEval("void format(String s, int d) { }",
+ Snippet format = methodKey(assertEval("void format(String s, int d) { }",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -713,7 +712,7 @@
}
public void testForwardImportOnDemandClassToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { static List<Integer> list; }",
+ Snippet a = classKey(assertEval("class A { static List<Integer> list; }",
added(RECOVERABLE_NOT_DEFINED)));
assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
assertEval("import java.util.*;",
@@ -721,7 +720,7 @@
ste(a, RECOVERABLE_NOT_DEFINED, VALID, true, null));
assertEval("A.list = Arrays.asList(1, 2, 3);", "[1, 2, 3]");
- PersistentSnippet list = classKey(assertEval("class List {}",
+ Snippet list = classKey(assertEval("class List {}",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -734,7 +733,7 @@
}
public void testForwardImportOnDemandClassToClass2() {
- PersistentSnippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
+ Snippet clsA = classKey(assertEval("class A extends ArrayList<Integer> { }",
added(RECOVERABLE_NOT_DEFINED)));
assertDeclareFail("new A();", "compiler.err.cant.resolve.location");
assertEval("import java.util.*;",
@@ -742,7 +741,7 @@
ste(clsA, RECOVERABLE_NOT_DEFINED, VALID, true, MAIN_SNIPPET));
Snippet vara = varKey(assertEval("A a = new A();", "[]"));
- PersistentSnippet arraylist = classKey(assertEval("class ArrayList {}",
+ Snippet arraylist = classKey(assertEval("class ArrayList {}",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -757,7 +756,7 @@
}
public void testForwardSingleImportFieldToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
+ Snippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.Math.PI;",
@@ -765,7 +764,7 @@
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("Math.abs(A.pi() - 3.1415) < 0.001;", "true");
- PersistentSnippet list = varKey(assertEval("String PI;",
+ Snippet list = varKey(assertEval("String PI;",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -778,7 +777,7 @@
}
public void testForwardSingleImportFieldToClass2() {
- PersistentSnippet a = classKey(assertEval("class A { static double pi = PI; }",
+ Snippet a = classKey(assertEval("class A { static double pi = PI; }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.Math.PI;",
@@ -786,7 +785,7 @@
ste(a, RECOVERABLE_DEFINED, VALID, true, null));
assertEval("Math.abs(A.pi - 3.1415) < 0.001;", "true");
- PersistentSnippet list = varKey(assertEval("String PI;",
+ Snippet list = varKey(assertEval("String PI;",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -799,7 +798,7 @@
}
public void testForwardImportOnDemandFieldToClass1() {
- PersistentSnippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
+ Snippet a = classKey(assertEval("class A { static double pi() { return PI; } }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.Math.*;",
@@ -807,7 +806,7 @@
ste(a, RECOVERABLE_DEFINED, VALID, false, null));
assertEval("Math.abs(A.pi() - 3.1415) < 0.001;", "true");
- PersistentSnippet list = varKey(assertEval("String PI;",
+ Snippet list = varKey(assertEval("String PI;",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
@@ -820,7 +819,7 @@
}
public void testForwardImportOnDemandFieldToClass2() {
- PersistentSnippet a = classKey(assertEval("class A { static double pi = PI; }",
+ Snippet a = classKey(assertEval("class A { static double pi = PI; }",
added(RECOVERABLE_DEFINED)));
assertEvalUnresolvedException("new A();", "A", 1, 0);
assertEval("import static java.lang.Math.*;",
@@ -828,7 +827,7 @@
ste(a, RECOVERABLE_DEFINED, VALID, true, null));
assertEval("Math.abs(A.pi - 3.1415) < 0.001;", "true");
- PersistentSnippet list = varKey(assertEval("String PI;",
+ Snippet list = varKey(assertEval("String PI;",
DiagCheck.DIAG_OK,
DiagCheck.DIAG_ERROR,
added(VALID),
--- a/langtools/test/jdk/jshell/ToolCommandOptionTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/jdk/jshell/ToolCommandOptionTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8157395 8157393 8157517 8158738
+ * @bug 8157395 8157393 8157517 8158738 8167128
* @summary Tests of jshell comand options, and undoing operations
* @modules jdk.jshell/jdk.internal.jshell.tool
* @build ToolCommandOptionTest ReplToolTesting
@@ -101,13 +101,17 @@
"| Unknown option: -all -- /drop -all"),
(a) -> assertCommandOutputStartsWith(a, "/drop z",
"| No such snippet: z"),
- (a) -> assertCommandOutputStartsWith(a, "/drop 2",
- "| This command does not accept the snippet '2' : x"),
+ (a) -> assertCommand(a, "/drop 2",
+ ""),
+ (a) -> assertCommandOutputStartsWith(a, "23qwl",
+ "| Error:"),
+ (a) -> assertCommandOutputStartsWith(a, "/drop e1",
+ "| This command does not accept the snippet 'e1' : 23qwl"),
(a) -> assertCommand(a, "/dr x y",
"| dropped variable x\n" +
"| dropped variable y"),
(a) -> assertCommand(a, "/list",
- "2 : x")
+ "")
);
}
--- a/langtools/test/jdk/jshell/ToolSimpleTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/jdk/jshell/ToolSimpleTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897
+ * @bug 8153716 8143955 8151754 8150382 8153920 8156910 8131024 8160089 8153897 8167128
* @summary Simple jshell tool tests
* @modules jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
@@ -217,6 +217,9 @@
a -> dropClass(a, "/drop 3", "class A", "| dropped class A"),
a -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
a -> dropImport(a, "/drop 4", "import java.util.stream.*", ""),
+ a -> assertCommand(a, "for (int i = 0; i < 10; ++i) {}", ""),
+ a -> assertCommand(a, "/drop 5", ""),
+ a -> assertCommand(a, "/list", ""),
a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
a -> assertCommandCheckOutput(a, "/methods", assertMethods()),
a -> assertCommandCheckOutput(a, "/types", assertClasses()),
@@ -244,6 +247,7 @@
assertStartsWith("| In the /drop argument, please specify an import, variable, method, or class to drop.")),
a -> assertVariable(a, "int", "a"),
a -> assertCommand(a, "a", "a ==> 0"),
+ a -> assertCommand(a, "/drop 2", ""),
a -> assertCommand(a, "/drop 2",
"| This command does not accept the snippet '2' : a\n" +
"| See /types, /methods, /vars, or /list")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,34 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8167000
+ * @summary Refine handling of multiple maximally specific abstract methods
+ * @compile/fail/ref=T8167000.out -XDrawDiagnostics -Werror -Xlint:unchecked T8167000.java
+ */
+
+import java.util.*;
+
+class T8167000 {
+
+ interface J {
+ List<Number> getAll(String str);
+ }
+
+ interface K {
+ Collection<Integer> getAll(String str);
+ }
+
+ interface L {
+ List getAll(String str);
+ }
+
+ interface M {
+ Collection getAll(String str);
+ }
+
+
+ static abstract class E implements J, K, L, M {
+ void test() {
+ List<String> l = getAll(""); //check that we get an unchecked warning here
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000.out Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,4 @@
+T8167000.java:31:36: compiler.warn.prob.found.req: (compiler.misc.unchecked.assign), java.util.List, java.util.List<java.lang.String>
+- compiler.err.warnings.and.werror
+1 error
+1 warning
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000b.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8167000
+ * @summary Refine handling of multiple maximally specific abstract methods
+ * @compile/fail/ref=T8167000b.out -XDrawDiagnostics T8167000b.java
+ */
+public class T8167000b {
+ interface A {
+ Integer m() throws Throwable;
+ }
+
+ interface B<X extends Throwable> {
+ Object m() throws X;
+ }
+
+ static abstract class E<T extends Throwable> implements A, B<T> {
+ void test() {
+ Integer l = m(); //error: unhandled T
+ }
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000b.out Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,2 @@
+T8167000b.java:18:26: compiler.err.unreported.exception.need.to.catch.or.throw: T
+1 error
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000c.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,21 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8167000
+ * @summary Refine handling of multiple maximally specific abstract methods
+ * @compile/fail/ref=T8167000c.out -XDrawDiagnostics T8167000c.java
+ */
+public class T8167000c<X extends Throwable> {
+ interface A {
+ Integer m() throws Throwable;
+ }
+
+ interface B<X extends Throwable> {
+ Object m() throws X;
+ }
+
+ interface E<T extends Throwable> extends A, B<T> { }
+
+ void test() {
+ E<X> ex = () -> { throw new Throwable(); };
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/8167000/T8167000c.out Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,4 @@
+T8167000c.java:19:27: compiler.err.unreported.exception.need.to.catch.or.throw: java.lang.Throwable
+- compiler.note.unchecked.filename: T8167000c.java
+- compiler.note.unchecked.recompile
+1 error
--- a/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -120,10 +120,10 @@
}
}
- boolean moreSpecificThan(TypeArgumentKind that, boolean strict) {
+ boolean moreSpecificThan(TypeArgumentKind that) {
switch (this) {
case NONE:
- return that == this || !strict;
+ return that == this;
case UNBOUND:
return that == this || that == NONE;
case INTEGER:
@@ -198,6 +198,7 @@
void check(Result<?> res) {
boolean errorExpected = false;
+ boolean loose = false;
int mostSpecific = 0;
//first check that either |R1| <: |R2| or |R2| <: |R1|
@@ -208,39 +209,43 @@
} else {
mostSpecific = rets[0].moreSpecificThan(rets[1]) ? 1 : 2;
}
+ } else if (sigs[0] != sigs[1]) {
+ mostSpecific = sigs[0] == SignatureKind.GENERIC ? 2 : 1;
+ loose = true;
}
//check that either TA1 <= TA2 or TA2 <= TA1 (unless most specific return found above is raw)
if (!errorExpected) {
if (targs[0] != targs[1]) {
- boolean useStrictCheck = targs[0].moreSpecificThan(targs[1], true) ||
- targs[1].moreSpecificThan(targs[0], true);
- if (!targs[0].moreSpecificThan(targs[1], useStrictCheck) &&
- !targs[1].moreSpecificThan(targs[0], useStrictCheck)) {
+ boolean ta1ms = targs[0].moreSpecificThan(targs[1]);
+ boolean ta2ms = targs[1].moreSpecificThan(targs[0]);
+ if (!ta1ms && !ta2ms) {
errorExpected = true;
+ } else if (mostSpecific != 0) {
+ errorExpected = !loose && targs[mostSpecific - 1] != TypeArgumentKind.NONE &&
+ (mostSpecific == 1 ? !ta1ms : !ta2ms);
} else {
- int mostSpecific2 = targs[0].moreSpecificThan(targs[1], useStrictCheck) ? 1 : 2;
- if (mostSpecific != 0 && mostSpecific2 != mostSpecific) {
- errorExpected = mostSpecific == 1 ?
- targs[0] != TypeArgumentKind.NONE :
- targs[1] != TypeArgumentKind.NONE;
- } else {
- mostSpecific = mostSpecific2;
- }
+ mostSpecific = ta1ms ? 1 : 2;
}
- } else if (mostSpecific == 0) {
- //when no signature is better than the other, an arbitrary choice
- //must be made - javac always picks the second signature
- mostSpecific = 2;
}
}
- //finally, check that most specific return type is compatible with expected type
+ if (mostSpecific == 0) {
+ //when no signature is better than the other, an arbitrary choice
+ //must be made - javac always picks the second signature
+ mostSpecific = 2;
+ }
+
if (!errorExpected) {
ReturnTypeKind msrt = mostSpecific == 1 ? rets[0] : rets[1];
TypeArgumentKind msta = mostSpecific == 1 ? targs[0] : targs[1];
SignatureKind mssig = mostSpecific == 1 ? sigs[0] : sigs[1];
+ //check that most specific is subsignature
+ errorExpected = sigs[0] != sigs[1] &&
+ mssig == SignatureKind.GENERIC;
+
+ //finally, check that most specific return type is compatible with expected type
if (!msrt.moreSpecificThan(rets[2]) ||
!msta.assignableTo(targs[2], mssig, level)) {
errorExpected = true;
--- a/langtools/test/tools/javac/modules/EdgeCases.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/tools/javac/modules/EdgeCases.java Wed Oct 19 08:06:10 2016 -0700
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 8154283
+ * @bug 8154283 8167320
* @summary tests for multi-module mode compilation
* @library /tools/lib
* @modules
@@ -54,6 +54,7 @@
//import com.sun.source.util.JavacTask; // conflicts with toolbox.JavacTask
import com.sun.tools.javac.api.JavacTaskImpl;
import com.sun.tools.javac.code.Symbol.ModuleSymbol;
+import com.sun.tools.javac.code.Symtab;
import toolbox.JarTask;
import toolbox.JavacTask;
@@ -449,4 +450,12 @@
}
}
+ @Test
+ public void testGetDirectivesComplete(Path base) throws Exception {
+ JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+ JavacTaskImpl task = (JavacTaskImpl) compiler.getTask(null, null, null, null, null, null);
+ Symtab syms = Symtab.instance(task.getContext());
+
+ syms.java_base.getDirectives();
+ }
}
--- a/langtools/test/tools/javac/modules/ModulePathTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/langtools/test/tools/javac/modules/ModulePathTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -29,7 +29,7 @@
* jdk.compiler/com.sun.tools.javac.api
* jdk.compiler/com.sun.tools.javac.main
* jdk.jdeps/com.sun.tools.javap
- * jdk.jlink/jdk.tools.jmod
+ * jdk.jlink
* @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask toolbox.ModuleBuilder
* ModuleTestBase
* @run main ModulePathTest
@@ -39,6 +39,7 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.spi.ToolProvider;
import toolbox.JarTask;
import toolbox.JavacTask;
@@ -420,6 +421,9 @@
"--class-path", dir.toString(),
jmod.toString()
};
- jdk.tools.jmod.Main.run(args, System.out);
+ ToolProvider jmodTool = ToolProvider.findFirst("jmod").orElseThrow(() ->
+ new RuntimeException("jmod tool not found")
+ );
+ jmodTool.run(System.out, System.err, args);
}
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/jdeprscan/tests/jdk/jdeprscan/TestRelease.java Wed Oct 19 08:06:10 2016 -0700
@@ -0,0 +1,58 @@
+/*
+ * 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 8167965
+ * @summary Test proper handling of the --release option.
+ * @modules jdk.jdeps/com.sun.tools.jdeprscan
+ * @build jdk.jdeprscan.TestRelease
+ * @run testng jdk.jdeprscan.TestRelease
+ */
+
+package jdk.jdeprscan;
+
+import com.sun.tools.jdeprscan.Main;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+public class TestRelease {
+ static boolean invoke(String arg) {
+ return Main.call(System.out, System.err, "--list", "--release", arg);
+ }
+
+ @Test
+ public void testSuccess() {
+ assertTrue(invoke("6"));
+ assertTrue(invoke("7"));
+ assertTrue(invoke("8"));
+ assertTrue(invoke("9"));
+ }
+
+ @Test
+ public void testFailure() {
+ assertFalse(invoke("5"));
+ }
+}
--- a/make/CopyImportModules.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/CopyImportModules.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -41,14 +41,14 @@
ifeq ($(OPENJDK_TARGET_OS), windows)
TO_BIN_FILTER := %$(SHARED_LIBRARY_SUFFIX) %.diz %.pdb %.map
- $(eval $(call SetupCopyFiles,COPY_LIBS_TO_BIN, \
+ $(eval $(call SetupCopyFiles, COPY_LIBS_TO_BIN, \
SRC := $(LIBS_DIR), \
DEST := $(JDK_OUTPUTDIR)/bin, \
FILES := $(filter $(TO_BIN_FILTER), \
$(call CacheFind, $(LIBS_DIR))) \
))
- $(eval $(call SetupCopyFiles,COPY_LIBS_TO_LIB, \
+ $(eval $(call SetupCopyFiles, COPY_LIBS_TO_LIB, \
SRC := $(LIBS_DIR), \
DEST := $(JDK_OUTPUTDIR)/lib, \
FILES := $(filter-out $(TO_BIN_FILTER), \
--- a/make/CreateBuildJdkCopy.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/CreateBuildJdkCopy.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/make/GensrcModuleInfo.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/GensrcModuleInfo.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/make/Images.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/Images.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -412,7 +412,7 @@
################################################################################
# /sample dir
-$(eval $(call SetupCopyFiles,COPY_SAMPLES, \
+$(eval $(call SetupCopyFiles, COPY_SAMPLES, \
SRC := $(SUPPORT_OUTPUTDIR)/sample/image, \
DEST := $(JDK_IMAGE_DIR)/sample, \
FILES := $(if $(wildcard $(SUPPORT_OUTPUTDIR)/sample/image), \
--- a/make/Init.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/Init.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/make/InitSupport.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/InitSupport.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/make/Jprt.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/Jprt.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/make/JrtfsJar.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/JrtfsJar.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -46,7 +46,7 @@
jdk/internal/jrtfs \
#
-$(eval $(call SetupJavaCompilation,BUILD_JRTFS, \
+$(eval $(call SetupJavaCompilation, BUILD_JRTFS, \
SETUP := GENERATE_OLDBYTECODE, \
SRC := $(JDK_TOPDIR)/src/java.base/share/classes, \
EXCLUDE_FILES := module-info.java, \
@@ -57,7 +57,7 @@
# file will not be copied unless META-INF/services would also be added to the INCLUDES.
# Adding META-INF/services would include all files in that directory when only the one
# is needed, which is why this explicit copy is defined instead.
-$(eval $(call SetupCopyFiles,COPY_JIMAGE_SERVICE_PROVIDER, \
+$(eval $(call SetupCopyFiles, COPY_JIMAGE_SERVICE_PROVIDER, \
SRC := $(JDK_TOPDIR)/src/java.base/share/classes, \
DEST := $(SUPPORT_OUTPUTDIR)/jrtfs_classes, \
FILES := META-INF/services/java.nio.file.spi.FileSystemProvider))
--- a/make/MacBundles.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/MacBundles.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/make/Main.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/Main.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -237,7 +237,7 @@
# Build hotspot target
ifeq ($(BUILD_HOTSPOT),true)
-hotspot:
+ hotspot:
+($(CD) $(HOTSPOT_TOPDIR)/make && $(MAKE) $(MAKE_ARGS) -f BuildHotspot.gmk)
endif
@@ -548,7 +548,7 @@
# The demos are currently linking to libjvm and libjava, just like all other
# jdk libs, even though they don't need to. To avoid warnings, make sure they
# aren't built until after libjava and libjvm are available to link to.
- demos-jdk: $(JAVA_TARGETS)
+ demos-jdk: java.base-libs exploded-image-optimize
# Declare dependency from <module>-java to <module>-gensrc
$(foreach m, $(GENSRC_MODULES), $(eval $m-java: $m-gensrc))
@@ -698,7 +698,7 @@
test-make: clean-test-make
- build-test-lib: java
+ build-test-lib: exploded-image-optimize
build-test-failure-handler: interim-langtools
--- a/make/common/CORE_PKGS.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/common/CORE_PKGS.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/make/common/JarArchive.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/common/JarArchive.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
@@ -242,7 +242,7 @@
# potential changes.
$$(if $$(filter $$($1_VARDEPS_FILE) $$($1_MANIFEST), $$?), \
$$(if $$($1_MANIFEST), \
- $(SED) -e '$(DOLLAR)$(DOLLAR)a\' $$($1_MANIFEST) > $$($1_MANIFEST_FILE) $$(NEWLINE) \
+ $(CP) $$($1_MANIFEST) $$($1_MANIFEST_FILE) $$(NEWLINE) \
, \
$(RM) $$($1_MANIFEST_FILE) && $(TOUCH) $$($1_MANIFEST_FILE) $$(NEWLINE)) \
$$(if $$($1_JARMAIN), \
--- a/make/common/JavaCompilation.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/common/JavaCompilation.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/make/common/NON_CORE_PKGS.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/common/NON_CORE_PKGS.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2002, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/make/common/SetupJavaCompilers.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/common/SetupJavaCompilers.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/make/devkit/Tools.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/make/devkit/Tools.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 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
--- a/make/devkit/createWindowsDevkit.sh Wed Oct 19 11:51:40 2016 +0300
+++ b/make/devkit/createWindowsDevkit.sh Wed Oct 19 08:06:10 2016 -0700
@@ -1,6 +1,6 @@
#!/bin/bash
#
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# This code is free software; you can redistribute it and/or modify it
--- a/nashorn/.hgtags Wed Oct 19 11:51:40 2016 +0300
+++ b/nashorn/.hgtags Wed Oct 19 08:06:10 2016 -0700
@@ -373,3 +373,4 @@
17ed43add2f9e3528686cd786ae2ed49c8ed36e9 jdk-9+137
4a6ee1185fc821df063e4d1537fa7ad2ebe9eb02 jdk-9+138
e3b11296395b39bfeb3364f26c2ef77fa652e300 jdk-9+139
+785843878cf78d50cc2959ea2c5a4202bbe885b4 jdk-9+140
--- a/nashorn/make/BuildNashorn.gmk Wed Oct 19 11:51:40 2016 +0300
+++ b/nashorn/make/BuildNashorn.gmk Wed Oct 19 08:06:10 2016 -0700
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved.
+# 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
--- a/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java Wed Oct 19 11:51:40 2016 +0300
+++ b/nashorn/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java Wed Oct 19 08:06:10 2016 -0700
@@ -100,7 +100,6 @@
import jdk.dynalink.SecureLookupSupplier;
import jdk.dynalink.internal.AccessControlContextFactory;
import jdk.dynalink.linker.support.Lookup;
-import jdk.internal.module.Modules;
import jdk.internal.reflect.CallerSensitive;
@@ -180,57 +179,10 @@
}
private static MethodHandle unreflect(final MethodHandles.Lookup lookup, final Method m) {
- try {
- return Lookup.unreflect(lookup, m);
- } catch (final IllegalAccessError iae) {
- if (addModuleRead(lookup, m)) {
- try {
- return Lookup.unreflect(lookup, m);
- } catch (final IllegalAccessError e2) {
- // fall through and throw original error as cause
- }
- }
- throw iae;
- }
+ return Lookup.unreflect(lookup, m);
}
private static MethodHandle unreflectConstructor(final MethodHandles.Lookup lookup, final Constructor<?> c) {
- try {
- return Lookup.unreflectConstructor(lookup, c);
- } catch (final IllegalAccessError iae) {
- if (addModuleRead(lookup, c)) {
- try {
- return Lookup.unreflectConstructor(lookup, c);
- } catch (final IllegalAccessError e2) {
- // fall through and throw original error as cause
- }
- }
- throw iae;
- }
- }
-
-
- private static boolean addModuleRead(final MethodHandles.Lookup lookup, final Executable e) {
- // Don't add module read link if this is not a CallerSensitive member
- if (!e.isAnnotationPresent(CallerSensitive.class)) {
- return false;
- }
-
- // If the lookup is public lookup, don't bother adding module read link!
- // public lookup cannot unreflect caller sensitives anyway!
- if (lookup == MethodHandles.publicLookup()) {
- return false;
- }
-
- // try to add missing module read from using module to declararing module!
- final Class<?> declClass = e.getDeclaringClass();
- final Module useModule = lookup.lookupClass().getModule();
- final Module declModule = declClass.getModule();
- if (useModule != null && declModule != null && declModule.isExported(declClass.getPackageName())) {
- Modules.addReads(useModule, declModule);
- return true;
- }
-
- return false;
+ return Lookup.unreflectConstructor(lookup, c);
}
}
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Wed Oct 19 11:51:40 2016 +0300
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/Context.java Wed Oct 19 08:06:10 2016 -0700
@@ -389,6 +389,15 @@
// is created, and invalidated forever once the second global is created.
private final AtomicReference<GlobalConstants> globalConstantsRef = new AtomicReference<>();
+ // Are java.sql, java.sql.rowset modules found in the system?
+ static final boolean javaSqlFound, javaSqlRowsetFound;
+
+ static {
+ final Layer boot = Layer.boot();
+ javaSqlFound = boot.findModule("java.sql").isPresent();
+ javaSqlRowsetFound = boot.findModule("java.sql.rowset").isPresent();
+ }
+
/**
* Get the current global scope
* @return the current global scope
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptLoader.java Wed Oct 19 11:51:40 2016 +0300
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/ScriptLoader.java Wed Oct 19 08:06:10 2016 -0700
@@ -68,12 +68,23 @@
private Module createModule(final String moduleName) {
final Module structMod = context.getStructLoader().getModule();
- final ModuleDescriptor descriptor
- = new ModuleDescriptor.Builder(moduleName)
+ final ModuleDescriptor.Builder builder =
+ new ModuleDescriptor.Builder(moduleName)
+ .requires("java.base")
+ .requires("java.logging")
.requires(NASHORN_MODULE.getName())
.requires(structMod.getName())
- .conceals(SCRIPTS_PKG)
- .build();
+ .conceals(SCRIPTS_PKG);
+
+ if (Context.javaSqlFound) {
+ builder.requires("java.sql");
+ }
+
+ if (Context.javaSqlRowsetFound) {
+ builder.requires("java.sql.rowset");
+ }
+
+ final ModuleDescriptor descriptor = builder.build();
final Module mod = Context.createModuleTrusted(structMod.getLayer(), descriptor, this);
loadModuleManipulator();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StructureLoader.java Wed Oct 19 11:51:40 2016 +0300
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/StructureLoader.java Wed Oct 19 08:06:10 2016 -0700
@@ -64,6 +64,7 @@
private Module createModule(final String moduleName) {
final ModuleDescriptor descriptor
= new ModuleDescriptor.Builder(moduleName)
+ .requires("java.base")
.requires(NASHORN_MODULE.getName())
.conceals(SCRIPTS_PKG)
.build();
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Wed Oct 19 11:51:40 2016 +0300
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java Wed Oct 19 08:06:10 2016 -0700
@@ -78,14 +78,17 @@
prioritizedLinkers = new GuardingDynamicLinker[] {
new NashornLinker(),
new NashornPrimitiveLinker(),
- new NashornStaticClassLinker(beansLinker),
new BoundCallableLinker(),
new JavaSuperAdapterLinker(beansLinker),
new JSObjectLinker(nashornBeansLinker),
new BrowserJSObjectLinker(nashornBeansLinker),
new ReflectionCheckLinker()
};
- fallbackLinkers = new GuardingDynamicLinker[] {nashornBeansLinker, new NashornBottomLinker() };
+ fallbackLinkers = new GuardingDynamicLinker[] {
+ new NashornStaticClassLinker(beansLinker),
+ nashornBeansLinker,
+ new NashornBottomLinker()
+ };
}
// do not create me!!
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Wed Oct 19 11:51:40 2016 +0300
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Wed Oct 19 08:06:10 2016 -0700
@@ -68,7 +68,7 @@
@Override
public GuardedInvocation getGuardedInvocation(final LinkRequest request, final LinkerServices linkerServices) throws Exception {
final Object self = request.getReceiver();
- if (self.getClass() != StaticClass.class) {
+ if (self == null || self.getClass() != StaticClass.class) {
return null;
}
final Class<?> receiverClass = ((StaticClass) self).getRepresentedClass();
--- a/nashorn/test/src/jdk/dynalink/test/DynamicLinkerFactoryTest.java Wed Oct 19 11:51:40 2016 +0300
+++ b/nashorn/test/src/jdk/dynalink/test/DynamicLinkerFactoryTest.java Wed Oct 19 08:06:10 2016 -0700
@@ -39,6 +39,7 @@
import jdk.dynalink.NoSuchDynamicMethodException;
import jdk.dynalink.Operation;
import jdk.dynalink.StandardOperation;
+import jdk.dynalink.beans.StaticClass;
import jdk.dynalink.linker.GuardedInvocation;
import jdk.dynalink.linker.GuardingDynamicLinker;
import jdk.dynalink.linker.LinkRequest;
@@ -234,6 +235,15 @@
@Test
public void autoLoadedLinkerTest() {
+ testAutoLoadedLinkerInvoked(new Object(), "toString");
+ }
+
+ @Test
+ public void autoLoadedLinkerSeesStaticMethod() {
+ testAutoLoadedLinkerInvoked(StaticClass.forClass(System.class), "currentTimeMillis");
+ }
+
+ private static void testAutoLoadedLinkerInvoked(final Object target, final String methodName) {
final DynamicLinkerFactory factory = newDynamicLinkerFactory(false);
final DynamicLinker linker = factory.createLinker();
@@ -241,22 +251,21 @@
checkOneAutoLoadingError(factory);
final MethodType mt = MethodType.methodType(Object.class, Object.class);
- // create a callsite with TestLinkerOperation
- final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor(
- MethodHandles.publicLookup(), new TestLinkerOperation(), mt)));
- boolean reachedAutoLinker = false;
-
+ final CallSiteDescriptor testDescriptor = new CallSiteDescriptor(MethodHandles.publicLookup(),
+ new NamedOperation(StandardOperation.GET_METHOD, methodName), mt);
+ final CallSite cs = linker.link(new SimpleRelinkableCallSite(testDescriptor));
+ TrustedGuardingDynamicLinkerExporter.enable();
try {
- cs.getTarget().invoke(new Object());
- } catch (final ReachedAutoLoadedDynamicLinkerException e) {
- // TrustedGuardingDynamicLinkerExporter threw exception on TestLinkerOperation as expected!
- reachedAutoLinker = true;
+ cs.getTarget().invoke(target);
+ // The linker was loaded and it observed our invocation
+ Assert.assertTrue(TrustedGuardingDynamicLinkerExporter.isLastCallSiteDescriptor(testDescriptor));
} catch (final Throwable th) {
throw new RuntimeException(th);
+ } finally {
+ TrustedGuardingDynamicLinkerExporter.disable();
}
- Assert.assertTrue(reachedAutoLinker);
}
@Test
--- a/nashorn/test/src/jdk/dynalink/test/ReachedAutoLoadedDynamicLinkerException.java Wed Oct 19 11:51:40 2016 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.dynalink.test;
-
-/**
- * Exception used to signal to the test method that the control has reached auto loaded
- * dynamic linker.
- */
-public final class ReachedAutoLoadedDynamicLinkerException extends RuntimeException {
-}
--- a/nashorn/test/src/jdk/dynalink/test/TestLinkerOperation.java Wed Oct 19 11:51:40 2016 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-/*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package jdk.dynalink.test;
-
-import jdk.dynalink.Operation;
-
-public final class TestLinkerOperation implements Operation {
-}
--- a/nashorn/test/src/jdk/dynalink/test/TrustedGuardingDynamicLinkerExporter.java Wed Oct 19 11:51:40 2016 +0300
+++ b/nashorn/test/src/jdk/dynalink/test/TrustedGuardingDynamicLinkerExporter.java Wed Oct 19 08:06:10 2016 -0700
@@ -25,8 +25,8 @@
package jdk.dynalink.test;
-import java.util.ArrayList;
import java.util.List;
+import jdk.dynalink.CallSiteDescriptor;
import jdk.dynalink.linker.GuardingDynamicLinker;
import jdk.dynalink.linker.GuardingDynamicLinkerExporter;
import jdk.dynalink.linker.LinkRequest;
@@ -37,20 +37,32 @@
*/
public final class TrustedGuardingDynamicLinkerExporter extends GuardingDynamicLinkerExporter {
+ private static final ThreadLocal<CallSiteDescriptor> lastDescriptor = new ThreadLocal<>();
+ private static boolean enabled = false;
+
+ public static void enable() {
+ reset(true);
+ }
+
+ public static void disable() {
+ reset(false);
+ }
+ public static boolean isLastCallSiteDescriptor(final CallSiteDescriptor desc) {
+ return lastDescriptor.get() == desc;
+ }
+
+ private static void reset(final boolean enable) {
+ lastDescriptor.set(null);
+ enabled = enable;
+ }
+
@Override
public List<GuardingDynamicLinker> get() {
- final ArrayList<GuardingDynamicLinker> linkers = new ArrayList<>();
- linkers.add((GuardingDynamicLinker) (final LinkRequest linkRequest, final LinkerServices linkerServices) -> {
- // handle only the TestLinkerOperation instances
- if (linkRequest.getCallSiteDescriptor().getOperation() instanceof TestLinkerOperation) {
- System.out.println("inside " + this.getClass().getName());
- // throw exception to signal to the test method that the control has reached here!
- throw new ReachedAutoLoadedDynamicLinkerException();
- } else {
- // any other operation!
- return null;
+ return List.of(((GuardingDynamicLinker) (final LinkRequest linkRequest, final LinkerServices linkerServices) -> {
+ if (enabled) {
+ lastDescriptor.set(linkRequest.getCallSiteDescriptor());
}
- });
- return linkers;
+ return null;
+ }));
}
}